Example #1
0
 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);
 }
Example #2
0
 static bool Equals(GenericSymbol g1, GenericSymbol g2)
 {
     if (g1.IsConcrete != g2.IsConcrete)
     {
         return(false);
     }
     if (g1.FullName != g2.FullName)
     {
         return(false);
     }
     return(true);
 }
        public ISymbol Lookup(string java_type)
        {
            string         type_params;
            int            ar;
            bool           he;
            string         key = GetSymbolInfo(java_type, out type_params, out ar, out he);
            ISymbol        sym;
            List <ISymbol> values;

            if (symbols.TryGetValue(key, out values))
            {
                sym = values [values.Count - 1];
            }
            else
            {
                sym = AllRegisteredSymbols().FirstOrDefault(v => v.FullName == key);
            }
            ISymbol result;

            if (sym != null)
            {
                if (type_params.Length > 0)
                {
                    GenBase gen = sym as GenBase;
                    if (gen != null && gen.IsGeneric)
                    {
                        result = new GenericSymbol(gen, type_params);
                    }
                    // In other case, it is still valid to derive from non-generic type.
                    // Generics are likely removed but we should not invalidate such derived classes.
                    else
                    {
                        result = gen;
                    }
                }
                // disable this condition; consider that "java.lang.Class[]" can be specified as a parameter type
                //else if (sym is GenBase && (sym as GenBase).IsGeneric)
                //	return null;
                else
                {
                    result = sym;
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
Example #4
0
        public static ISymbol Lookup(string java_type)
        {
            string  type_params;
            int     ar;
            bool    he;
            string  key = GetSymbolInfo(java_type, out type_params, out ar, out he);
            ISymbol result;
            ISymbol sym = symbols.ContainsKey(key) ? symbols [key] : symbols.FirstOrDefault(s => s.Value.FullName == key).Value;

            if (sym != null)
            {
                if (type_params.Length > 0)
                {
                    GenBase gen = sym as GenBase;
                    if (gen != null && gen.IsGeneric)
                    {
                        result = new GenericSymbol(gen, type_params);
                    }
                    // In other case, it is still valid to derive from non-generic type.
                    // Generics are likely removed but we should not invalidate such derived classes.
                    else
                    {
                        result = gen;
                    }
                }
                // disable this condition; consider that "java.lang.Class[]" can be specified as a parameter type
                //else if (sym is GenBase && (sym as GenBase).IsGeneric)
                //	return null;
                else
                {
                    result = sym;
                }
            }
            else
            {
                return(null);
            }

            return(result);
        }
Example #5
0
        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();
        }
Example #6
0
        public override void FixupExplicitImplementation()
        {
            if (fill_explicit_implementation_started)
            {
                return;                 // already done.
            }
            fill_explicit_implementation_started = true;
            if (BaseGen != null && BaseGen.explicitly_implemented_iface_methods == null)
            {
                BaseGen.FixupExplicitImplementation();
            }

            foreach (InterfaceGen iface in GetAllDerivedInterfaces())
            {
                if (iface.IsGeneric)
                {
                    bool skip = false;
                    foreach (ISymbol isym in Interfaces)
                    {
                        var gs = isym as GenericSymbol;
                        if (gs != null && gs.IsConcrete && gs.Gen == iface)
                        {
                            skip = true;
                        }
                    }
                    if (skip)
                    {
                        continue;                         // we don't handle it here; generic interface methods are generated in different manner.
                    }
                }
                if (BaseGen != null && BaseGen.GetAllDerivedInterfaces().Contains(iface))
                {
                    continue;                     // no need to fill members for already-implemented-in-base-class iface.
                }
                foreach (var m in iface.Methods.Where(m => !ContainsMethod(m, false, false)))
                {
                    string sig          = m.GetSignature();
                    bool   doExplicitly = false;
                    if (IsCovariantMethod(m))
                    {
                        doExplicitly = true;
                    }
                    else if (m.IsGeneric)
                    {
                        doExplicitly = true;
                    }
                    if (doExplicitly)
                    {
                        explicitly_implemented_iface_methods.Add(sig);
                    }
                }
            }

            // Keep in sync with Generate() that generates explicit iface method impl.
            foreach (ISymbol isym in Interfaces)
            {
                if (isym is GenericSymbol)
                {
                    GenericSymbol gs = isym as GenericSymbol;
                    if (gs.IsConcrete)
                    {
                        foreach (Method m in gs.Gen.Methods)
                        {
                            if (m.IsGeneric)
                            {
                                explicitly_implemented_iface_methods.Add(m.GetSignature());
                            }
                        }
                    }
                }
            }

            foreach (var nt in NestedTypes)
            {
                nt.FixupExplicitImplementation();
            }
        }
Example #7
0
        // This is supposed to generate instantiated generic method output, but I don't think it is done yet.
        public void GenerateExplicitIface(StreamWriter sw, string indent, CodeGenerationOptions opt, GenericSymbol gen)
        {
            sw.WriteLine("{0}// This method is explicitly implemented as a member of an instantiated {1}", indent, gen.FullName);
            GenerateCustomAttributes(sw, indent);
            sw.WriteLine("{0}{1} {2}.{3} ({4})", indent, opt.GetOutputName(RetVal.FullName), opt.GetOutputName(gen.Gen.FullName), Name, GenBase.GetSignature(this, opt));
            sw.WriteLine("{0}{{", indent);
            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;
            }
            GenerateGenericBody(sw, indent + "\t", opt, null, String.Empty, mappings);
            sw.WriteLine("{0}}}", indent);
            sw.WriteLine();
        }
Example #8
0
        public ISymbol Lookup(string java_type)
        {
            string         type_params;
            int            ar;
            bool           he;
            string         key = GetSymbolInfo(java_type, out type_params, out ar, out he);
            ISymbol        sym;
            List <ISymbol> values;

            if (symbols.TryGetValue(key, out values))
            {
                sym = values [values.Count - 1];
            }
            else
            {
                // Note we're potentially searching shallow types, but this is only looking at the type name
                // Anything we find we will populate before returning to the user

                lock (cache_population_lock) {
                    if (all_symbols_cache == null)
                    {
                        all_symbols_cache = new ConcurrentDictionary <string, ISymbol> (symbols.Values.SelectMany(v => v).GroupBy(s => s.FullName).ToDictionary(s => s.Key, s => s.FirstOrDefault()));
                    }

                    if (!all_symbols_cache.TryGetValue(key, out sym))
                    {
                        // We may be looking for a type like:
                        // - System.Collections.Generic.IList<Java.Util.Locale.LanguageRange>
                        // Our key is "System.Collections.Generic.IList", but it's stored in
                        // the symbol table with the arity so we need to look for
                        // "System.Collections.Generic.IList`1" to find a match
                        key = AddArity(key, type_params);
                        all_symbols_cache.TryGetValue(key, out sym);
                    }
                }
            }
            ISymbol result;

            if (sym != null)
            {
                if (type_params.Length > 0)
                {
                    GenBase gen = sym as GenBase;

                    EnsurePopulated(gen);

                    if (gen != null && gen.IsGeneric)
                    {
                        result = new GenericSymbol(gen, type_params);
                    }
                    // In other case, it is still valid to derive from non-generic type.
                    // Generics are likely removed but we should not invalidate such derived classes.
                    else
                    {
                        result = gen;
                    }
                }
                // disable this condition; consider that "java.lang.Class[]" can be specified as a parameter type
                //else if (sym is GenBase && (sym as GenBase).IsGeneric)
                //	return null;
                else
                {
                    result = sym;
                }
            }
            else
            {
                return(null);
            }

            if (result is GenBase gen_base)
            {
                EnsurePopulated(gen_base);
            }

            return(result);
        }
Example #9
0
        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();
        }