/// <summary> /// Create a type builder for the given type. /// </summary> internal static IClassBuilder[] Create(ReachableContext context, AssemblyCompiler compiler, TypeDefinition typeDef) { if (typeDef.FullName == "<Module>") return new IClassBuilder[] { new SkipClassBuilder() }; if (typeDef.IsDelegate()) return new IClassBuilder[] {new DelegateClassBuilder(context, compiler, typeDef) }; if (typeDef.IsAttribute()) return new IClassBuilder[] {new AttributeClassBuilder(context, compiler, typeDef) }; if (typeDef.IsAnnotation()) return new IClassBuilder[] {new AnnotationClassBuilder(context, compiler, typeDef) }; if (typeDef.HasDexImportAttribute()) return new IClassBuilder[] {new DexImportClassBuilder(context, compiler, typeDef) }; if (typeDef.HasJavaImportAttribute()) return new IClassBuilder[] {CreateJavaImportBuilder(context, compiler, typeDef)}; if (typeDef.IsEnum) { if (typeDef.UsedInNullableT) { var nullableBaseClassBuilder = new NullableEnumBaseClassBuilder(context, compiler, typeDef); IClassBuilder builder = new EnumClassBuilder(context, compiler, typeDef, nullableBaseClassBuilder); return new[] { builder, nullableBaseClassBuilder }; } return new IClassBuilder[] { new EnumClassBuilder(context, compiler, typeDef, null) }; } else { IClassBuilder builder = new StandardClassBuilder(context, compiler, typeDef); if (typeDef.UsedInNullableT) return new[] { builder, new NullableBaseClassBuilder(context, compiler, typeDef) }; return new[] { builder }; } }
/// <summary> /// Create the current type as class definition. /// </summary> protected virtual void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType) { // Create classdef var nsConverter = targetPackage.NameConverter; classDef = new ClassDefinition(); classDef.MapFileId = compiler.GetNextMapFileId(); classDef.Namespace = nsConverter.GetConvertedNamespace(XType); var name = CreateClassName(XType); if ((parentType != null) && parentType.HasDexImportAttribute()) { var fullName = nsConverter.GetConvertedFullName(parentXType) + "_" + name; var index = fullName.LastIndexOf('.'); classDef.Name = (index < 0) ? fullName : fullName.Substring(index + 1); } else { classDef.Name = (parent != null) ? parent.Name + "$" + name : name; } // Set access flags //if (typeDef.IsPublic) classDef.IsPublic = true; //else classDef.IsPrivate = true; classDef.IsPublic = true; if (typeDef.IsSealed) classDef.IsFinal = true; if (typeDef.IsInterface) { classDef.IsInterface = true; classDef.IsAbstract = true; } else if (typeDef.IsAbstract) { classDef.IsAbstract = true; } if ((parent != null) && (!parentType.HasDexImportAttribute())) { // Add to parent if this is a nested type classDef.Owner = parent; parent.AddInnerClass(classDef); } else { // Add to dex if it is a root class // TODO: here we could simplify the names, e.g. remove the scope, as long as no // clashing does occur. targetPackage.DexFile.AddClass(classDef); } }