void GetAllDerivedInterfaces(List <InterfaceGen> ifaces) { foreach (ISymbol isym in Interfaces) { InterfaceGen iface = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen; if (iface == null) { continue; } bool found = false; foreach (InterfaceGen known in ifaces) { if (known.FullName == iface.FullName) { found = true; } } if (found) { continue; } ifaces.Add(iface); iface.GetAllDerivedInterfaces(ifaces); } }
public bool GetGenericMappings(InterfaceGen gen, Dictionary <string, string> mappings) { foreach (ISymbol sym in Interfaces) { if (sym is GenericSymbol) { GenericSymbol gsym = (GenericSymbol)sym; if (gsym.Gen.FullName == gen.FullName) { for (int i = 0; i < gsym.TypeParams.Length; i++) { mappings [gsym.Gen.TypeParameters [i].Name] = gsym.TypeParams [i].FullName; } return(true); } else if (gsym.Gen.GetGenericMappings(gen, mappings)) { string[] keys = new string [mappings.Keys.Count]; mappings.Keys.CopyTo(keys, 0); foreach (string tp in keys) { mappings [tp] = gsym.TypeParams [Array.IndexOf((from gtp in gsym.Gen.TypeParameters select gtp.Name).ToArray(), mappings [tp])].FullName; } return(true); } } } return(false); }
internal override void WriteInterfaceInvokerHandle(InterfaceGen type, string indent, string declaringType) { WritePeerMembers(indent, type.RawJniName, declaringType, false); writer.WriteLine(); writer.WriteLine("{0}static JniObjectReference java_class_ref => _members.JniPeerType.PeerReference;", indent); writer.WriteLine("{0}public override global::Java.Interop.JniPeerMembers JniPeerMembers => _members;", indent); writer.WriteLine("{0}protected override IntPtr ThresholdClass => class_ref.Handle;", indent); writer.WriteLine("{0}protected override global::System.Type ThresholdType => _members.ManagedPeerType;", indent); writer.WriteLine(); }
internal override void WriteInterfaceInvokerHandle(InterfaceGen type, StreamWriter sw, 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(); }
public static InterfaceGen CreateInterface(XElement pkg, XElement elem, CodeGenerationOptions options) { var iface = new InterfaceGen(CreateGenBaseSupport(pkg, elem, true)) { ArgsType = elem.XGetAttribute("argsType"), HasManagedName = elem.Attribute("managedName") != null, NoAlternatives = elem.XGetAttribute("no-alternatives") == "true", // Only use an explicitly set XML attribute Unnest = elem.XGetAttribute("unnest") == "true" ? true : elem.XGetAttribute("unnest") == "false" ? false : !options.SupportNestedInterfaceTypes }; FillApiSince(iface, pkg, elem); SetLineInfo(iface, elem, options); foreach (var child in elem.Elements()) { switch (child.Name.LocalName) { case "implements": string iname = child.XGetAttribute("name-generic-aware"); iname = iname.Length > 0 ? iname : child.XGetAttribute("name"); iface.AddImplementedInterface(iname); break; case "method": if (child.XGetAttribute("visibility") != "kotlin-internal") { iface.AddMethod(CreateMethod(iface, child, options)); } break; case "field": if (child.XGetAttribute("visibility") != "kotlin-internal") { iface.AddField(CreateField(iface, child, options)); } break; case "typeParameters": break; // handled at GenBaseSupport default: Report.LogCodedWarning(0, Report.WarningUnexpectedInterfaceChild, iface, child.ToString()); break; } } return(iface); }
static void AddNestedInterfaceTypes(GenBase type, List <InterfaceExtensionInfo> nestedInterfaces) { foreach (GenBase nt in type.NestedTypes) { InterfaceGen ni = nt as InterfaceGen; if (ni != null) { nestedInterfaces.Add(new InterfaceExtensionInfo { DeclaringType = type.FullName.Substring(type.Namespace.Length + 1).Replace(".", "_"), Type = ni }); } else { AddNestedInterfaceTypes(nt, nestedInterfaces); } } }
internal override void WriteInterfaceInvokerHandle(InterfaceGen type, string indent, string declaringType) { WritePeerMembers(indent, type.RawJniName, declaringType, false); 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(); }
public static InterfaceGen CreateInterface(TypeDefinition t, CodeGenerationOptions opt) { var iface = new InterfaceGen(CreateGenBaseSupport(t, opt)) { IsShallow = opt.UseShallowReferencedTypes, }; foreach (var ifaceImpl in t.Interfaces) { iface.AddImplementedInterface(ifaceImpl.InterfaceType.FullNameCorrected()); } Action populate = () => { foreach (var m in t.Methods) { if (m.IsPrivate || m.IsAssembly || GetRegisterAttribute(m.CustomAttributes) == null) { continue; } iface.AddMethod(CreateMethod(iface, m)); } }; if (iface.IsShallow) { iface.PopulateAction = populate; } else { populate(); } iface.MayHaveManagedGenericArguments = !iface.IsAcw; return(iface); }
public static InterfaceGen CreateInterface(XElement pkg, XElement elem) { var iface = new InterfaceGen(CreateGenBaseSupport(pkg, elem, true)) { ArgsType = elem.XGetAttribute("argsType"), HasManagedName = elem.Attribute("managedName") != null }; foreach (var child in elem.Elements()) { switch (child.Name.LocalName) { case "implements": string iname = child.XGetAttribute("name-generic-aware"); iname = iname.Length > 0 ? iname : child.XGetAttribute("name"); iface.AddImplementedInterface(iname); break; case "method": iface.AddMethod(CreateMethod(iface, child)); break; case "field": iface.AddField(CreateField(child)); break; case "typeParameters": break; // handled at GenBaseSupport default: Report.Warning(0, Report.WarningInterfaceGen + 0, "unexpected interface child {0}.", child); break; } } return(iface); }
void GenerateDeclaration(StreamWriter sw, string indent, CodeGenerationOptions opt) { StringBuilder sb = new StringBuilder(); foreach (ISymbol isym in Interfaces) { InterfaceGen igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen; if (igen.IsConstSugar) { continue; } if (sb.Length > 0) { sb.Append(", "); } sb.Append(opt.GetOutputName(isym.FullName)); } sw.WriteLine("{0}// Metadata.xml XPath interface reference: path=\"{1}\"", indent, MetadataXPathReference); if (this.IsDeprecated) { sw.WriteLine("{0}[ObsoleteAttribute (@\"{1}\")]", indent, DeprecatedComment); } sw.WriteLine("{0}[Register (\"{1}\", \"\", \"{2}\"{3})]", indent, RawJniName, Namespace + "." + FullName.Substring(Namespace.Length + 1).Replace('.', '/') + "Invoker", this.AdditionalAttributeString()); if (this.TypeParameters != null && this.TypeParameters.Any()) { sw.WriteLine("{0}{1}", indent, TypeParameters.ToGeneratedAttributeString()); } sw.WriteLine("{0}{1} partial interface {2} : {3} {{", indent, Visibility, Name, Interfaces.Count == 0 || sb.Length == 0 ? "IJavaObject" : sb.ToString()); sw.WriteLine(); GenProperties(sw, indent + "\t", opt); GenMethods(sw, indent + "\t", opt); sw.WriteLine(indent + "}"); sw.WriteLine(); }
public Property GetPropertyByName(string name, bool check_ifaces, bool check_base_ifaces) { if (prop_hash.ContainsKey(name)) { return(prop_hash [name]); } if (check_ifaces) { foreach (ISymbol isym in Interfaces) { InterfaceGen igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen; if (igen == null) { continue; } var ret = igen.GetPropertyByName(name, true); if (ret != null) { return(ret); } } } return(BaseSymbol != null?BaseSymbol.GetPropertyByName(name, check_base_ifaces, check_base_ifaces) : null); }
public bool ContainsMethod(Method method, bool check_ifaces, bool check_base_ifaces) { // background: bug #10123. // Visibility check was introduced - and required so far - to block "public overrides protected" methods // (which is allowed in Java but not in C#). // The problem is, it does not *always* result in error and generates callable code, and we depend on // that fact in several classes that implements some interface that requires "public Object clone()". // // This visibility inconsistency results in 1) error for abstract methods and 2) warning for virtual methods. // Hence, for abstract methods we dare to ignore visibility difference and treat it as override, // *then* C# compiler will report this inconsistency as error that users need to fix manually, but // with obvious message saying "it is because of visibility consistency", // not "abstract member not implemented" (it is *implemented* in different visibility and brings confusion). // For virtual methods, just check the visibility difference and treat as different method. // Regardless of whether it is actually an override or not, we just invoke Java method. if (jni_sig_hash.ContainsKey(method.JavaName + method.JniSignature)) { var bm = jni_sig_hash [method.JavaName + method.JniSignature]; if (bm.Visibility == method.Visibility || bm.IsAbstract) { return(true); } } if (check_ifaces) { foreach (ISymbol isym in Interfaces) { InterfaceGen igen = (isym is GenericSymbol ? (isym as GenericSymbol).Gen : isym) as InterfaceGen; if (igen != null && igen.ContainsMethod(method, true)) { return(true); } } } return(BaseSymbol != null && BaseSymbol.ContainsMethod(method, check_base_ifaces, check_base_ifaces)); }
internal override void WriteInterfaceInvokerHandle(InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType) { writer.WriteLine("{0}internal new static readonly JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));", indent, type.RawJniName, declaringType); 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(); }
void GenerateInvoker(StreamWriter sw, IEnumerable <Method> methods, string indent, CodeGenerationOptions opt, HashSet <string> members, InterfaceGen gen) { foreach (Method m in methods) { string sig = m.GetSignature(); if (members.Contains(sig)) { continue; } members.Add(sig); if (!m.IsAbstract) { continue; } if (IsExplicitlyImplementedMethod(sig)) { // sw.WriteLine ("// This invoker explicitly implements this method"); m.GenerateExplicitInterfaceInvoker(sw, indent, opt, gen); } else { // sw.WriteLine ("// This invoker overrides {0} method", gen.FullName); m.IsOverride = true; m.Generate(sw, indent, opt, this, false); m.IsOverride = false; } } }
internal override void WriteClassHandle(InterfaceGen type, string indent, string declaringType) { WritePeerMembers(indent, type.RawJniName, declaringType, type.Name == declaringType); }
public override void Generate(StreamWriter sw, string indent, CodeGenerationOptions opt, GenerationInfo gen_info) { opt.ContextTypes.Push(this); gen_info.TypeRegistrations.Add(new KeyValuePair <string, string>(RawJniName, AssemblyQualifiedName)); bool is_enum = base_symbol != null && base_symbol.FullName == "Java.Lang.Enum"; if (is_enum) { gen_info.Enums.Add(RawJniName.Replace('/', '.') + ":" + Namespace + ":" + JavaSimpleName); } StringBuilder sb = new StringBuilder(); foreach (ISymbol isym in Interfaces) { GenericSymbol gs = isym as GenericSymbol; InterfaceGen gen = (gs == null ? isym : gs.Gen) as InterfaceGen; if (gen != null && gen.IsConstSugar) { continue; } if (sb.Length > 0) { sb.Append(", "); } sb.Append(opt.GetOutputName(isym.FullName)); } string obj_type = null; if (base_symbol != null) { GenericSymbol gs = base_symbol as GenericSymbol; obj_type = gs != null && gs.IsConcrete ? gs.GetGenericType(null) : opt.GetOutputName(base_symbol.FullName); } sw.WriteLine("{0}// Metadata.xml XPath class reference: path=\"{1}\"", indent, MetadataXPathReference); if (this.IsDeprecated) { sw.WriteLine("{0}[ObsoleteAttribute (@\"{1}\")]", indent, this.DeprecatedComment); } sw.WriteLine("{0}[global::Android.Runtime.Register (\"{1}\", DoNotGenerateAcw=true{2})]", indent, RawJniName, this.AdditionalAttributeString()); if (this.TypeParameters != null && this.TypeParameters.Any()) { sw.WriteLine("{0}{1}", indent, TypeParameters.ToGeneratedAttributeString()); } string inherits = ""; if (inherits_object && obj_type != null) { inherits = ": " + obj_type; } if (sb.Length > 0) { if (string.IsNullOrEmpty(inherits)) { inherits = ": "; } else { inherits += ", "; } } sw.WriteLine("{0}{1} {2}{3}{4}partial class {5} {6}{7} {{", indent, Visibility, needs_new ? "new " : String.Empty, IsAbstract ? "abstract " : String.Empty, IsFinal ? "sealed " : String.Empty, Name, inherits, sb.ToString()); sw.WriteLine(); var seen = new HashSet <string> (); GenFields(sw, indent + "\t", opt, seen); bool haveNested = false; foreach (var iface in GetAllImplementedInterfaces() .Except(BaseGen == null ? new InterfaceGen[0] : BaseGen.GetAllImplementedInterfaces()) .Where(i => i.Fields.Count > 0)) { if (!haveNested) { sw.WriteLine(); sw.WriteLine("{0}\tpublic static class InterfaceConsts {{", indent); haveNested = true; } sw.WriteLine(); sw.WriteLine("{0}\t\t// The following are fields from: {1}", indent, iface.JavaName); iface.GenFields(sw, indent + "\t\t", opt, seen); } if (haveNested) { sw.WriteLine("{0}\t}}\n", indent); } foreach (GenBase nest in NestedTypes) { if (BaseGen != null && BaseGen.ContainsNestedType(nest)) { if (nest is ClassGen) { (nest as ClassGen).needs_new = true; } } nest.Generate(sw, indent + "\t", opt, gen_info); sw.WriteLine(); } if (HasClassHandle) { bool requireNew = false; for (var bg = BaseGen; bg != null && bg is XmlClassGen; bg = bg.BaseGen) { if (bg.HasClassHandle) { requireNew = true; break; } } opt.CodeGenerator.WriteClassHandle(this, sw, indent, opt, requireNew); } GenConstructors(sw, indent + "\t", opt); GenProperties(sw, indent + "\t", opt); GenMethods(sw, indent + "\t", opt); if (IsAbstract) { GenerateAbstractMembers(sw, indent + "\t", opt); } bool is_char_seq = false; foreach (ISymbol isym in Interfaces) { if (isym is GenericSymbol) { GenericSymbol gs = isym as GenericSymbol; if (gs.IsConcrete) { // FIXME: not sure if excluding default methods is a valid idea... foreach (Method m in gs.Gen.Methods.Where(m => !m.IsInterfaceDefaultMethod && !m.IsStatic)) { if (m.IsGeneric) { m.GenerateExplicitIface(sw, indent + "\t", opt, gs); } } } } else if (isym.FullName == "Java.Lang.ICharSequence") { is_char_seq = true; } } if (is_char_seq) { GenCharSequenceEnumerator(sw, indent + "\t", opt); } sw.WriteLine(indent + "}"); if (!AssemblyQualifiedName.Contains('/')) { foreach (InterfaceExtensionInfo nestedIface in GetNestedInterfaceTypes()) { nestedIface.Type.GenerateExtensionsDeclaration(sw, indent, opt, nestedIface.DeclaringType); } } if (IsAbstract) { sw.WriteLine(); GenerateInvoker(sw, indent, opt); } opt.ContextTypes.Pop(); }
internal abstract void WriteInterfaceInvokerHandle(InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType);
internal override void WriteClassHandle(InterfaceGen type, TextWriter writer, string indent, CodeGenerationOptions opt, string declaringType) { writer.WriteLine("{0}new static JniPeerMembers _members = new JniPeerMembers (\"{1}\", typeof ({2}));", indent, type.RawJniName, declaringType); }
internal override void WriteClassHandle(InterfaceGen type, StreamWriter sw, string indent, CodeGenerationOptions opt, string declaringType) { sw.WriteLine("{0}static IntPtr class_ref = JNIEnv.FindClass (\"{1}\");", indent, type.RawJniName); }
public void GenerateAbstractDeclaration(StreamWriter sw, string indent, CodeGenerationOptions opt, InterfaceGen gen, GenBase impl) { if (RetVal.IsGeneric && gen != null) { GenerateCustomAttributes(sw, indent); sw.WriteLine("{0}{1} {2}.{3} ({4})", indent, opt.GetOutputName(RetVal.FullName), opt.GetOutputName(gen.FullName), Name, GenBase.GetSignature(this, opt)); sw.WriteLine("{0}{{", indent); sw.WriteLine("{0}\tthrow new NotImplementedException ();", indent); sw.WriteLine("{0}}}", indent); sw.WriteLine(); } else { bool gen_as_formatted = IsReturnCharSequence; string name = AdjustedName; GenerateCallback(sw, indent, opt, impl, null, gen_as_formatted); sw.WriteLine("{0}// Metadata.xml XPath method reference: path=\"{1}\"", indent, GetMetadataXPathReference(this.DeclaringType)); sw.WriteLine("{0}[Register (\"{1}\", \"{2}\", \"{3}\"{4})]", indent, JavaName, JniSignature, ConnectorName, this.AdditionalAttributeString()); GenerateCustomAttributes(sw, indent); sw.WriteLine("{0}{1} abstract {2} {3} ({4});", indent, Visibility, opt.GetOutputName(RetVal.FullName), name, GenBase.GetSignature(this, opt)); sw.WriteLine(); if (gen_as_formatted || Parameters.HasCharSequence) { GenerateStringOverload(sw, indent, opt); } } GenerateAsyncWrapper(sw, indent, opt); }
internal override void WriteClassHandle(InterfaceGen type, string indent, string declaringType) { writer.WriteLine("{0}new static IntPtr class_ref = JNIEnv.FindClass (\"{1}\");", indent, type.RawJniName); }