コード例 #1
0
ファイル: FieldBuilder.cs プロジェクト: luozhiping1987/dot42
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public virtual void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield      = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);

            // Give warning if static in generic class.
            // This could of cause also be handled automagically be the compiler,
            // with mixture of whats done in the Interlocked converter and whats
            // done in the GenericInstanceConverter.
            if (field.IsStatic && declaringType.IsGenericClass)
            {
                if (!field.HasSuppressMessageAttribute("StaticFieldInGenericType") &&
                    !field.DeclaringType.HasSuppressMessageAttribute("StaticFieldInGenericType"))
                {
                    string msg;
                    if (field.Name.Contains("CachedAnonymousMethodDelegate"))
                    {
                        msg = "The compiler generated a static field '{0}' in generic type '{1}'. This is not supported " +
                              "in Dot42 if the anonymous delegate accesses a generic class parameter. A workaround " +
                              "is to convert the anonymous static delegate to a normal method.\n";
                    }
                    else
                    {
                        msg = "Static field '{0}' in generic type {1}: All generic instances will share " +
                              "the same static field, contrary on how CLR operates. A workaround is to " +
                              "use ConcurrentDictionaries to access the values dependent on the type.\n";
                    }

                    msg += "You can suppress this warning with a [SuppressMessage(\"dot42\"," +
                           " \"StaticFieldInGenericType\")] attribute, either on the field or on the class.";

                    var body = field.DeclaringType.Methods.Select(m => m.Body)
                               .FirstOrDefault(m => m != null &&
                                               m.Instructions.Any(i => i.SequencePoint(m) != null));
                    if (body != null)
                    {
                        var seqPoint = body.Instructions.Select(i => i.SequencePoint(body)).First(i => i != null);
                        DLog.Warning(DContext.CompilerILConverter, seqPoint.Document.Url, seqPoint.StartColumn, seqPoint.StartLine, msg, field.Name, declaringType.FullName);
                    }
                    else
                    {
                        DLog.Warning(DContext.CompilerILConverter, msg, field.Name, declaringType.FullName);
                    }
                }
            }
        }
コード例 #2
0
ファイル: FieldBuilder.cs プロジェクト: jakesays/dot42
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public virtual void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);

            // Give warning if static in generic class.
            // This could of cause also be handled automagically be the compiler,
            // with mixture of whats done in the Interlocked converter and whats
            // done in the GenericInstanceConverter.
            if (field.IsStatic && declaringType.IsGenericClass)
            {
                if (!field.HasSuppressMessageAttribute("StaticFieldInGenericType")
                 && !field.DeclaringType.HasSuppressMessageAttribute("StaticFieldInGenericType"))
                {
                    string msg;
                    if (field.Name.Contains("CachedAnonymousMethodDelegate"))
                        msg = "The compiler generated a static field '{0}' in generic type '{1}'. This is not supported " +
                              "in Dot42 if the anonymous delegate accesses a generic class parameter. A workaround " +
                              "is to convert the anonymous static delegate to a normal method.\n";
                    else
                        msg = "Static field '{0}' in generic type {1}: All generic instances will share " +
                              "the same static field, contrary on how CLR operates. A workaround is to " +
                              "use ConcurrentDictionaries to access the values dependent on the type.\n";
                    
                    msg += "You can suppress this warning with a [SuppressMessage(\"dot42\"," +
                           " \"StaticFieldInGenericType\")] attribute, either on the field or on the class.";

                    var body = field.DeclaringType.Methods.Select(m => m.Body)
                                                          .FirstOrDefault(m => m != null 
                                                                            && m.Instructions.Any(i => i.SequencePoint != null));
                    if (body != null)
                    {
                        var seqPoint = body.Instructions.Select(i=>i.SequencePoint).First(i => i != null);
                        DLog.Warning(DContext.CompilerILConverter, seqPoint.Document.Url, seqPoint.StartColumn, seqPoint.StartLine, msg, field.Name, declaringType.FullName);
                    }
                    else
                    {
                        DLog.Warning(DContext.CompilerILConverter, msg, field.Name, declaringType.FullName);
                    }
                }
            }
        }
コード例 #3
0
ファイル: FieldBuilder.cs プロジェクト: rfcclub/dot42
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);
        }
コード例 #4
0
ファイル: FieldBuilder.cs プロジェクト: yuva2achieve/dot42
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield      = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);
        }
コード例 #5
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build ctors
            foreach (var baseCtor in GetBaseClassCtors())
            {
                // TODO: does this make sense? after all, we derive from object.
                //       probalby one should just remove this code, and generate a
                //       defaul constructor.

                var prototype = PrototypeBuilder.BuildPrototype(Compiler, targetPackage, null, baseCtor);
                var ctor      = new MethodDefinition(Class, "<init>", prototype);
                ctor.AccessFlags = AccessFlags.Public | AccessFlags.Constructor;
                Class.Methods.Add(ctor);
                // Create ctor body
                var ctorBody = CreateCtorBody(prototype);
                targetPackage.Record(new CompiledMethod {
                    DexMethod = ctor, RLBody = ctorBody
                });
            }

            // build original type field
            // Create field definition
            // NOTE: at the moment the underlying type is both defined as a type and in the annotation.
            //       remove one or the other when we have determined which is the better way.
            var dfield = new Dot42.DexLib.FieldDefinition();

            dfield.Owner       = Class;
            dfield.Name        = "underlying$";
            dfield.IsSynthetic = true;
            dfield.IsFinal     = true;
            dfield.IsStatic    = true;
            dfield.IsPublic    = true;

            dfield.Type  = Compiler.Module.TypeSystem.Type.GetClassReference(targetPackage);
            dfield.Value = _underlyingBuilder.Class;


            Class.Fields.Add(dfield);
        }
コード例 #6
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build ctors
            foreach (var baseCtor in GetBaseClassCtors())
            {
                // TODO: does this make sense? after all, we derive from object. 
                //       probalby one should just remove this code, and generate a 
                //       defaul constructor.
                
                var prototype = PrototypeBuilder.BuildPrototype(Compiler, targetPackage, null, baseCtor);
                var ctor = new MethodDefinition(Class, "<init>", prototype);
                ctor.AccessFlags = AccessFlags.Public | AccessFlags.Constructor;
                Class.Methods.Add(ctor);
                // Create ctor body
                var ctorBody = CreateCtorBody(prototype);
                targetPackage.Record(new CompiledMethod { DexMethod = ctor, RLBody = ctorBody });                
            }

            // build original type field
            // Create field definition
            // NOTE: at the moment the underlying type is both defined as a type and in the annotation.
            //       remove one or the other when we have determined which is the better way.
            var dfield = new Dot42.DexLib.FieldDefinition();

            dfield.Owner = Class;
            dfield.Name = "underlying$";
            dfield.IsSynthetic = true;
            dfield.IsFinal = true;
            dfield.IsStatic= true;
            dfield.IsPublic = true;

            dfield.Type = Compiler.Module.TypeSystem.Type.GetClassReference(targetPackage);
            dfield.Value = _underlyingBuilder.Class;
            

            Class.Fields.Add(dfield);

        }