public string AutoDetectEnumifiedOverrideReturn(AncestorDescendantCache cache) { if (RetVal.FullName != "int") { return(null); } var classes = cache.GetAncestorsAndDescendants(DeclaringType); classes = classes.Concat(classes.SelectMany(x => x.GetAllImplementedInterfaces())); foreach (var t in classes) { foreach (var candidate in t.GetAllMethods().Where(m => m.Name == Name && m.Parameters.Count == Parameters.Count)) { if (JniSignature != candidate.JniSignature) { continue; } if (candidate.IsReturnEnumified) { RetVal.SetGeneratedEnumType(candidate.RetVal.FullName); } } } return(null); }
public void AutoDetectEnumifiedOverrideProperties(AncestorDescendantCache cache) { if (Type != "int") { return; } var classes = cache.GetAncestorsAndDescendants(Getter.DeclaringType); classes = classes.Concat(classes.SelectMany(x => x.GetAllImplementedInterfaces())); foreach (var t in classes) { foreach (var candidate in t.Properties.Where(p => p.Name == Name)) { if (Getter.JniSignature != candidate.Getter.JniSignature) { continue; } if (candidate.Getter.IsReturnEnumified) { Getter.RetVal.SetGeneratedEnumType(candidate.Getter.RetVal.FullName); } } } }
public string [] AutoDetectEnumifiedOverrideParameters(AncestorDescendantCache cache) { if (Parameters.All(p => p.Type != "int")) { return(null); } var classes = cache.GetAncestorsAndDescendants(DeclaringType); classes = classes.Concat(classes.SelectMany(x => x.GetAllImplementedInterfaces())); foreach (var t in classes) { foreach (var candidate in t.GetAllMethods().Where(m => m.Name == Name && m.Parameters.Count == Parameters.Count && m.Parameters.Any(p => p.IsEnumified))) { var ret = new string [Parameters.Count]; bool mismatch = false; for (int i = 0; i < Parameters.Count; i++) { if (Parameters [i].Type == "int" && candidate.Parameters [i].IsEnumified) { ret [i] = candidate.Parameters [i].Type; } else if (Parameters [i].Type != candidate.Parameters [i].Type) { mismatch = true; break; } } if (mismatch) { continue; } for (int i = 0; i < ret.Length; i++) { if (ret [i] != null) { Parameters [i].SetGeneratedEnumType(ret [i]); } } return(ret); } } return(null); }
static void Run(CodeGeneratorOptions options, DirectoryAssemblyResolver resolver) { string assemblyQN = options.AssemblyQualifiedName; string api_level = options.ApiLevel; int product_version = options.ProductVersion; bool preserve_enums = options.PreserveEnums; string csdir = options.ManagedCallableWrapperSourceOutputDirectory ?? "cs"; string javadir = "java"; string enumdir = options.EnumOutputDirectory ?? "enum"; string enum_metadata = options.EnumMetadataOutputFile ?? "enummetadata"; var references = options.AssemblyReferences; string enum_fields_map = options.EnumFieldsMapFile; string enum_flags = options.EnumFlagsFile; string enum_methods_map = options.EnumMethodsMapFile; var fixups = options.FixupFiles; var annotations_zips = options.AnnotationsZipFiles; string filename = options.ApiDescriptionFile; string mapping_file = options.MappingReportFile; bool only_xml_adjuster = options.OnlyRunApiXmlAdjuster; string api_xml_adjuster_output = options.ApiXmlAdjusterOutput; var apiSource = ""; var opt = new CodeGenerationOptions() { CodeGenerationTarget = options.CodeGenerationTarget, UseGlobal = options.GlobalTypeNames, IgnoreNonPublicType = true, UseShortFileNames = options.UseShortFileNames, ProductVersion = options.ProductVersion, SupportInterfaceConstants = options.SupportInterfaceConstants, SupportDefaultInterfaceMethods = options.SupportDefaultInterfaceMethods, SupportNestedInterfaceTypes = options.SupportNestedInterfaceTypes, SupportNullableReferenceTypes = options.SupportNullableReferenceTypes, }; var resolverCache = new TypeDefinitionCache(); // Load reference libraries foreach (var lib in options.LibraryPaths) { resolver.SearchDirectories.Add(lib); } foreach (var reference in references) { resolver.SearchDirectories.Add(Path.GetDirectoryName(reference)); } // Figure out if this is class-parse string apiXmlFile = filename; string apiSourceAttr = null; using (var xr = XmlReader.Create(filename)) { xr.MoveToContent(); apiSourceAttr = xr.GetAttribute("api-source"); } // We don't use shallow referenced types with class-parse because the Adjuster process // enumerates every ctor/method/property/field to build its model, so we will need // every type to be fully populated. opt.UseShallowReferencedTypes = apiSourceAttr != "class-parse"; foreach (var reference in references.Distinct()) { try { Report.Verbose(0, "resolving assembly {0}.", reference); var assembly = resolver.Load(reference); foreach (var md in assembly.Modules) { foreach (var td in md.Types) { // FIXME: at some stage we want to import generic types. // For now generator fails to load generic types that have conflicting type e.g. // AdapterView`1 and AdapterView cannot co-exist. // It is mostly because generator primarily targets jar (no real generics land). var nonGenericOverload = td.HasGenericParameters ? md.GetType(td.FullName.Substring(0, td.FullName.IndexOf('`'))) : null; if (BindSameType(td, nonGenericOverload, resolverCache)) { continue; } ProcessReferencedType(td, opt); } } } catch (Exception ex) { Report.Warning(0, Report.WarningCodeGenerator + 0, ex, "failed to parse assembly {0}: {1}", reference, ex.Message); } } // For class-parse API description, transform it to jar2xml style. if (apiSourceAttr == "class-parse") { apiXmlFile = api_xml_adjuster_output ?? Path.Combine(Path.GetDirectoryName(filename), Path.GetFileName(filename) + ".adjusted"); new Adjuster().Process(filename, opt, opt.SymbolTable.AllRegisteredSymbols(opt).OfType <GenBase> ().ToArray(), apiXmlFile, Report.Verbosity ?? 0); } if (only_xml_adjuster) { return; } // load XML API definition with fixups. Dictionary <string, EnumMappings.EnumDescription> enums = null; EnumMappings enummap = null; if (enum_fields_map != null || enum_methods_map != null) { enummap = new EnumMappings(enumdir, enum_metadata, api_level, preserve_enums); enums = enummap.Process(enum_fields_map, enum_flags, enum_methods_map); fixups.Add(enum_metadata); } Parser p = new Parser(opt); List <GenBase> gens = p.Parse(apiXmlFile, fixups, api_level, product_version); if (gens == null) { return; } apiSource = p.ApiSource; // disable interface default methods here, especially before validation. gens = gens.Where(g => !g.IsObfuscated && g.Visibility != "private").ToList(); foreach (var gen in gens) { gen.StripNonBindables(opt); if (gen.IsGeneratable) { AddTypeToTable(opt, gen); } } // Apply fixups KotlinFixups.Fixup(gens); Validate(gens, opt, new CodeGeneratorContext()); foreach (var api_versions_xml in options.ApiVersionsXmlFiles) { ApiVersionsSupport.AssignApiLevels(gens, api_versions_xml); } foreach (GenBase gen in gens) { gen.FillProperties(); } var cache = new AncestorDescendantCache(gens); foreach (var gen in gens) { gen.UpdateEnums(opt, cache); } foreach (GenBase gen in gens) { gen.FixupMethodOverrides(opt); } foreach (GenBase gen in gens) { gen.FixupExplicitImplementation(); } SealedProtectedFixups.Fixup(gens); GenerateAnnotationAttributes(gens, annotations_zips); //SymbolTable.Dump (); GenerationInfo gen_info = new GenerationInfo(csdir, javadir, assemblyQN); opt.AssemblyName = gen_info.Assembly; if (mapping_file != null) { GenerateMappingReportFile(gens, mapping_file); } foreach (IGeneratable gen in gens) { if (gen.IsGeneratable) { gen.Generate(opt, gen_info); } } new NamespaceMapping(gens).Generate(opt, gen_info); ClassGen.GenerateTypeRegistrations(opt, gen_info); ClassGen.GenerateEnumList(gen_info); // Create the .cs files for the enums var enumFiles = enums == null ? null : enummap.WriteEnumerations(enumdir, enums, FlattenNestedTypes(gens).ToArray(), opt.UseShortFileNames); gen_info.GenerateLibraryProjectFile(options, enumFiles); }