예제 #1
0
        private void AnalyzeContents()
        {
            fieldTypeValue = TypeHelpers.BoxIfReferenceType(
                ParentType.Assembly.Resolve(Definition.FieldType));

            var attrBuilder = new AttributeMapBuilder();

            // Analyze access modifier.
            attrBuilder.Add(AccessModifierAttribute.Create(AnalyzeAccessModifier()));

            // TODO: analyze other attributes.
            attributeMap = new AttributeMap(attrBuilder);
        }
예제 #2
0
        private void AnalyzeSignature()
        {
            var assembly = ParentType.Assembly;

            // Analyze the return parameter.
            returnParam = WrapReturnParameter(
                Definition.MethodReturnType,
                assembly,
                this);

            // Analyze the parameter list.
            formalParams = Definition.Parameters
                           .Select(param => WrapParameter(param, assembly, this))
                           .ToArray();

            // Analyze the method definition's attributes.
            var attrBuilder = new AttributeMapBuilder();

            if (Definition.IsAbstract || Definition.DeclaringType.IsInterface)
            {
                attrBuilder.Add(FlagAttribute.Abstract);
                attrBuilder.Add(FlagAttribute.Virtual);
            }
            else if (Definition.IsVirtual)
            {
                attrBuilder.Add(FlagAttribute.Virtual);
            }

            if (Definition.IsPInvokeImpl)
            {
                if (Definition.HasPInvokeInfo)
                {
                    attrBuilder.Add(new ExternAttribute(Definition.PInvokeInfo.EntryPoint));
                }
                else
                {
                    attrBuilder.Add(new ExternAttribute());
                }
            }
            else if (Definition.IsInternalCall)
            {
                attrBuilder.Add(FlagAttribute.InternalCall);
            }

            // The default 'object' constructor is a nop. Taking that
            // into account can significantly improve constructor inlining
            // results.
            var declaringType = Definition.DeclaringType;

            if (declaringType.Namespace == "System" &&
                declaringType.Name == "Object" &&
                Definition.IsConstructor &&
                Definition.Parameters.Count == 0)
            {
                attrBuilder.Add(new ExceptionSpecificationAttribute(ExceptionSpecification.NoThrow));
                attrBuilder.Add(new MemorySpecificationAttribute(MemorySpecification.Nothing));
            }

            // Analyze access modifier.
            attrBuilder.Add(AccessModifierAttribute.Create(AnalyzeAccessModifier()));
            // TODO: analyze more attributes.
            attributeMap = new AttributeMap(attrBuilder);
        }
예제 #3
0
        private void AnalyzeAttributes()
        {
            var attrBuilder = new AttributeMapBuilder();

            // Handle low-hanging fruit first.
            if (!Definition.IsValueType)
            {
                attrBuilder.Add(FlagAttribute.ReferenceType);
            }
            if (Definition.IsAbstract)
            {
                attrBuilder.Add(FlagAttribute.Abstract);
            }
            if (Definition.IsInterface)
            {
                attrBuilder.Add(FlagAttribute.Abstract);
                attrBuilder.Add(FlagAttribute.InterfaceType);
            }
            if (!Definition.IsSealed)
            {
                attrBuilder.Add(FlagAttribute.Virtual);
            }

            // If we're dealing with an integer type, then we want to
            // assign that type an integer spec.
            IntegerSpec iSpec;

            if (Definition.Namespace == "System")
            {
                if (integerSpecMap.TryGetValue(Definition.Name, out iSpec))
                {
                    attrBuilder.Add(IntegerSpecAttribute.Create(iSpec));
                    attrBuilder.Add(FlagAttribute.SpecialType);
                }
                else if (Definition.Name == "Single" || Definition.Name == "Double")
                {
                    attrBuilder.Add(FlagAttribute.SpecialType);
                }
            }

            // If we are presented an enum type, then we need to look
            // up its 'value__' field, which specifies its enum type.
            if (Definition.IsEnum)
            {
                // The 'value__' field has some very particular properties:
                // it has both the "runtime special name" and "special name"
                // attributes.
                var valueField = Definition.Fields.FirstOrDefault(
                    field =>
                    field.Name == "value__" &&
                    field.IsRuntimeSpecialName &&
                    field.IsSpecialName);

                // Make sure that we didn't encounter a "fake" enum.
                if (valueField != null)
                {
                    // Resolve the enum's element type. This should always be an
                    // integer type.
                    var enumElementType = Assembly.Resolve(valueField.FieldType);
                    var enumIntSpec     = enumElementType.GetIntegerSpecOrNull();

                    if (enumIntSpec != null)
                    {
                        // Mark the enum type itself as an integer type because it
                        // acts like an integer type in essentially every way.
                        attrBuilder.Add(IntegerSpecAttribute.Create(enumIntSpec));
                        attrBuilder.Add(FlagAttribute.SpecialType);
                    }
                }
            }

            // Analyze access modifier.
            attrBuilder.Add(AccessModifierAttribute.Create(AnalyzeAccessModifier()));

            // TODO: support more attributes.
            attributeMap = new AttributeMap(attrBuilder);
        }