コード例 #1
0
ファイル: ClassBuilder.cs プロジェクト: Xtremrules/dot42
        /// <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);
            }
        }
コード例 #2
0
        /// <summary>
        /// Create an annotation interface.
        /// </summary>
        internal static AttributeAnnotationInterface Create(
            ISourceLocation sequencePoint,
            AssemblyCompiler compiler,
            DexTargetPackage targetPackage,
            TypeDefinition attributeType,
            ClassDefinition attributeClass)
        {
            // Create class
            ClassDefinition @interface = new ClassDefinition();
            @interface.Name = CreateAnnotationTypeName(attributeClass);
            @interface.Namespace = attributeClass.Namespace;
            @interface.AccessFlags = AccessFlags.Public | AccessFlags.Abstract | AccessFlags.Interface | AccessFlags.Annotation;
            @interface.Owner = attributeClass;
            attributeClass.AddInnerClass(@interface);

            // Set super class
            @interface.SuperClass = FrameworkReferences.Object;

            // Implement Dot42.Internal.IAttribute
            @interface.Interfaces.Add(new ClassReference("java/lang/annotation/Annotation"));

            // Prepare result
            AttributeAnnotationInterface result = new AttributeAnnotationInterface(@interface);

            // Add methods from IAttribute
            XModel.XTypeDefinition baseIntfType = compiler.GetDot42InternalType("IAttribute").Resolve();
            foreach (XModel.XMethodDefinition imethod in baseIntfType.Methods)
            {
                if (imethod.Parameters.Count > 0) 
                    throw new CompilerException(string.Format("Invalid IAttribute method {0}", imethod));
                string methodName = NameConverter.GetConvertedName(imethod);
                TypeReference dfieldType = imethod.ReturnType.GetReference(targetPackage);
                MethodDefinition method = new MethodDefinition(@interface, methodName, new Prototype(dfieldType));
                method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract;
                @interface.Methods.Add(method);                
            }

            TypeDefinition currentType = attributeType;

            while (currentType != null && currentType.FullName != typeof(Attribute).FullName)
            {
                // Add field mapping
                foreach (var field in currentType.Fields.Where(x => x.IsReachable && x.IsPublic))
                {
                    string methodName = CreateGetMethodName(NameConverter.GetConvertedName(field), result);
                    MethodDefinition method = new MethodDefinition(@interface, methodName,
                                                        MakePrototype(field.FieldType, targetPackage, compiler.Module));
                    method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract;
                    result.FieldToGetMethodMap.Add(field, method);
                    @interface.Methods.Add(method);
                }

                // Add property mapping
                foreach (var property in currentType.Properties.Where(
                                              x => x.IsReachable && (x.SetMethod != null) 
                                         && x.SetMethod.IsPublic && x.SetMethod.IsReachable))
                {
                    // ignore properties with same name [might be overriden]
                    if (result.PropertyToGetMethodMap.Keys.Any(k => k.Name == property.Name))
                        continue;

                    string methodName = CreateGetMethodName(NameConverter.GetConvertedName(property), result);
                    Mono.Cecil.TypeReference propType = property.PropertyType;

                    MethodDefinition method = new MethodDefinition(@interface, methodName,
                                                        MakePrototype(propType, targetPackage, compiler.Module));
                    method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract;
                    result.PropertyToGetMethodMap.Add(property, method);
                    @interface.Methods.Add(method);
                }

                if (currentType.BaseType == null || currentType.BaseType.IsSystemObject())
                    break;

                currentType = currentType.BaseType.Resolve();
            }
            // Add ctor mapping
            var argIndex = 0;
            foreach (var ctor in attributeType.Methods.Where(x => (x.Name == ".ctor") && x.IsReachable))
            {
                // Add methods for the ctor arguments
                List<Tuple<MethodDefinition, Mono.Cecil.TypeReference>> paramGetMethods = new List<Tuple<MethodDefinition, Mono.Cecil.TypeReference>>();
                foreach (ParameterDefinition p in ctor.Parameters)
                {
                    string methodName = CreateGetMethodName("c" + argIndex++, result);
                    MethodDefinition method = new MethodDefinition(@interface, methodName, MakePrototype(p.ParameterType, targetPackage, compiler.Module));
                    method.AccessFlags = AccessFlags.Public | AccessFlags.Abstract;
                    @interface.Methods.Add(method);
                    paramGetMethods.Add(Tuple.Create(method, p.ParameterType));
                }

                // Add a builder method
                MethodDefinition buildMethod = CreateBuildMethod(sequencePoint, ctor, paramGetMethods, compiler, targetPackage, attributeClass, result);
                result.CtorMap.Add(ctor, new AttributeCtorMapping(buildMethod, paramGetMethods.Select(p=>p.Item1).ToList()));
            }

            // Create default values annotation
            Annotation defAnnotation = CreateDefaultAnnotation(result);
            result.AnnotationInterfaceClass.Annotations.Add(defAnnotation);

            return result;
        }
コード例 #3
0
ファイル: ClassBuilder.cs プロジェクト: Xtremrules/dot42
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        protected virtual void CreateClassDefinition(Dex target, NameConverter nsConverter, ClassDefinition parent, ClassFile parentClass)
        {
            // Create classdef
            classDef = new ClassDefinition();
            classDef.MapFileId = compiler.GetNextMapFileId();
            classDef.Namespace = nsConverter.GetConvertedNamespace(typeDef);
            var name = NameConverter.GetConvertedName(typeDef);
            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.IsFinal) classDef.IsFinal = true;
            if (typeDef.IsInterface)
            {
                classDef.IsInterface = true;
                classDef.IsAbstract = true;
            }
            else if (typeDef.IsAbstract)
            {
                classDef.IsAbstract = true;
            }
            if (typeDef.Interfaces.Any(x => x.ClassName == "java/lang/annotation/Annotation"))
            {
                classDef.IsAnnotation = true;
            }

            classDef.IsEnum = typeDef.IsEnum;

            if (parent != null)
            {
                // 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
                target.AddClass(classDef);
            }
        }