예제 #1
0
        /// <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);
                    }
                }
            }
        }