public void GenerateAbstractDeclaration(StreamWriter sw, string indent, CodeGenerationOptions opt, GenBase gen) { bool overrides = false; var baseProp = gen.BaseSymbol != null?gen.BaseSymbol.GetPropertyByName(name, true) : null; if (baseProp != null) { if (baseProp.Type != Getter.Return) { // This may not be required if we can change generic parameter support to return constrained type (not just J.L.Object). sw.WriteLine("{0}// skipped generating property {1} because its Java method declaration is variant that we cannot represent in C#", indent, name); return; } overrides = true; } string abstract_name = AdjustedName; string visibility = Getter.RetVal.IsGeneric ? "protected" : Getter.Visibility; if (!overrides) { GenerateCallbacks(sw, indent, opt, gen, abstract_name); } sw.WriteLine("{0}{1} abstract{2} {3} {4} {{", indent, visibility, overrides ? " override" : "", opt.GetOutputName(Getter.ReturnType), abstract_name); sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.MetadataXPathReference, Getter.JavaName, Getter.Parameters.GetMethodXPathPredicate()); if (Getter.IsReturnEnumified) { sw.WriteLine("{0}[return:global::Android.Runtime.GeneratedEnum]", indent); } Getter.GenerateCustomAttributes(sw, indent); sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}\"{4})] get;", indent, Getter.JavaName, Getter.JniSignature, Getter.ConnectorName, Getter.AdditionalAttributeString()); if (Setter != null) { sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.MetadataXPathReference, Setter.JavaName, Setter.Parameters.GetMethodXPathPredicate()); Setter.GenerateCustomAttributes(sw, indent); sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}\"{4})] set;", indent, Setter.JavaName, Setter.JniSignature, Setter.ConnectorName, Setter.AdditionalAttributeString()); } sw.WriteLine("{0}}}", indent); sw.WriteLine(); if (Type.StartsWith("Java.Lang.ICharSequence")) { GenerateStringVariant(sw, indent); } }
public void GenerateDeclaration(StreamWriter sw, string indent, CodeGenerationOptions opt, GenBase gen, string adapter) { sw.WriteLine("{0}{1} {2} {{", indent, opt.GetOutputName(Type), AdjustedName); if (Getter != null) { sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.MetadataXPathReference, Getter.JavaName, Getter.Parameters.GetMethodXPathPredicate()); if (Getter.GenericArguments != null && Getter.GenericArguments.Any()) { sw.WriteLine("{0}{1}", indent, Getter.GenericArguments.ToGeneratedAttributeString()); } sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}:{4}\"{5})] get;", indent, Getter.JavaName, Getter.JniSignature, Getter.ConnectorName, Getter.GetAdapterName(opt, adapter), Getter.AdditionalAttributeString()); } if (Setter != null) { sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.MetadataXPathReference, Setter.JavaName, Setter.Parameters.GetMethodXPathPredicate()); if (Setter.GenericArguments != null && Setter.GenericArguments.Any()) { sw.WriteLine("{0}{1}", indent, Setter.GenericArguments.ToGeneratedAttributeString()); } sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}:{4}\"{5})] set;", indent, Setter.JavaName, Setter.JniSignature, Setter.ConnectorName, Setter.GetAdapterName(opt, adapter), Setter.AdditionalAttributeString()); } sw.WriteLine("{0}}}", indent); sw.WriteLine(); }
public void Generate(GenBase gen, StreamWriter sw, string indent, CodeGenerationOptions opt, bool with_callbacks, bool force_override) { // <TechnicalDebt> // This is a special workaround for AdapterView inheritance. // (How it is special? They have hand-written bindings AND brings generic // version of AdapterView<T> in the inheritance, also added by metadata!) // // They are on top of fragile hand-bound code, and when we are making changes // in generator, they bite. Since we are not going to bring API breakage // right now, we need special workarounds to get things working. // // So far, what we need here is to have AbsSpinner.Adapter compile. // // > platforms/*/src/generated/Android.Widget.AbsSpinner.cs(156,56): error CS0533: // > `Android.Widget.AbsSpinner.Adapter' hides inherited abstract member // > `Android.Widget.AdapterView<Android.Widget.ISpinnerAdapter>.Adapter // // It is because the AdapterView<T>.Adapter is hand-bound and cannot be // detected by generator! // // So, we explicitly treat it as a special-case. // // Then, Spinner, ListView and GridView instantiate them, so they are also special cases. // </TechnicalDebt> if (Name == "Adapter" && (Getter.DeclaringType.BaseGen.FullName == "Android.Widget.AdapterView" || Getter.DeclaringType.BaseGen.BaseGen != null && Getter.DeclaringType.BaseGen.BaseGen.FullName == "Android.Widget.AdapterView")) { force_override = true; } // ... and the above breaks generator tests... if (Name == "Adapter" && (Getter.DeclaringType.BaseGen.FullName == "Xamarin.Test.AdapterView" || Getter.DeclaringType.BaseGen.BaseGen != null && Getter.DeclaringType.BaseGen.BaseGen.FullName == "Xamarin.Test.AdapterView")) { force_override = true; } string decl_name = AdjustedName; string virtual_override = String.Empty; bool is_virtual = Getter.IsVirtual && (Setter == null || Setter.IsVirtual); if (with_callbacks && is_virtual) { virtual_override = " virtual"; Getter.GenerateCallback(sw, indent, opt, gen, AdjustedName); } if (with_callbacks && is_virtual && Setter != null) { virtual_override = " virtual"; Setter.GenerateCallback(sw, indent, opt, gen, AdjustedName); } virtual_override = force_override ? " override" : virtual_override; if ((Getter ?? Setter).IsStatic) { virtual_override = " static"; } // It should be using AdjustedName instead of Name, but ICharSequence ("Formatted") properties are not caught by this... else if (gen.BaseSymbol != null && gen.BaseSymbol.GetPropertyByName(Name, true) != null) { virtual_override = " override"; } Getter.GenerateIdField(sw, indent, opt); if (Setter != null) { Setter.GenerateIdField(sw, indent, opt); } string visibility = Getter.IsAbstract && Getter.RetVal.IsGeneric ? "protected" : (Setter ?? Getter).Visibility; // Unlike [Register], mcs does not allow applying [Obsolete] on property accessors, so we can apply them only under limited condition... if (Getter.Deprecated != null && (Setter == null || Setter.Deprecated != null)) { sw.WriteLine("{0}[Obsolete (@\"{1}\")]", indent, Getter.Deprecated.Replace("\"", "\"\"").Trim() + (Setter != null && Setter.Deprecated != Getter.Deprecated ? " " + Setter.Deprecated.Replace("\"", "\"\"").Trim() : null)); } Getter.GenerateCustomAttributes(sw, indent); sw.WriteLine("{0}{1}{2} unsafe {3} {4} {{", indent, visibility, virtual_override, opt.GetOutputName(Getter.ReturnType), decl_name); sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.MetadataXPathReference, Getter.JavaName, Getter.Parameters.GetMethodXPathPredicate()); sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}\"{4})]", indent, Getter.JavaName, Getter.JniSignature, Getter.ConnectorName, Getter.AdditionalAttributeString()); sw.WriteLine("{0}\tget {{", indent); Getter.GenerateBody(sw, indent + "\t\t", opt); sw.WriteLine("{0}\t}}", indent); if (Setter != null) { sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.MetadataXPathReference, Setter.JavaName, Setter.Parameters.GetMethodXPathPredicate()); Setter.GenerateCustomAttributes(sw, indent); sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}\"{4})]", indent, Setter.JavaName, Setter.JniSignature, Setter.ConnectorName, Setter.AdditionalAttributeString()); sw.WriteLine("{0}\tset {{", indent); string pname = Setter.Parameters [0].Name; Setter.Parameters [0].Name = "value"; Setter.GenerateBody(sw, indent + "\t\t", opt); Setter.Parameters [0].Name = pname; sw.WriteLine("{0}\t}}", indent); } else if (GenerateDispatchingSetter) { sw.WriteLine("{0}// This is a dispatching setter", indent + "\t"); sw.WriteLine("{0}set {{ Set{1} (value); }}", indent + "\t", Name); } sw.WriteLine("{0}}}", indent); sw.WriteLine(); if (Type.StartsWith("Java.Lang.ICharSequence") && virtual_override != " override") { GenerateStringVariant(sw, indent); } }
public void GenerateExplicitIface(StreamWriter sw, string indent, CodeGenerationOptions opt, GenericSymbol gen, string adapter) { Dictionary <string, string> mappings = new Dictionary <string, string> (); for (int i = 0; i < gen.TypeParams.Length; i++) { mappings [gen.Gen.TypeParameters [i].Name] = gen.TypeParams [i].FullName; } //If the property type is Java.Lang.Object, we don't need to generate an explicit implementation if (Getter?.RetVal.GetGenericType(mappings) == "Java.Lang.Object") { return; } if (Setter?.Parameters[0].GetGenericType(mappings) == "Java.Lang.Object") { return; } sw.WriteLine("{0}// This method is explicitly implemented as a member of an instantiated {1}", indent, gen.FullName); sw.WriteLine("{0}{1} {2}.{3} {{", indent, opt.GetOutputName(Type), opt.GetOutputName(gen.Gen.FullName), AdjustedName); if (Getter != null) { if (gen.Gen.IsGeneratable) { sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.Gen.MetadataXPathReference, Getter.JavaName, Getter.Parameters.GetMethodXPathPredicate()); } if (Getter.GenericArguments != null && Getter.GenericArguments.Any()) { sw.WriteLine("{0}{1}", indent, Getter.GenericArguments.ToGeneratedAttributeString()); } sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}:{4}\"{5})] get {{", indent, Getter.JavaName, Getter.JniSignature, Getter.ConnectorName, Getter.GetAdapterName(opt, adapter), Getter.AdditionalAttributeString()); sw.WriteLine("{0}\t\treturn {1};", indent, Name); sw.WriteLine("{0}\t}}", indent); } if (Setter != null) { if (gen.Gen.IsGeneratable) { sw.WriteLine("{0}\t// Metadata.xml XPath method reference: path=\"{1}/method[@name='{2}'{3}]\"", indent, gen.Gen.MetadataXPathReference, Setter.JavaName, Setter.Parameters.GetMethodXPathPredicate()); } if (Setter.GenericArguments != null && Setter.GenericArguments.Any()) { sw.WriteLine("{0}{1}", indent, Setter.GenericArguments.ToGeneratedAttributeString()); } sw.WriteLine("{0}\t[Register (\"{1}\", \"{2}\", \"{3}:{4}\"{5})] set {{", indent, Setter.JavaName, Setter.JniSignature, Setter.ConnectorName, Setter.GetAdapterName(opt, adapter), Setter.AdditionalAttributeString()); sw.WriteLine("{0}\t\t{1} = {2};", indent, Name, Setter.Parameters.GetGenericCall(opt, mappings)); sw.WriteLine("{0}\t}}", indent); } sw.WriteLine("{0}}}", indent); sw.WriteLine(); }