diff --git a/.gitignore b/.gitignore
index 06e74a2ed..fd760efe3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@ xa-gendarme.html
packages
.vs/
*.userprefs
+*.user
Resource.designer.cs
\ No newline at end of file
diff --git a/tools/generator/CodeGenerator.cs b/tools/generator/CodeGenerator.cs
index f9f20a83a..19c2a4394 100644
--- a/tools/generator/CodeGenerator.cs
+++ b/tools/generator/CodeGenerator.cs
@@ -695,22 +695,57 @@ protected CodeGenerator ()
{
}
- internal abstract void WriteClassHandle (ClassGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, bool requireNew);
+ internal abstract void WriteClassHandle (ClassGen type, TextWriter writer, string indent, CodeGenerationOptions opt, bool requireNew);
- internal abstract void WriteClassHandle (InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType);
+ internal abstract void WriteClassHandle (InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType);
- internal abstract void WriteClassInvokerHandle (ClassGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType);
- internal abstract void WriteInterfaceInvokerHandle (InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType);
+ internal abstract void WriteClassInvokerHandle (ClassGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType);
+ internal abstract void WriteInterfaceInvokerHandle (InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType);
- internal abstract void WriteConstructorIdField (Ctor ctor, StreamWriter sw, string indent, CodeGenerationOptions opt);
- internal abstract void WriteConstructorBody (Ctor ctor, StreamWriter sw, string indent, CodeGenerationOptions opt, StringCollection call_cleanup);
+ internal abstract void WriteConstructorIdField (Ctor ctor, TextWriter writer, string indent, CodeGenerationOptions opt);
+ internal abstract void WriteConstructorBody (Ctor ctor, TextWriter writer, string indent, CodeGenerationOptions opt, StringCollection call_cleanup);
- internal abstract void WriteMethodIdField (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt);
- internal abstract void WriteMethodBody (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt);
+ internal abstract void WriteMethodIdField (Method method, TextWriter writer, string indent, CodeGenerationOptions opt);
+ internal abstract void WriteMethodBody (Method method, TextWriter writer, string indent, CodeGenerationOptions opt);
- internal abstract void WriteFieldIdField (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt);
- internal abstract void WriteFieldGetBody (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt);
- internal abstract void WriteFieldSetBody (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt);
+ internal abstract void WriteFieldIdField (Field field, TextWriter writer, string indent, CodeGenerationOptions opt);
+ internal abstract void WriteFieldGetBody (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type);
+ internal abstract void WriteFieldSetBody (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type);
+
+ internal virtual void WriteField (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type)
+ {
+ if (field.IsEnumified)
+ writer.WriteLine ("[global::Android.Runtime.GeneratedEnum]");
+ if (field.NeedsProperty) {
+ string fieldType = field.Symbol.IsArray ? "IList<" + field.Symbol.ElementType + ">" : opt.GetOutputName (field.Symbol.FullName);
+ WriteFieldIdField (field, writer, indent, opt);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}// Metadata.xml XPath field reference: path=\"{1}/field[@name='{2}']\"", indent, type.MetadataXPathReference, field.JavaName);
+ writer.WriteLine ("{0}[Register (\"{1}\"{2})]", indent, field.JavaName, field.AdditionalAttributeString ());
+ writer.WriteLine ("{0}{1} {2}{3} {4} {{", indent, field.Visibility, field.IsStatic ? "static " : String.Empty, fieldType, field.Name);
+ writer.WriteLine ("{0}\tget {{", indent);
+ WriteFieldGetBody (field, writer, indent + "\t\t", opt, type);
+ writer.WriteLine ("{0}\t}}", indent);
+
+ if (!field.IsConst) {
+ writer.WriteLine ("{0}\tset {{", indent);
+ WriteFieldSetBody (field, writer, indent + "\t\t", opt, type);
+ writer.WriteLine ("{0}\t}}", indent);
+ }
+ writer.WriteLine ("{0}}}", indent);
+ }
+ else {
+ writer.WriteLine ("{0}// Metadata.xml XPath field reference: path=\"{1}/field[@name='{2}']\"", indent, type.MetadataXPathReference, field.JavaName);
+ writer.WriteLine ("{0}[Register (\"{1}\"{2})]", indent, field.JavaName, field.AdditionalAttributeString ());
+ if (field.IsDeprecated)
+ writer.WriteLine ("{0}[Obsolete (\"{1}\")]", indent, field.DeprecatedComment);
+ if (field.Annotation != null)
+ writer.WriteLine ("{0}{1}", indent, field.Annotation);
+
+ // the Value complication is due to constant enum from negative integer value (C# compiler requires explicit parenthesis).
+ writer.WriteLine ("{0}{1} const {2} {3} = ({2}) {4};", indent, field.Visibility, opt.GetOutputName (field.Symbol.FullName), field.Name, field.Value.Contains ('-') && field.Symbol.FullName.Contains ('.') ? '(' + field.Value + ')' : field.Value);
+ }
+ }
}
}
diff --git a/tools/generator/Field.cs b/tools/generator/Field.cs
index 4c66716c2..31bc33c5b 100644
--- a/tools/generator/Field.cs
+++ b/tools/generator/Field.cs
@@ -234,45 +234,6 @@ internal ParameterList SetParameters {
public string Annotation { get; internal set; }
- void GenerateProperty (StreamWriter sw, string indent, CodeGenerationOptions opt, GenBase gen)
- {
- string type = Symbol.IsArray ? "IList<" + Symbol.ElementType + ">" : opt.GetOutputName (Symbol.FullName);
- opt.CodeGenerator.WriteFieldIdField (this, sw, indent, opt);
- sw.WriteLine ();
- sw.WriteLine ("{0}// Metadata.xml XPath field reference: path=\"{1}/field[@name='{2}']\"", indent, gen.MetadataXPathReference, JavaName);
- sw.WriteLine ("{0}[Register (\"{1}\"{2})]", indent, JavaName, this.AdditionalAttributeString ());
- sw.WriteLine ("{0}{1} {2}{3} {4} {{", indent, Visibility, IsStatic ? "static " : String.Empty, type, Name);
- sw.WriteLine ("{0}\tget {{", indent);
- opt.CodeGenerator.WriteFieldGetBody (this, sw, indent + "\t\t", opt);
- sw.WriteLine ("{0}\t}}", indent);
-
- if (!IsConst) {
- sw.WriteLine ("{0}\tset {{", indent);
- opt.CodeGenerator.WriteFieldSetBody (this, sw, indent + "\t\t", opt);
- sw.WriteLine ("{0}\t}}", indent);
- }
- sw.WriteLine ("{0}}}", indent);
- }
-
- public void Generate (StreamWriter sw, string indent, CodeGenerationOptions opt, GenBase type)
- {
- if (IsEnumified)
- sw.WriteLine ("[global::Android.Runtime.GeneratedEnum]");
- if (NeedsProperty)
- GenerateProperty (sw, indent, opt, type);
- else {
- sw.WriteLine ("{0}// Metadata.xml XPath field reference: path=\"{1}/field[@name='{2}']\"", indent, type.MetadataXPathReference, JavaName);
- sw.WriteLine ("{0}[Register (\"{1}\"{2})]", indent, JavaName, this.AdditionalAttributeString ());
- if (IsDeprecated)
- sw.WriteLine ("{0}[Obsolete (\"{1}\")]", indent, DeprecatedComment);
- if (Annotation != null)
- sw.WriteLine ("{0}{1}", indent, Annotation);
-
- // the Value complication is due to constant enum from negative integer value (C# compiler requires explicit parenthesis).
- sw.WriteLine ("{0}{1} const {2} {3} = ({2}) {4};", indent, Visibility, opt.GetOutputName (Symbol.FullName), Name, Value.Contains ('-') && Symbol.FullName.Contains ('.') ? '(' + Value + ')' : Value);
- }
- }
-
public bool Validate (CodeGenerationOptions opt, GenericParameterDefinitionList type_params)
{
symbol = SymbolTable.Lookup (TypeName, type_params);
diff --git a/tools/generator/GenBase.cs b/tools/generator/GenBase.cs
index 5e000de2c..e9b52bb24 100644
--- a/tools/generator/GenBase.cs
+++ b/tools/generator/GenBase.cs
@@ -577,7 +577,7 @@ public bool GenFields (StreamWriter sw, string indent, CodeGenerationOptions opt
seen.Add (f.Name);
needsProperty = needsProperty || f.NeedsProperty;
sw.WriteLine ();
- f.Generate (sw, indent, opt, this);
+ opt.CodeGenerator.WriteField (f, sw, indent, opt, this);
}
}
return needsProperty;
diff --git a/tools/generator/JavaInteropCodeGenerator.cs b/tools/generator/JavaInteropCodeGenerator.cs
index c515b7226..635bf56fd 100644
--- a/tools/generator/JavaInteropCodeGenerator.cs
+++ b/tools/generator/JavaInteropCodeGenerator.cs
@@ -19,33 +19,33 @@ static string GetInvokeType (string type)
}
- internal override void WriteClassHandle (ClassGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, bool requireNew)
+ internal override void WriteClassHandle (ClassGen type, TextWriter writer, string indent, CodeGenerationOptions opt, bool requireNew)
{
- sw.WriteLine ("{0}\tinternal {1} static readonly JniPeerMembers _members = new {2} (\"{3}\", typeof ({4}));",
+ writer.WriteLine ("{0}\tinternal {1} static readonly JniPeerMembers _members = new {2} (\"{3}\", typeof ({4}));",
indent,
requireNew ? "new" : " ",
GetPeerMembersType (),
type.RawJniName,
type.Name);
- sw.WriteLine ("{0}\tinternal static {1}IntPtr class_ref {{", indent, requireNew ? "new " : string.Empty);
- sw.WriteLine ("{0}\t\tget {{", indent);
- sw.WriteLine ("{0}\t\t\treturn _members.JniPeerType.PeerReference.Handle;", indent);
- sw.WriteLine ("{0}\t\t}}", indent);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}\tinternal static {1}IntPtr class_ref {{", indent, requireNew ? "new " : string.Empty);
+ writer.WriteLine ("{0}\t\tget {{", indent);
+ writer.WriteLine ("{0}\t\t\treturn _members.JniPeerType.PeerReference.Handle;", indent);
+ writer.WriteLine ("{0}\t\t}}", indent);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
if (type.BaseGen != null && type.InheritsObject) {
- sw.WriteLine ("{0}\tpublic override global::Java.Interop.JniPeerMembers JniPeerMembers {{", indent);
- sw.WriteLine ("{0}\t\tget {{ return _members; }}", indent);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}\tprotected override IntPtr ThresholdClass {{", indent);
- sw.WriteLine ("{0}\t\tget {{ return _members.JniPeerType.PeerReference.Handle; }}", indent);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}\tprotected override global::System.Type ThresholdType {{", indent);
- sw.WriteLine ("{0}\t\tget {{ return _members.ManagedPeerType; }}", indent);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}\tpublic override global::Java.Interop.JniPeerMembers JniPeerMembers {{", indent);
+ writer.WriteLine ("{0}\t\tget {{ return _members; }}", indent);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}\tprotected override IntPtr ThresholdClass {{", indent);
+ writer.WriteLine ("{0}\t\tget {{ return _members.JniPeerType.PeerReference.Handle; }}", indent);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}\tprotected override global::System.Type ThresholdType {{", indent);
+ writer.WriteLine ("{0}\t\tget {{ return _members.ManagedPeerType; }}", indent);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
}
}
@@ -54,175 +54,175 @@ protected virtual string GetPeerMembersType ()
return "JniPeerMembers";
}
- internal override void WriteClassHandle (InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType)
+ internal override void WriteClassHandle (InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType)
{
- sw.WriteLine ("{0}new static JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));",indent, type.RawJniName, declaringType);
+ writer.WriteLine ("{0}new static JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));",indent, type.RawJniName, declaringType);
}
- internal override void WriteClassInvokerHandle (ClassGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType)
+ internal override void WriteClassInvokerHandle (ClassGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType)
{
- sw.WriteLine ("{0}internal new static readonly JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));",
+ writer.WriteLine ("{0}internal new static readonly JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));",
indent,
type.RawJniName,
declaringType);
- sw.WriteLine ();
- sw.WriteLine ("{0}public override global::Java.Interop.JniPeerMembers JniPeerMembers {{", indent);
- sw.WriteLine ("{0}\tget {{ return _members; }}", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
- sw.WriteLine ("{0}\tget {{ return _members.ManagedPeerType; }}", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ();
+ writer.WriteLine ("{0}public override global::Java.Interop.JniPeerMembers JniPeerMembers {{", indent);
+ writer.WriteLine ("{0}\tget {{ return _members; }}", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
+ writer.WriteLine ("{0}\tget {{ return _members.ManagedPeerType; }}", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
}
- internal override void WriteInterfaceInvokerHandle (InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType)
+ internal override void WriteInterfaceInvokerHandle (InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType)
{
- sw.WriteLine ("{0}internal new static readonly JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));",
+ writer.WriteLine ("{0}internal new static readonly JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));",
indent,
type.RawJniName,
declaringType);
- sw.WriteLine ();
- sw.WriteLine ("{0}static IntPtr java_class_ref {{", indent);
- sw.WriteLine ("{0}\tget {{ return _members.JniPeerType.PeerReference.Handle; }}", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}public override global::Java.Interop.JniPeerMembers JniPeerMembers {{", indent);
- sw.WriteLine ("{0}\tget {{ return _members; }}", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}protected override IntPtr ThresholdClass {{", indent);
- sw.WriteLine ("{0}\tget {{ return class_ref; }}", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
- sw.WriteLine ("{0}\tget {{ return _members.ManagedPeerType; }}", indent, declaringType);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ();
+ writer.WriteLine ("{0}static IntPtr java_class_ref {{", indent);
+ writer.WriteLine ("{0}\tget {{ return _members.JniPeerType.PeerReference.Handle; }}", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}public override global::Java.Interop.JniPeerMembers JniPeerMembers {{", indent);
+ writer.WriteLine ("{0}\tget {{ return _members; }}", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}protected override IntPtr ThresholdClass {{", indent);
+ writer.WriteLine ("{0}\tget {{ return class_ref; }}", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
+ writer.WriteLine ("{0}\tget {{ return _members.ManagedPeerType; }}", indent, declaringType);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
}
- internal override void WriteConstructorIdField (Ctor ctor, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteConstructorIdField (Ctor ctor, TextWriter writer, string indent, CodeGenerationOptions opt)
{
// No method id_ctor field required; it's now an `id` constant in the binding.
}
- internal override void WriteConstructorBody (Ctor ctor, StreamWriter sw, string indent, CodeGenerationOptions opt, System.Collections.Specialized.StringCollection call_cleanup)
+ internal override void WriteConstructorBody (Ctor ctor, TextWriter writer, string indent, CodeGenerationOptions opt, System.Collections.Specialized.StringCollection call_cleanup)
{
- sw.WriteLine ("{0}{1}string __id = \"{2}\";",
+ writer.WriteLine ("{0}{1}string __id = \"{2}\";",
indent,
ctor.IsNonStaticNestedType ? "" : "const ",
ctor.IsNonStaticNestedType
? "(" + ctor.Parameters.JniNestedDerivedSignature + ")V"
: ctor.JniSignature);
- sw.WriteLine ();
- sw.WriteLine ("{0}if ({1} != IntPtr.Zero)", indent, opt.ContextType.GetObjectHandleProperty ("this"));
- sw.WriteLine ("{0}\treturn;", indent);
- sw.WriteLine ();
+ writer.WriteLine ();
+ writer.WriteLine ("{0}if ({1} != IntPtr.Zero)", indent, opt.ContextType.GetObjectHandleProperty ("this"));
+ writer.WriteLine ("{0}\treturn;", indent);
+ writer.WriteLine ();
foreach (string prep in ctor.Parameters.GetCallPrep (opt))
- sw.WriteLine ("{0}{1}", indent, prep);
- sw.WriteLine ("{0}try {{", indent);
+ writer.WriteLine ("{0}{1}", indent, prep);
+ writer.WriteLine ("{0}try {{", indent);
var oldindent = indent;
indent += "\t";
- ctor.Parameters.WriteCallArgs (sw, indent, opt, invoker:false);
- sw.WriteLine ("{0}var __r = _members.InstanceMethods.StartCreateInstance (__id, ((object) this).GetType (){1});", indent, ctor.Parameters.GetCallArgs (opt, invoker:false));
- sw.WriteLine ("{0}SetHandle (__r.Handle, JniHandleOwnership.TransferLocalRef);", indent);
- sw.WriteLine ("{0}_members.InstanceMethods.FinishCreateInstance (__id, this{1});", indent, ctor.Parameters.GetCallArgs (opt, invoker:false));
+ ctor.Parameters.WriteCallArgs (writer, indent, opt, invoker:false);
+ writer.WriteLine ("{0}var __r = _members.InstanceMethods.StartCreateInstance (__id, ((object) this).GetType (){1});", indent, ctor.Parameters.GetCallArgs (opt, invoker:false));
+ writer.WriteLine ("{0}SetHandle (__r.Handle, JniHandleOwnership.TransferLocalRef);", indent);
+ writer.WriteLine ("{0}_members.InstanceMethods.FinishCreateInstance (__id, this{1});", indent, ctor.Parameters.GetCallArgs (opt, invoker:false));
indent = oldindent;
- sw.WriteLine ("{0}}} finally {{", indent);
+ writer.WriteLine ("{0}}} finally {{", indent);
foreach (string cleanup in call_cleanup)
- sw.WriteLine ("{0}\t{1}", indent, cleanup);
- sw.WriteLine ("{0}}}", indent);
+ writer.WriteLine ("{0}\t{1}", indent, cleanup);
+ writer.WriteLine ("{0}}}", indent);
}
- internal override void WriteMethodIdField (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteMethodIdField (Method method, TextWriter writer, string indent, CodeGenerationOptions opt)
{
// No method id_ field required; it's now an `id` constant in the binding.
}
- internal override void WriteMethodBody (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteMethodBody (Method method, TextWriter writer, string indent, CodeGenerationOptions opt)
{
- sw.WriteLine ("{0}const string __id = \"{1}.{2}\";", indent, method.JavaName, method.JniSignature);
+ writer.WriteLine ("{0}const string __id = \"{1}.{2}\";", indent, method.JavaName, method.JniSignature);
foreach (string prep in method.Parameters.GetCallPrep (opt))
- sw.WriteLine ("{0}{1}", indent, prep);
- sw.WriteLine ("{0}try {{", indent);
+ writer.WriteLine ("{0}{1}", indent, prep);
+ writer.WriteLine ("{0}try {{", indent);
var oldindent = indent;
indent += "\t";
- method.Parameters.WriteCallArgs (sw, indent, opt, invoker: false);
+ method.Parameters.WriteCallArgs (writer, indent, opt, invoker: false);
var invokeType = GetInvokeType (method.RetVal.CallMethodPrefix);
- sw.Write (indent);
+ writer.Write (indent);
if (!method.IsVoid) {
- sw.Write ("var __rm = ");
+ writer.Write ("var __rm = ");
}
if (method.IsStatic) {
- sw.WriteLine ("_members.StaticMethods.Invoke{0}Method (__id{1});",
+ writer.WriteLine ("_members.StaticMethods.Invoke{0}Method (__id{1});",
invokeType,
method.Parameters.GetCallArgs (opt, invoker: false));
} else if (method.IsFinal) {
- sw.WriteLine ("_members.InstanceMethods.InvokeNonvirtual{0}Method (__id, this{1});",
+ writer.WriteLine ("_members.InstanceMethods.InvokeNonvirtual{0}Method (__id, this{1});",
invokeType,
method.Parameters.GetCallArgs (opt, invoker: false));
} else if (method.IsVirtual && !method.IsAbstract) {
- sw.WriteLine ("_members.InstanceMethods.InvokeVirtual{0}Method (__id, this{1});",
+ writer.WriteLine ("_members.InstanceMethods.InvokeVirtual{0}Method (__id, this{1});",
invokeType,
method.Parameters.GetCallArgs (opt, invoker: false));
} else {
- sw.WriteLine ("_members.InstanceMethods.InvokeAbstract{0}Method (__id, this{1});",
+ writer.WriteLine ("_members.InstanceMethods.InvokeAbstract{0}Method (__id, this{1});",
invokeType,
method.Parameters.GetCallArgs (opt, invoker: false));
}
if (!method.IsVoid) {
var r = invokeType == "Object" ? "__rm.Handle" : "__rm";
- sw.WriteLine ("{0}return {1};", indent, method.RetVal.FromNative (opt, r, true));
+ writer.WriteLine ("{0}return {1};", indent, method.RetVal.FromNative (opt, r, true));
}
indent = oldindent;
- sw.WriteLine ("{0}}} finally {{", indent);
+ writer.WriteLine ("{0}}} finally {{", indent);
foreach (string cleanup in method.Parameters.GetCallCleanup (opt))
- sw.WriteLine ("{0}\t{1}", indent, cleanup);
- sw.WriteLine ("{0}}}", indent);
+ writer.WriteLine ("{0}\t{1}", indent, cleanup);
+ writer.WriteLine ("{0}}}", indent);
}
- internal override void WriteFieldIdField (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteFieldIdField (Field field, TextWriter writer, string indent, CodeGenerationOptions opt)
{
// No field id_ field required
}
- internal override void WriteFieldGetBody (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteFieldGetBody (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type)
{
- sw.WriteLine ("{0}const string __id = \"{1}.{2}\";", indent, field.JavaName, field.Symbol.JniName);
- sw.WriteLine ();
+ writer.WriteLine ("{0}const string __id = \"{1}.{2}\";", indent, field.JavaName, field.Symbol.JniName);
+ writer.WriteLine ();
var invokeType = GetInvokeType (field.GetMethodPrefix);
var indirect = field.IsStatic ? "StaticFields" : "InstanceFields";
var invoke = "Get{0}Value";
invoke = string.Format (invoke, invokeType);
- sw.WriteLine ("{0}var __v = _members.{1}.{2} (__id{3});",
+ writer.WriteLine ("{0}var __v = _members.{1}.{2} (__id{3});",
indent,
indirect,
invoke,
field.IsStatic ? "" : ", this");
if (field.Symbol.IsArray) {
- sw.WriteLine ("{0}return global::Android.Runtime.JavaArray<{1}>.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef);", indent, opt.GetOutputName (field.Symbol.ElementType));
+ writer.WriteLine ("{0}return global::Android.Runtime.JavaArray<{1}>.FromJniHandle (__v.Handle, JniHandleOwnership.TransferLocalRef);", indent, opt.GetOutputName (field.Symbol.ElementType));
}
else if (field.Symbol.NativeType != field.Symbol.FullName) {
- sw.WriteLine ("{0}return {1};",
+ writer.WriteLine ("{0}return {1};",
indent,
field.Symbol.FromNative (opt, invokeType != "Object" ? "__v" : "__v.Handle", true));
} else {
- sw.WriteLine ("{0}return __v;", indent);
+ writer.WriteLine ("{0}return __v;", indent);
}
}
- internal override void WriteFieldSetBody (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteFieldSetBody (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type)
{
- sw.WriteLine ("{0}const string __id = \"{1}.{2}\";", indent, field.JavaName, field.Symbol.JniName);
- sw.WriteLine ();
+ writer.WriteLine ("{0}const string __id = \"{1}.{2}\";", indent, field.JavaName, field.Symbol.JniName);
+ writer.WriteLine ();
var invokeType = GetInvokeType (field.GetMethodPrefix);
var indirect = field.IsStatic ? "StaticFields" : "InstanceFields";
@@ -231,40 +231,40 @@ internal override void WriteFieldSetBody (Field field, StreamWriter sw, string i
bool have_prep = false;
if (field.Symbol.IsArray) {
arg = opt.GetSafeIdentifier (SymbolTable.GetNativeName ("value"));
- sw.WriteLine ("{0}IntPtr {1} = global::Android.Runtime.JavaArray<{2}>.ToLocalJniHandle (value);", indent, arg, opt.GetOutputName (field.Symbol.ElementType));
+ writer.WriteLine ("{0}IntPtr {1} = global::Android.Runtime.JavaArray<{2}>.ToLocalJniHandle (value);", indent, arg, opt.GetOutputName (field.Symbol.ElementType));
} else {
foreach (string prep in field.SetParameters.GetCallPrep (opt)) {
have_prep = true;
- sw.WriteLine ("{0}{1}", indent, prep);
+ writer.WriteLine ("{0}{1}", indent, prep);
}
arg = field.SetParameters [0].ToNative (opt);
if (field.SetParameters.HasCleanup && !have_prep) {
arg = opt.GetSafeIdentifier (SymbolTable.GetNativeName ("value"));
- sw.WriteLine ("{0}IntPtr {1} = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value);", indent, arg);
+ writer.WriteLine ("{0}IntPtr {1} = global::Android.Runtime.JNIEnv.ToLocalJniHandle (value);", indent, arg);
}
}
- sw.WriteLine ("{0}try {{", indent);
+ writer.WriteLine ("{0}try {{", indent);
- sw.WriteLine ("{0}\t_members.{1}.SetValue (__id{2}, {3});",
+ writer.WriteLine ("{0}\t_members.{1}.SetValue (__id{2}, {3});",
indent,
indirect,
field.IsStatic ? "" : ", this",
invokeType != "Object" ? arg : "new JniObjectReference (" + arg + ")");
- sw.WriteLine ("{0}}} finally {{", indent);
+ writer.WriteLine ("{0}}} finally {{", indent);
if (field.Symbol.IsArray) {
- sw.WriteLine ("{0}\tglobal::Android.Runtime.JNIEnv.DeleteLocalRef ({1});", indent, arg);
+ writer.WriteLine ("{0}\tglobal::Android.Runtime.JNIEnv.DeleteLocalRef ({1});", indent, arg);
} else {
foreach (string cleanup in field.SetParameters.GetCallCleanup (opt))
- sw.WriteLine ("{0}\t{1}", indent, cleanup);
+ writer.WriteLine ("{0}\t{1}", indent, cleanup);
if (field.SetParameters.HasCleanup && !have_prep) {
- sw.WriteLine ("{0}\tglobal::Android.Runtime.JNIEnv.DeleteLocalRef ({1});", indent, arg);
+ writer.WriteLine ("{0}\tglobal::Android.Runtime.JNIEnv.DeleteLocalRef ({1});", indent, arg);
}
}
- sw.WriteLine ("{0}}}", indent);
+ writer.WriteLine ("{0}}}", indent);
}
}
}
diff --git a/tools/generator/Parameter.cs b/tools/generator/Parameter.cs
index 405d459b8..9b66baa4c 100644
--- a/tools/generator/Parameter.cs
+++ b/tools/generator/Parameter.cs
@@ -18,7 +18,7 @@ public class Parameter {
ISymbol sym;
bool is_enumified;
- private Parameter (string name, string type, string managedType, bool isEnumified, string rawtype = null)
+ internal Parameter (string name, string type, string managedType, bool isEnumified, string rawtype = null)
{
this.name = name;
this.type = type;
diff --git a/tools/generator/ParameterList.cs b/tools/generator/ParameterList.cs
index 409c85857..dacd5b4c0 100644
--- a/tools/generator/ParameterList.cs
+++ b/tools/generator/ParameterList.cs
@@ -74,7 +74,7 @@ public string JavaCall {
}
}
- public void WriteCallArgs (StreamWriter sw, string indent, CodeGenerationOptions opt, bool invoker)
+ public void WriteCallArgs (TextWriter writer, string indent, CodeGenerationOptions opt, bool invoker)
{
if (items.Count == 0)
return;
@@ -85,10 +85,10 @@ public void WriteCallArgs (StreamWriter sw, string indent, CodeGenerationOptions
JValue = invoker ? JValue : "JniArgumentValue";
break;
}
- sw.WriteLine ("{0}{1}* __args = stackalloc {1} [{2}];", indent, JValue, items.Count);
+ writer.WriteLine ("{0}{1}* __args = stackalloc {1} [{2}];", indent, JValue, items.Count);
for (int i = 0; i < items.Count; ++i) {
var p = items [i];
- sw.WriteLine ("{0}__args [{1}] = new {2} ({3});", indent, i, JValue, p.GetCall (opt));
+ writer.WriteLine ("{0}__args [{1}] = new {2} ({3});", indent, i, JValue, p.GetCall (opt));
}
}
diff --git a/tools/generator/Properties/AssemblyInfo.cs b/tools/generator/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..0021446c8
--- /dev/null
+++ b/tools/generator/Properties/AssemblyInfo.cs
@@ -0,0 +1,3 @@
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("generator-Tests")]
\ No newline at end of file
diff --git a/tools/generator/Tests/AccessModifiers.cs b/tools/generator/Tests/Integration-Tests/AccessModifiers.cs
similarity index 100%
rename from tools/generator/Tests/AccessModifiers.cs
rename to tools/generator/Tests/Integration-Tests/AccessModifiers.cs
diff --git a/tools/generator/Tests/Adapters.cs b/tools/generator/Tests/Integration-Tests/Adapters.cs
similarity index 100%
rename from tools/generator/Tests/Adapters.cs
rename to tools/generator/Tests/Integration-Tests/Adapters.cs
diff --git a/tools/generator/Tests/Android_Graphics_Color.cs b/tools/generator/Tests/Integration-Tests/Android_Graphics_Color.cs
similarity index 100%
rename from tools/generator/Tests/Android_Graphics_Color.cs
rename to tools/generator/Tests/Integration-Tests/Android_Graphics_Color.cs
diff --git a/tools/generator/Tests/Arrays.cs b/tools/generator/Tests/Integration-Tests/Arrays.cs
similarity index 100%
rename from tools/generator/Tests/Arrays.cs
rename to tools/generator/Tests/Integration-Tests/Arrays.cs
diff --git a/tools/generator/Tests/BaseGeneratorTest.cs b/tools/generator/Tests/Integration-Tests/BaseGeneratorTest.cs
similarity index 100%
rename from tools/generator/Tests/BaseGeneratorTest.cs
rename to tools/generator/Tests/Integration-Tests/BaseGeneratorTest.cs
diff --git a/tools/generator/Tests/CSharpKeywords.cs b/tools/generator/Tests/Integration-Tests/CSharpKeywords.cs
similarity index 100%
rename from tools/generator/Tests/CSharpKeywords.cs
rename to tools/generator/Tests/Integration-Tests/CSharpKeywords.cs
diff --git a/tools/generator/Tests/Compiler.cs b/tools/generator/Tests/Integration-Tests/Compiler.cs
similarity index 100%
rename from tools/generator/Tests/Compiler.cs
rename to tools/generator/Tests/Integration-Tests/Compiler.cs
diff --git a/tools/generator/Tests/Constructors.cs b/tools/generator/Tests/Integration-Tests/Constructors.cs
similarity index 100%
rename from tools/generator/Tests/Constructors.cs
rename to tools/generator/Tests/Integration-Tests/Constructors.cs
diff --git a/tools/generator/Tests/Enumerations.cs b/tools/generator/Tests/Integration-Tests/Enumerations.cs
similarity index 100%
rename from tools/generator/Tests/Enumerations.cs
rename to tools/generator/Tests/Integration-Tests/Enumerations.cs
diff --git a/tools/generator/Tests/GenericArguments.cs b/tools/generator/Tests/Integration-Tests/GenericArguments.cs
similarity index 100%
rename from tools/generator/Tests/GenericArguments.cs
rename to tools/generator/Tests/Integration-Tests/GenericArguments.cs
diff --git a/tools/generator/Tests/InterfaceMethodsConflict.cs b/tools/generator/Tests/Integration-Tests/InterfaceMethodsConflict.cs
similarity index 100%
rename from tools/generator/Tests/InterfaceMethodsConflict.cs
rename to tools/generator/Tests/Integration-Tests/InterfaceMethodsConflict.cs
diff --git a/tools/generator/Tests/Interfaces.cs b/tools/generator/Tests/Integration-Tests/Interfaces.cs
similarity index 100%
rename from tools/generator/Tests/Interfaces.cs
rename to tools/generator/Tests/Integration-Tests/Interfaces.cs
diff --git a/tools/generator/Tests/Java_Lang_Enum.cs b/tools/generator/Tests/Integration-Tests/Java_Lang_Enum.cs
similarity index 100%
rename from tools/generator/Tests/Java_Lang_Enum.cs
rename to tools/generator/Tests/Integration-Tests/Java_Lang_Enum.cs
diff --git a/tools/generator/Tests/Java_Lang_Object.cs b/tools/generator/Tests/Integration-Tests/Java_Lang_Object.cs
similarity index 100%
rename from tools/generator/Tests/Java_Lang_Object.cs
rename to tools/generator/Tests/Integration-Tests/Java_Lang_Object.cs
diff --git a/tools/generator/Tests/Java_Util_List.cs b/tools/generator/Tests/Integration-Tests/Java_Util_List.cs
similarity index 100%
rename from tools/generator/Tests/Java_Util_List.cs
rename to tools/generator/Tests/Integration-Tests/Java_Util_List.cs
diff --git a/tools/generator/Tests/NestedTypes.cs b/tools/generator/Tests/Integration-Tests/NestedTypes.cs
similarity index 100%
rename from tools/generator/Tests/NestedTypes.cs
rename to tools/generator/Tests/Integration-Tests/NestedTypes.cs
diff --git a/tools/generator/Tests/NonStaticFields.cs b/tools/generator/Tests/Integration-Tests/NonStaticFields.cs
similarity index 100%
rename from tools/generator/Tests/NonStaticFields.cs
rename to tools/generator/Tests/Integration-Tests/NonStaticFields.cs
diff --git a/tools/generator/Tests/NormalMethods.cs b/tools/generator/Tests/Integration-Tests/NormalMethods.cs
similarity index 100%
rename from tools/generator/Tests/NormalMethods.cs
rename to tools/generator/Tests/Integration-Tests/NormalMethods.cs
diff --git a/tools/generator/Tests/NormalProperties.cs b/tools/generator/Tests/Integration-Tests/NormalProperties.cs
similarity index 100%
rename from tools/generator/Tests/NormalProperties.cs
rename to tools/generator/Tests/Integration-Tests/NormalProperties.cs
diff --git a/tools/generator/Tests/PamareterXPath.cs b/tools/generator/Tests/Integration-Tests/PamareterXPath.cs
similarity index 100%
rename from tools/generator/Tests/PamareterXPath.cs
rename to tools/generator/Tests/Integration-Tests/PamareterXPath.cs
diff --git a/tools/generator/Tests/StaticFields.cs b/tools/generator/Tests/Integration-Tests/StaticFields.cs
similarity index 100%
rename from tools/generator/Tests/StaticFields.cs
rename to tools/generator/Tests/Integration-Tests/StaticFields.cs
diff --git a/tools/generator/Tests/StaticMethods.cs b/tools/generator/Tests/Integration-Tests/StaticMethods.cs
similarity index 100%
rename from tools/generator/Tests/StaticMethods.cs
rename to tools/generator/Tests/Integration-Tests/StaticMethods.cs
diff --git a/tools/generator/Tests/StaticProperties.cs b/tools/generator/Tests/Integration-Tests/StaticProperties.cs
similarity index 100%
rename from tools/generator/Tests/StaticProperties.cs
rename to tools/generator/Tests/Integration-Tests/StaticProperties.cs
diff --git a/tools/generator/Tests/Streams.cs b/tools/generator/Tests/Integration-Tests/Streams.cs
similarity index 100%
rename from tools/generator/Tests/Streams.cs
rename to tools/generator/Tests/Integration-Tests/Streams.cs
diff --git a/tools/generator/Tests/Unit-Tests/JavaInteropCodeGeneratorTests.cs b/tools/generator/Tests/Unit-Tests/JavaInteropCodeGeneratorTests.cs
new file mode 100644
index 000000000..ef137a3c4
--- /dev/null
+++ b/tools/generator/Tests/Unit-Tests/JavaInteropCodeGeneratorTests.cs
@@ -0,0 +1,261 @@
+using MonoDroid.Generation;
+using NUnit.Framework;
+using System.IO;
+using System.Text;
+
+namespace generatortests
+{
+ [TestFixture]
+ class JavaInteropCodeGeneratorTests
+ {
+ CodeGenerator generator;
+ StringBuilder builder;
+ StringWriter writer;
+ CodeGenerationOptions options;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ builder = new StringBuilder ();
+ writer = new StringWriter (builder);
+ options = new CodeGenerationOptions {
+ CodeGenerationTarget = Xamarin.Android.Binder.CodeGenerationTarget.JavaInterop1,
+ };
+ generator = options.CodeGenerator;
+ }
+
+ [TearDown]
+ public void TearDown ()
+ {
+ writer.Dispose ();
+ }
+
+ [Test]
+ public void WriteClassHandle ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+
+ generator.WriteClassHandle (@class, writer, string.Empty, options, false);
+
+ Assert.AreEqual (@" internal static readonly JniPeerMembers _members = new JniPeerMembers (""com/mypackage/foo"", typeof (foo));
+ internal static IntPtr class_ref {
+ get {
+ return _members.JniPeerType.PeerReference.Handle;
+ }
+ }
+
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteClassInvokerHandle ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+
+ generator.WriteClassInvokerHandle (@class, writer, string.Empty, options, "Com.MyPackage.Foo");
+
+ Assert.AreEqual (@"internal new static readonly JniPeerMembers _members = new JniPeerMembers (""com/mypackage/foo"", typeof (Com.MyPackage.Foo));
+
+public override global::Java.Interop.JniPeerMembers JniPeerMembers {
+ get { return _members; }
+}
+
+protected override global::System.Type ThresholdType {
+ get { return _members.ManagedPeerType; }
+}
+
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteFieldIdField ()
+ {
+ var field = new TestField ("java.lang.String", "bar");
+
+ generator.WriteFieldIdField (field, writer, string.Empty, options);
+
+ //NOTE: not needed for JavaInteropCodeGenerator
+ Assert.AreEqual ("", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteFieldGetBody ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteFieldGetBody (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"const string __id = ""bar.Ljava/lang/String;"";
+
+var __v = _members.InstanceFields.GetObjectValue (__id, this);
+return JNIEnv.GetString (__v.Handle, JniHandleOwnership.TransferLocalRef);
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteFieldSetBody ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteFieldSetBody (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"const string __id = ""bar.Ljava/lang/String;"";
+
+IntPtr native_value = JNIEnv.NewString (value);
+try {
+ _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value));
+} finally {
+ JNIEnv.DeleteLocalRef (native_value);
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteStringField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"
+// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public string bar {
+ get {
+ const string __id = ""bar.Ljava/lang/String;"";
+
+ var __v = _members.InstanceFields.GetObjectValue (__id, this);
+ return JNIEnv.GetString (__v.Handle, JniHandleOwnership.TransferLocalRef);
+ }
+ set {
+ const string __id = ""bar.Ljava/lang/String;"";
+
+ IntPtr native_value = JNIEnv.NewString (value);
+ try {
+ _members.InstanceFields.SetValue (__id, this, new JniObjectReference (native_value));
+ } finally {
+ JNIEnv.DeleteLocalRef (native_value);
+ }
+ }
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteIntField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"
+// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public int bar {
+ get {
+ const string __id = ""bar.I"";
+
+ var __v = _members.InstanceFields.GetInt32Value (__id, this);
+ return __v;
+ }
+ set {
+ const string __id = ""bar.I"";
+
+ try {
+ _members.InstanceFields.SetValue (__id, this, value);
+ } finally {
+ }
+ }
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteEnumifiedField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetEnumified ();
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ StringAssert.Contains ("[global::Android.Runtime.GeneratedEnum]", builder.ToString (), "Should contain GeneratedEnumAttribute!");
+ }
+
+ [Test]
+ public void WriteDeprecatedField ()
+ {
+ var comment = "Don't use this!";
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetConstant ("1234").SetDeprecated (comment);
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ StringAssert.Contains ($"[Obsolete (\"{comment}\")]", builder.ToString (), "Should contain ObsoleteAttribute!");
+ }
+
+ [Test]
+ public void WriteProtectedField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetVisibility ("protected");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ StringAssert.Contains ("protected int bar {", builder.ToString (), "Property should be protected!");
+ }
+
+ [Test]
+ public void WriteConstantField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar").SetConstant ();
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"
+// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public static string bar {
+ get {
+ const string __id = ""bar.Ljava/lang/String;"";
+
+ var __v = _members.StaticFields.GetObjectValue (__id);
+ return JNIEnv.GetString (__v.Handle, JniHandleOwnership.TransferLocalRef);
+ }
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteConstantFieldWithStringValue ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar").SetConstant ("\"hello\"");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public const string bar = (string) ""hello"";
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteConstantFieldWithIntValue ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetConstant ("1234");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public const int bar = (int) 1234;
+", builder.ToString ());
+ }
+ }
+}
diff --git a/tools/generator/Tests/Unit-Tests/SupportTypes.cs b/tools/generator/Tests/Unit-Tests/SupportTypes.cs
new file mode 100644
index 000000000..14fc79521
--- /dev/null
+++ b/tools/generator/Tests/Unit-Tests/SupportTypes.cs
@@ -0,0 +1,140 @@
+using MonoDroid.Generation;
+using System.Linq;
+
+namespace generatortests
+{
+ class TestClass : ClassGen
+ {
+ public TestClass (string baseType, string javaName) : base (new TestBaseSupport (javaName))
+ {
+ this.BaseType = BaseType;
+ }
+
+ public override bool IsAbstract => false;
+
+ public override bool IsFinal => false;
+
+ public override string BaseType { get; set; }
+ }
+
+ class TestBaseSupport : GenBaseSupport
+ {
+ public TestBaseSupport (string javaName)
+ {
+ var split = javaName.Split ('.');
+ Name = split.Last ();
+ FullName = javaName;
+ PackageName = javaName.Substring (0, javaName.Length - Name.Length - 1);
+ }
+
+ public override bool IsAcw => false;
+
+ public override bool IsDeprecated => false;
+
+ public override string DeprecatedComment => string.Empty;
+
+ public override bool IsGeneratable => true;
+
+ public override bool IsGeneric => false;
+
+ public override bool IsObfuscated => false;
+
+ public override string FullName { get; set; }
+
+ public override string Name { get; set; }
+
+ public override string Namespace => PackageName;
+
+ public override string JavaSimpleName => Name;
+
+ public override string PackageName { get; set; }
+
+ public override string Visibility => "public";
+
+ GenericParameterDefinitionList typeParameters = new GenericParameterDefinitionList ();
+
+ public override GenericParameterDefinitionList TypeParameters => typeParameters;
+ }
+
+ class TestField : Field
+ {
+ bool isFinal, isStatic, isEnumified, isDeprecated;
+ string type, value, deprecatedComment, visibility = "public";
+ ISymbol managedSymbol;
+ Parameter setterParameter;
+
+ public TestField (string type, string name)
+ {
+ this.type = type;
+ Name = name;
+
+ //HACK: SymbolTable is static, hence problematic for testing
+ // If running a unit test first, we need to add java.lang.String.
+ // If an integration test was run, java.lang.String exists already.
+ // Down the line SymbolTable should be refactored to be non-static, so this could be done in [SetUp]
+ managedSymbol = SymbolTable.Lookup (type) ??
+ new SimpleSymbol ("", "java.lang.String", "Ljava/lang/String;", "Java.Lang.String");
+ }
+
+ public TestField SetStatic ()
+ {
+ isStatic = true;
+ return this;
+ }
+
+ public TestField SetConstant (string value = null)
+ {
+ isFinal =
+ isStatic = true;
+ this.value = value;
+ return this;
+ }
+
+ public TestField SetEnumified ()
+ {
+ isEnumified = true;
+ return this;
+ }
+
+ public TestField SetDeprecated (string comment = null)
+ {
+ isDeprecated = true;
+ deprecatedComment = comment;
+ return this;
+ }
+
+ public TestField SetVisibility (string visibility)
+ {
+ this.visibility = visibility;
+ return this;
+ }
+
+ public override bool IsDeprecated => isDeprecated;
+
+ public override string DeprecatedComment => deprecatedComment;
+
+ public override bool IsFinal => isFinal;
+
+ public override bool IsStatic => isStatic;
+
+ public override string JavaName => Name;
+
+ public override bool IsEnumified => isEnumified;
+
+ public override string TypeName => type;
+
+ public override string Name { get; set; }
+
+ public override string Value => value;
+
+ public override string Visibility => visibility;
+
+ protected override Parameter SetterParameter {
+ get {
+ if (setterParameter == null)
+ setterParameter = new Parameter ("value", type, managedSymbol.FullName, isEnumified);
+ return setterParameter;
+ }
+ }
+ }
+}
diff --git a/tools/generator/Tests/Unit-Tests/XamarinAndroidCodeGeneratorTests.cs b/tools/generator/Tests/Unit-Tests/XamarinAndroidCodeGeneratorTests.cs
new file mode 100644
index 000000000..0936214d7
--- /dev/null
+++ b/tools/generator/Tests/Unit-Tests/XamarinAndroidCodeGeneratorTests.cs
@@ -0,0 +1,257 @@
+using MonoDroid.Generation;
+using NUnit.Framework;
+using System.IO;
+using System.Text;
+
+namespace generatortests
+{
+ [TestFixture]
+ public class XamarinAndroidCodeGeneratorTests
+ {
+ CodeGenerator generator;
+ StringBuilder builder;
+ StringWriter writer;
+ CodeGenerationOptions options;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ builder = new StringBuilder ();
+ writer = new StringWriter (builder);
+ options = new CodeGenerationOptions {
+ CodeGenerationTarget = Xamarin.Android.Binder.CodeGenerationTarget.XamarinAndroid,
+ };
+ generator = options.CodeGenerator;
+ }
+
+ [TearDown]
+ public void TearDown ()
+ {
+ writer.Dispose ();
+ }
+
+ [Test]
+ public void WriteClassHandle()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+
+ generator.WriteClassHandle (@class, writer, string.Empty, options, false);
+
+ Assert.AreEqual (@" internal static IntPtr java_class_handle;
+ internal static IntPtr class_ref {
+ get {
+ return JNIEnv.FindClass (""com/mypackage/foo"", ref java_class_handle);
+ }
+ }
+
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteClassInvokerHandle ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+
+ generator.WriteClassInvokerHandle (@class, writer, string.Empty, options, "Com.MyPackage.Foo");
+
+ Assert.AreEqual (@"protected override global::System.Type ThresholdType {
+ get { return typeof (Com.MyPackage.Foo); }
+}
+
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteFieldIdField ()
+ {
+ var field = new TestField ("java.lang.String", "bar");
+
+ generator.WriteFieldIdField (field, writer, string.Empty, options);
+
+ Assert.AreEqual (@"static IntPtr bar_jfieldId;
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteFieldGetBody ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteFieldGetBody (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetFieldID (class_ref, ""bar"", ""Ljava/lang/String;"");
+IntPtr __ret = JNIEnv.GetObjectField (((global::Java.Lang.Object) this).Handle, bar_jfieldId);
+return JNIEnv.GetString (__ret, JniHandleOwnership.TransferLocalRef);
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteFieldSetBody ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteFieldSetBody (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetFieldID (class_ref, ""bar"", ""Ljava/lang/String;"");
+IntPtr native_value = JNIEnv.NewString (value);
+try {
+ JNIEnv.SetField (((global::Java.Lang.Object) this).Handle, bar_jfieldId, native_value);
+} finally {
+ JNIEnv.DeleteLocalRef (native_value);
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteStringField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"static IntPtr bar_jfieldId;
+
+// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public string bar {
+ get {
+ if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetFieldID (class_ref, ""bar"", ""Ljava/lang/String;"");
+ IntPtr __ret = JNIEnv.GetObjectField (((global::Java.Lang.Object) this).Handle, bar_jfieldId);
+ return JNIEnv.GetString (__ret, JniHandleOwnership.TransferLocalRef);
+ }
+ set {
+ if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetFieldID (class_ref, ""bar"", ""Ljava/lang/String;"");
+ IntPtr native_value = JNIEnv.NewString (value);
+ try {
+ JNIEnv.SetField (((global::Java.Lang.Object) this).Handle, bar_jfieldId, native_value);
+ } finally {
+ JNIEnv.DeleteLocalRef (native_value);
+ }
+ }
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteIntField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"static IntPtr bar_jfieldId;
+
+// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public int bar {
+ get {
+ if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetFieldID (class_ref, ""bar"", ""I"");
+ return JNIEnv.GetIntField (((global::Java.Lang.Object) this).Handle, bar_jfieldId);
+ }
+ set {
+ if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetFieldID (class_ref, ""bar"", ""I"");
+ try {
+ JNIEnv.SetField (((global::Java.Lang.Object) this).Handle, bar_jfieldId, value);
+ } finally {
+ }
+ }
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteEnumifiedField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetEnumified ();
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ StringAssert.Contains ("[global::Android.Runtime.GeneratedEnum]", builder.ToString (), "Should contain GeneratedEnumAttribute!");
+ }
+
+ [Test]
+ public void WriteDeprecatedField ()
+ {
+ var comment = "Don't use this!";
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetConstant ("1234").SetDeprecated (comment);
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ StringAssert.Contains ($"[Obsolete (\"{comment}\")]", builder.ToString (), "Should contain ObsoleteAttribute!");
+ }
+
+ [Test]
+ public void WriteProtectedField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetVisibility ("protected");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ StringAssert.Contains ("protected int bar {", builder.ToString (), "Property should be protected!");
+ }
+
+ [Test]
+ public void WriteConstantField ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar").SetConstant ();
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"static IntPtr bar_jfieldId;
+
+// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public static string bar {
+ get {
+ if (bar_jfieldId == IntPtr.Zero)
+ bar_jfieldId = JNIEnv.GetStaticFieldID (class_ref, ""bar"", ""Ljava/lang/String;"");
+ IntPtr __ret = JNIEnv.GetStaticObjectField (class_ref, bar_jfieldId);
+ return JNIEnv.GetString (__ret, JniHandleOwnership.TransferLocalRef);
+ }
+}
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteConstantFieldWithStringValue ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("java.lang.String", "bar").SetConstant ("\"hello\"");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public const string bar = (string) ""hello"";
+", builder.ToString ());
+ }
+
+ [Test]
+ public void WriteConstantFieldWithIntValue ()
+ {
+ var @class = new TestClass ("java.lang.Object", "com.mypackage.foo");
+ var field = new TestField ("int", "bar").SetConstant ("1234");
+ Assert.IsTrue (field.Validate (options, new GenericParameterDefinitionList ()), "field.Validate failed!");
+ generator.WriteField (field, writer, string.Empty, options, @class);
+
+ Assert.AreEqual (@"// Metadata.xml XPath field reference: path=""/api/package[@name='com.mypackage']/class[@name='foo']/field[@name='bar']""
+[Register (""bar"")]
+public const int bar = (int) 1234;
+", builder.ToString ());
+ }
+ }
+}
diff --git a/tools/generator/Tests/generator-Tests.csproj b/tools/generator/Tests/generator-Tests.csproj
index 4ede84fee..542a7afe3 100644
--- a/tools/generator/Tests/generator-Tests.csproj
+++ b/tools/generator/Tests/generator-Tests.csproj
@@ -42,30 +42,33 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -182,5 +185,8 @@
+
+
+
-
+
\ No newline at end of file
diff --git a/tools/generator/XamarinAndroidCodeGenerator.cs b/tools/generator/XamarinAndroidCodeGenerator.cs
index 5dc77792a..ca2ff1a65 100644
--- a/tools/generator/XamarinAndroidCodeGenerator.cs
+++ b/tools/generator/XamarinAndroidCodeGenerator.cs
@@ -5,144 +5,144 @@ namespace MonoDroid.Generation {
class XamarinAndroidCodeGenerator : CodeGenerator {
- internal override void WriteClassHandle (ClassGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, bool requireNew)
+ internal override void WriteClassHandle (ClassGen type, TextWriter writer, string indent, CodeGenerationOptions opt, bool requireNew)
{
- sw.WriteLine ("{0}\tinternal static {1}IntPtr java_class_handle;", indent, requireNew ? "new " : string.Empty);
- sw.WriteLine ("{0}\tinternal static {1}IntPtr class_ref {{", indent, requireNew ? "new " : string.Empty);
- sw.WriteLine ("{0}\t\tget {{", indent);
- sw.WriteLine ("{0}\t\t\treturn JNIEnv.FindClass (\"{1}\", ref java_class_handle);", indent, type.RawJniName);
- sw.WriteLine ("{0}\t\t}}", indent);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}\tinternal static {1}IntPtr java_class_handle;", indent, requireNew ? "new " : string.Empty);
+ writer.WriteLine ("{0}\tinternal static {1}IntPtr class_ref {{", indent, requireNew ? "new " : string.Empty);
+ writer.WriteLine ("{0}\t\tget {{", indent);
+ writer.WriteLine ("{0}\t\t\treturn JNIEnv.FindClass (\"{1}\", ref java_class_handle);", indent, type.RawJniName);
+ writer.WriteLine ("{0}\t\t}}", indent);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
if (type.BaseGen != null && type.InheritsObject) {
- sw.WriteLine ("{0}\tprotected override IntPtr ThresholdClass {{", indent);
- sw.WriteLine ("{0}\t\tget {{ return class_ref; }}", indent);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}\tprotected override global::System.Type ThresholdType {{", indent);
- sw.WriteLine ("{0}\t\tget {{ return typeof ({1}); }}", indent, type.Name);
- sw.WriteLine ("{0}\t}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}\tprotected override IntPtr ThresholdClass {{", indent);
+ writer.WriteLine ("{0}\t\tget {{ return class_ref; }}", indent);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}\tprotected override global::System.Type ThresholdType {{", indent);
+ writer.WriteLine ("{0}\t\tget {{ return typeof ({1}); }}", indent, type.Name);
+ writer.WriteLine ("{0}\t}}", indent);
+ writer.WriteLine ();
}
}
- internal override void WriteClassHandle (InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType)
+ internal override void WriteClassHandle (InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType)
{
- sw.WriteLine ("{0}new static IntPtr class_ref = JNIEnv.FindClass (\"{1}\");", indent, type.RawJniName);
+ writer.WriteLine ("{0}new static IntPtr class_ref = JNIEnv.FindClass (\"{1}\");", indent, type.RawJniName);
}
- internal override void WriteClassInvokerHandle (ClassGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType)
+ internal override void WriteClassInvokerHandle (ClassGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType)
{
- sw.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
- sw.WriteLine ("{0}\tget {{ return typeof ({1}); }}", indent, declaringType);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
+ writer.WriteLine ("{0}\tget {{ return typeof ({1}); }}", indent, declaringType);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
}
- internal override void WriteInterfaceInvokerHandle (InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType)
+ internal override void WriteInterfaceInvokerHandle (InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType)
{
- sw.WriteLine ("{0}static IntPtr java_class_ref = JNIEnv.FindClass (\"{1}\");", indent, type.RawJniName);
- sw.WriteLine ();
- sw.WriteLine ("{0}protected override IntPtr ThresholdClass {{", indent);
- sw.WriteLine ("{0}\tget {{ return class_ref; }}", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
- sw.WriteLine ("{0}\tget {{ return typeof ({1}); }}", indent, declaringType);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}static IntPtr java_class_ref = JNIEnv.FindClass (\"{1}\");", indent, type.RawJniName);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}protected override IntPtr ThresholdClass {{", indent);
+ writer.WriteLine ("{0}\tget {{ return class_ref; }}", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}protected override global::System.Type ThresholdType {{", indent);
+ writer.WriteLine ("{0}\tget {{ return typeof ({1}); }}", indent, declaringType);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
}
- internal override void WriteConstructorIdField (Ctor ctor, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteConstructorIdField (Ctor ctor, TextWriter writer, string indent, CodeGenerationOptions opt)
{
- sw.WriteLine ("{0}static IntPtr {1};", indent, ctor.ID);
+ writer.WriteLine ("{0}static IntPtr {1};", indent, ctor.ID);
}
- internal override void WriteConstructorBody (Ctor ctor, StreamWriter sw, string indent, CodeGenerationOptions opt, System.Collections.Specialized.StringCollection call_cleanup)
+ internal override void WriteConstructorBody (Ctor ctor, TextWriter writer, string indent, CodeGenerationOptions opt, System.Collections.Specialized.StringCollection call_cleanup)
{
- sw.WriteLine ("{0}if ({1} != IntPtr.Zero)", indent, opt.ContextType.GetObjectHandleProperty ("this"));
- sw.WriteLine ("{0}\treturn;", indent);
- sw.WriteLine ();
+ writer.WriteLine ("{0}if ({1} != IntPtr.Zero)", indent, opt.ContextType.GetObjectHandleProperty ("this"));
+ writer.WriteLine ("{0}\treturn;", indent);
+ writer.WriteLine ();
foreach (string prep in ctor.Parameters.GetCallPrep (opt))
- sw.WriteLine ("{0}{1}", indent, prep);
- sw.WriteLine ("{0}try {{", indent);
+ writer.WriteLine ("{0}{1}", indent, prep);
+ writer.WriteLine ("{0}try {{", indent);
var oldindent = indent;
indent += "\t";
- ctor.Parameters.WriteCallArgs (sw, indent, opt, invoker:false);
- sw.WriteLine ("{0}if (((object) this).GetType () != typeof ({1})) {{", indent, ctor.Name);
- sw.WriteLine ("{0}\tSetHandle (", indent);
- sw.WriteLine ("{0}\t\t\tglobal::Android.Runtime.JNIEnv.StartCreateInstance (((object) this).GetType (), \"{1}\"{2}),",
+ ctor.Parameters.WriteCallArgs (writer, indent, opt, invoker:false);
+ writer.WriteLine ("{0}if (((object) this).GetType () != typeof ({1})) {{", indent, ctor.Name);
+ writer.WriteLine ("{0}\tSetHandle (", indent);
+ writer.WriteLine ("{0}\t\t\tglobal::Android.Runtime.JNIEnv.StartCreateInstance (((object) this).GetType (), \"{1}\"{2}),",
indent,
ctor.IsNonStaticNestedType ? "(" + ctor.Parameters.JniNestedDerivedSignature + ")V" : ctor.JniSignature,
ctor.Parameters.GetCallArgs (opt, invoker:false));
- sw.WriteLine ("{0}\t\t\tJniHandleOwnership.TransferLocalRef);", indent);
- sw.WriteLine ("{0}\tglobal::Android.Runtime.JNIEnv.FinishCreateInstance ({1}, \"{2}\"{3});",
+ writer.WriteLine ("{0}\t\t\tJniHandleOwnership.TransferLocalRef);", indent);
+ writer.WriteLine ("{0}\tglobal::Android.Runtime.JNIEnv.FinishCreateInstance ({1}, \"{2}\"{3});",
indent,
opt.ContextType.GetObjectHandleProperty ("this"),
ctor.IsNonStaticNestedType ? "(" + ctor.Parameters.JniNestedDerivedSignature + ")V" : ctor.JniSignature,
ctor.Parameters.GetCallArgs (opt, invoker:false));
- sw.WriteLine ("{0}\treturn;", indent);
- sw.WriteLine ("{0}}}", indent);
- sw.WriteLine ();
- sw.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, ctor.ID);
- sw.WriteLine ("{0}\t{1} = JNIEnv.GetMethodID (class_ref, \"\", \"{2}\");", indent, ctor.ID, ctor.JniSignature);
- sw.WriteLine ("{0}SetHandle (", indent);
- sw.WriteLine ("{0}\t\tglobal::Android.Runtime.JNIEnv.StartCreateInstance (class_ref, {1}{2}),",
+ writer.WriteLine ("{0}\treturn;", indent);
+ writer.WriteLine ("{0}}}", indent);
+ writer.WriteLine ();
+ writer.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, ctor.ID);
+ writer.WriteLine ("{0}\t{1} = JNIEnv.GetMethodID (class_ref, \"\", \"{2}\");", indent, ctor.ID, ctor.JniSignature);
+ writer.WriteLine ("{0}SetHandle (", indent);
+ writer.WriteLine ("{0}\t\tglobal::Android.Runtime.JNIEnv.StartCreateInstance (class_ref, {1}{2}),",
indent, ctor.ID, ctor.Parameters.GetCallArgs (opt, invoker:false));
- sw.WriteLine ("{0}\t\tJniHandleOwnership.TransferLocalRef);", indent);
- sw.WriteLine ("{0}JNIEnv.FinishCreateInstance ({1}, class_ref, {2}{3});",
+ writer.WriteLine ("{0}\t\tJniHandleOwnership.TransferLocalRef);", indent);
+ writer.WriteLine ("{0}JNIEnv.FinishCreateInstance ({1}, class_ref, {2}{3});",
indent,
opt.ContextType.GetObjectHandleProperty ("this"),
ctor.ID,
ctor.Parameters.GetCallArgs (opt, invoker:false));
indent = oldindent;
- sw.WriteLine ("{0}}} finally {{", indent);
+ writer.WriteLine ("{0}}} finally {{", indent);
foreach (string cleanup in call_cleanup)
- sw.WriteLine ("{0}\t{1}", indent, cleanup);
- sw.WriteLine ("{0}}}", indent);
+ writer.WriteLine ("{0}\t{1}", indent, cleanup);
+ writer.WriteLine ("{0}}}", indent);
}
- internal override void WriteMethodIdField (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteMethodIdField (Method method, TextWriter writer, string indent, CodeGenerationOptions opt)
{
- sw.WriteLine ("{0}static IntPtr {1};", indent, method.EscapedIdName);
+ writer.WriteLine ("{0}static IntPtr {1};", indent, method.EscapedIdName);
}
- void GenerateJNICall (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt, string call, bool declare_ret)
+ void GenerateJNICall (Method method, TextWriter writer, string indent, CodeGenerationOptions opt, string call, bool declare_ret)
{
if (method.IsVoid)
- sw.WriteLine ("{0}{1};", indent, call);
+ writer.WriteLine ("{0}{1};", indent, call);
else if (method.Parameters.HasCleanup)
- sw.WriteLine ("{0}{1}__ret = {2};", indent, declare_ret ? opt.GetOutputName (method.RetVal.FullName) + " " : String.Empty, method.RetVal.FromNative (opt, call, true));
+ writer.WriteLine ("{0}{1}__ret = {2};", indent, declare_ret ? opt.GetOutputName (method.RetVal.FullName) + " " : String.Empty, method.RetVal.FromNative (opt, call, true));
else
- sw.WriteLine ("{0}return {1};", indent, method.RetVal.FromNative (opt, call, true));
+ writer.WriteLine ("{0}return {1};", indent, method.RetVal.FromNative (opt, call, true));
}
- internal override void WriteMethodBody (Method method, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteMethodBody (Method method, TextWriter writer, string indent, CodeGenerationOptions opt)
{
- sw.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, method.EscapedIdName);
- sw.WriteLine ("{0}\t{1} = JNIEnv.Get{2}MethodID (class_ref, \"{3}\", \"{4}\");", indent, method.EscapedIdName, method.IsStatic ? "Static" : String.Empty, method.JavaName, method.JniSignature);
+ writer.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, method.EscapedIdName);
+ writer.WriteLine ("{0}\t{1} = JNIEnv.Get{2}MethodID (class_ref, \"{3}\", \"{4}\");", indent, method.EscapedIdName, method.IsStatic ? "Static" : String.Empty, method.JavaName, method.JniSignature);
bool use_non_virtual = method.IsVirtual && !method.IsAbstract;
foreach (string prep in method.Parameters.GetCallPrep (opt))
- sw.WriteLine ("{0}{1}", indent, prep);
- sw.WriteLine ("{0}try {{", indent);
+ writer.WriteLine ("{0}{1}", indent, prep);
+ writer.WriteLine ("{0}try {{", indent);
var oldindent = indent;
indent += "\t";
- method.Parameters.WriteCallArgs (sw, indent, opt, invoker: false);
+ method.Parameters.WriteCallArgs (writer, indent, opt, invoker: false);
if (method.IsStatic) {
- GenerateJNICall (method, sw, indent, opt, "JNIEnv.CallStatic" + method.RetVal.CallMethodPrefix + "Method (class_ref, " + method.EscapedIdName + method.Parameters.GetCallArgs (opt, invoker:false) + ")", true);
+ GenerateJNICall (method, writer, indent, opt, "JNIEnv.CallStatic" + method.RetVal.CallMethodPrefix + "Method (class_ref, " + method.EscapedIdName + method.Parameters.GetCallArgs (opt, invoker:false) + ")", true);
} else if (use_non_virtual) {
- sw.WriteLine ();
+ writer.WriteLine ();
if (!method.IsVoid && method.Parameters.HasCleanup)
- sw.WriteLine ("{0}{1} __ret;", indent, opt.GetOutputName (method.RetVal.FullName));
- sw.WriteLine ("{0}if (((object) this).GetType () == ThresholdType)", indent);
- GenerateJNICall (method, sw, indent + "\t", opt,
+ writer.WriteLine ("{0}{1} __ret;", indent, opt.GetOutputName (method.RetVal.FullName));
+ writer.WriteLine ("{0}if (((object) this).GetType () == ThresholdType)", indent);
+ GenerateJNICall (method, writer, indent + "\t", opt,
"JNIEnv.Call" + method.RetVal.CallMethodPrefix + "Method (" +
opt.ContextType.GetObjectHandleProperty ("this") +
", " + method.EscapedIdName + method.Parameters.GetCallArgs (opt, invoker:false) + ")",
declare_ret: false);
- sw.WriteLine ("{0}else", indent);
- GenerateJNICall (method, sw, indent + "\t", opt,
+ writer.WriteLine ("{0}else", indent);
+ GenerateJNICall (method, writer, indent + "\t", opt,
"JNIEnv.CallNonvirtual" + method.RetVal.CallMethodPrefix + "Method (" +
opt.ContextType.GetObjectHandleProperty ("this") +
", ThresholdClass, " +
@@ -152,7 +152,7 @@ internal override void WriteMethodBody (Method method, StreamWriter sw, string i
} else {
GenerateJNICall (
method,
- sw,
+ writer,
indent,
opt,
"JNIEnv.Call" + method.RetVal.CallMethodPrefix + "Method (" +
@@ -163,23 +163,23 @@ internal override void WriteMethodBody (Method method, StreamWriter sw, string i
}
if (!method.IsVoid && method.Parameters.HasCleanup)
- sw.WriteLine ("{0}return __ret;", indent);
+ writer.WriteLine ("{0}return __ret;", indent);
indent = oldindent;
- sw.WriteLine ("{0}}} finally {{", indent);
+ writer.WriteLine ("{0}}} finally {{", indent);
foreach (string cleanup in method.Parameters.GetCallCleanup (opt))
- sw.WriteLine ("{0}\t{1}", indent, cleanup);
- sw.WriteLine ("{0}}}", indent);
+ writer.WriteLine ("{0}\t{1}", indent, cleanup);
+ writer.WriteLine ("{0}}}", indent);
}
- internal override void WriteFieldIdField (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteFieldIdField (Field field, TextWriter writer, string indent, CodeGenerationOptions opt)
{
- sw.WriteLine ("{0}static IntPtr {1};", indent, field.ID);
+ writer.WriteLine ("{0}static IntPtr {1};", indent, field.ID);
}
- internal override void WriteFieldGetBody (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteFieldGetBody (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type)
{
- sw.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, field.ID);
- sw.WriteLine ("{0}\t{1} = JNIEnv.Get{2}FieldID (class_ref, \"{3}\", \"{4}\");", indent, field.ID, field.IsStatic ? "Static" : String.Empty, field.JavaName, field.Symbol.JniName);
+ writer.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, field.ID);
+ writer.WriteLine ("{0}\t{1} = JNIEnv.Get{2}FieldID (class_ref, \"{3}\", \"{4}\");", indent, field.ID, field.IsStatic ? "Static" : String.Empty, field.JavaName, field.Symbol.JniName);
string call = String.Format ("JNIEnv.Get{0}{1}Field ({2}, {3})",
field.IsStatic
? "Static"
@@ -187,69 +187,69 @@ internal override void WriteFieldGetBody (Field field, StreamWriter sw, string i
field.GetMethodPrefix,
field.IsStatic
? "class_ref"
- : opt.ContextType.GetObjectHandleProperty ("this"),
+ : type.GetObjectHandleProperty ("this"),
field.ID);
//var asym = Symbol as ArraySymbol;
if (field.Symbol.IsArray) {
- sw.WriteLine ("{0}return global::Android.Runtime.JavaArray<{1}>.FromJniHandle ({2}, JniHandleOwnership.TransferLocalRef);", indent, opt.GetOutputName (field.Symbol.ElementType), call);
+ writer.WriteLine ("{0}return global::Android.Runtime.JavaArray<{1}>.FromJniHandle ({2}, JniHandleOwnership.TransferLocalRef);", indent, opt.GetOutputName (field.Symbol.ElementType), call);
}
else if (field.Symbol.NativeType != field.Symbol.FullName) {
- sw.WriteLine ("{0}{1} __ret = {2};", indent, field.Symbol.NativeType, call);
- sw.WriteLine ("{0}return {1};", indent, field.Symbol.FromNative (opt, "__ret", true));
+ writer.WriteLine ("{0}{1} __ret = {2};", indent, field.Symbol.NativeType, call);
+ writer.WriteLine ("{0}return {1};", indent, field.Symbol.FromNative (opt, "__ret", true));
} else {
- sw.WriteLine ("{0}return {1};", indent, call);
+ writer.WriteLine ("{0}return {1};", indent, call);
}
}
- internal override void WriteFieldSetBody (Field field, StreamWriter sw, string indent, CodeGenerationOptions opt)
+ internal override void WriteFieldSetBody (Field field, TextWriter writer, string indent, CodeGenerationOptions opt, GenBase type)
{
- sw.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, field.ID);
- sw.WriteLine ("{0}\t{1} = JNIEnv.Get{2}FieldID (class_ref, \"{3}\", \"{4}\");", indent, field.ID, field.IsStatic ? "Static" : String.Empty, field.JavaName, field.Symbol.JniName);
+ writer.WriteLine ("{0}if ({1} == IntPtr.Zero)", indent, field.ID);
+ writer.WriteLine ("{0}\t{1} = JNIEnv.Get{2}FieldID (class_ref, \"{3}\", \"{4}\");", indent, field.ID, field.IsStatic ? "Static" : String.Empty, field.JavaName, field.Symbol.JniName);
string arg;
bool have_prep = false;
if (field.Symbol.IsArray) {
arg = opt.GetSafeIdentifier (SymbolTable.GetNativeName ("value"));
- sw.WriteLine ("{0}IntPtr {1} = global::Android.Runtime.JavaArray<{2}>.ToLocalJniHandle (value);", indent, arg, opt.GetOutputName (field.Symbol.ElementType));
+ writer.WriteLine ("{0}IntPtr {1} = global::Android.Runtime.JavaArray<{2}>.ToLocalJniHandle (value);", indent, arg, opt.GetOutputName (field.Symbol.ElementType));
} else {
foreach (string prep in field.SetParameters.GetCallPrep (opt)) {
have_prep = true;
- sw.WriteLine ("{0}{1}", indent, prep);
+ writer.WriteLine ("{0}{1}", indent, prep);
}
arg = field.SetParameters [0].ToNative (opt);
if (field.SetParameters.HasCleanup && !have_prep) {
arg = opt.GetSafeIdentifier (SymbolTable.GetNativeName ("value"));
- sw.WriteLine ("{0}IntPtr {1} = JNIEnv.ToLocalJniHandle (value);", indent, arg);
+ writer.WriteLine ("{0}IntPtr {1} = JNIEnv.ToLocalJniHandle (value);", indent, arg);
}
}
- sw.WriteLine ("{0}try {{", indent);
+ writer.WriteLine ("{0}try {{", indent);
- sw.WriteLine ("{0}\tJNIEnv.Set{1}Field ({2}, {3}, {4});",
+ writer.WriteLine ("{0}\tJNIEnv.Set{1}Field ({2}, {3}, {4});",
indent,
field.IsStatic
? "Static"
: String.Empty,
field.IsStatic
? "class_ref"
- : opt.ContextType.GetObjectHandleProperty ("this"),
+ : type.GetObjectHandleProperty ("this"),
field.ID,
arg);
- sw.WriteLine ("{0}}} finally {{", indent);
+ writer.WriteLine ("{0}}} finally {{", indent);
if (field.Symbol.IsArray) {
- sw.WriteLine ("{0}\tJNIEnv.DeleteLocalRef ({1});", indent, arg);
+ writer.WriteLine ("{0}\tJNIEnv.DeleteLocalRef ({1});", indent, arg);
} else {
foreach (string cleanup in field.SetParameters.GetCallCleanup (opt))
- sw.WriteLine ("{0}\t{1}", indent, cleanup);
+ writer.WriteLine ("{0}\t{1}", indent, cleanup);
if (field.SetParameters.HasCleanup && !have_prep) {
- sw.WriteLine ("{0}\tJNIEnv.DeleteLocalRef ({1});", indent, arg);
+ writer.WriteLine ("{0}\tJNIEnv.DeleteLocalRef ({1});", indent, arg);
}
}
- sw.WriteLine ("{0}}}", indent);
+ writer.WriteLine ("{0}}}", indent);
}
}
}
diff --git a/tools/generator/generator.csproj b/tools/generator/generator.csproj
index 5ab46b18f..cc2eae052 100644
--- a/tools/generator/generator.csproj
+++ b/tools/generator/generator.csproj
@@ -1,4 +1,4 @@
-
+
Debug
@@ -93,6 +93,7 @@
+
@@ -142,4 +143,4 @@
-
+
\ No newline at end of file