コード例 #1
0
        private void ImportEnumFields(TypeSymbol enumTypeSymbol)
        {
            TypeDefinition type = (TypeDefinition)enumTypeSymbol.MetadataReference;

            foreach (FieldDefinition field in type.Fields)
            {
                if (field.IsSpecialName)
                {
                    continue;
                }

                Debug.Assert(enumTypeSymbol is EnumerationSymbol);
                EnumerationSymbol enumSymbol = (EnumerationSymbol)enumTypeSymbol;

                TypeSymbol fieldType;

                if (enumSymbol.UseNamedValues)
                {
                    fieldType = symbols.ResolveIntrinsicType(IntrinsicType.String);
                }
                else
                {
                    fieldType = symbols.ResolveIntrinsicType(IntrinsicType.Integer);
                }

                string fieldName = field.Name;

                EnumerationFieldSymbol fieldSymbol =
                    new EnumerationFieldSymbol(fieldName, enumTypeSymbol, field.Constant, fieldType);
                ImportMemberDetails(fieldSymbol, null, field);

                enumTypeSymbol.AddMember(fieldSymbol);
            }
        }
コード例 #2
0
        private void ImportDelegateInvoke(TypeSymbol delegateTypeSymbol)
        {
            TypeDefinition type = (TypeDefinition)delegateTypeSymbol.MetadataReference;

            foreach (MethodDefinition method in type.Methods)
            {
                if (string.CompareOrdinal(method.Name, "Invoke") != 0)
                {
                    continue;
                }

                TypeSymbol returnType = ResolveType(method.MethodReturnType.ReturnType);
                Debug.Assert(returnType != null);

                if (returnType == null)
                {
                    continue;
                }

                MethodSymbol methodSymbol =
                    new MethodSymbol("Invoke", delegateTypeSymbol, returnType, MemberVisibility.Public);
                methodSymbol.SetImplementationState(SymbolImplementationFlags.Abstract);
                methodSymbol.SetTransformedName(string.Empty);

                delegateTypeSymbol.AddMember(methodSymbol);
            }
        }
コード例 #3
0
        private void ImportEvents(TypeSymbol typeSymbol)
        {
            TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference;

            foreach (EventDefinition eventDef in type.Events)
            {
                if (eventDef.IsSpecialName)
                {
                    continue;
                }
                if ((eventDef.AddMethod == null) || (eventDef.RemoveMethod == null))
                {
                    continue;
                }
                if (eventDef.AddMethod.IsPrivate || eventDef.AddMethod.IsAssembly || eventDef.AddMethod.IsFamilyAndAssembly)
                {
                    continue;
                }

                string eventName = eventDef.Name;

                TypeSymbol eventHandlerType = ResolveType(eventDef.EventType);
                if (eventHandlerType == null)
                {
                    continue;
                }

                EventSymbol eventSymbol = new EventSymbol(eventName, typeSymbol, eventHandlerType);
                ImportMemberDetails(eventSymbol, eventDef.AddMethod, eventDef);

                typeSymbol.AddMember(eventSymbol);
            }
        }
コード例 #4
0
        private void ImportFields(TypeSymbol typeSymbol)
        {
            TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference;

            foreach (FieldDefinition field in type.Fields)
            {
                if (field.IsSpecialName)
                {
                    continue;
                }

                if (field.IsPrivate || field.IsAssembly || field.IsFamilyAndAssembly)
                {
                    continue;
                }

                string fieldName = field.Name;

                TypeSymbol fieldType = ResolveType(field.FieldType);

                if (fieldType == null)
                {
                    continue;
                }

                MemberVisibility visibility = MemberVisibility.PrivateInstance;

                if (field.IsStatic)
                {
                    visibility |= MemberVisibility.Static;
                }

                if (field.IsPublic)
                {
                    visibility |= MemberVisibility.Public;
                }
                else if (field.IsFamily || field.IsFamilyOrAssembly)
                {
                    visibility |= MemberVisibility.Protected;
                }

                FieldSymbol fieldSymbol = new FieldSymbol(fieldName, typeSymbol, fieldType);

                fieldSymbol.SetVisibility(visibility);
                ImportMemberDetails(fieldSymbol, null, field);

                if (field.IsLiteral && field.HasConstant && !typeSymbol.IsCoreType &&
                    (field.FieldType.IsPrimitive || field.FieldType.Name == "String"))
                {
                    fieldSymbol.SetConstant();
                    fieldSymbol.Value = field.Constant;
                }

                typeSymbol.AddMember(fieldSymbol);
            }
        }
コード例 #5
0
        private void ImportEvents(TypeSymbol typeSymbol)
        {
            TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference;

            foreach (EventDefinition eventDef in type.Events)
            {
                if (eventDef.IsSpecialName)
                {
                    continue;
                }

                if (eventDef.AddMethod == null || eventDef.RemoveMethod == null)
                {
                    continue;
                }

                if (eventDef.AddMethod.IsPrivate || eventDef.AddMethod.IsAssembly ||
                    eventDef.AddMethod.IsFamilyAndAssembly)
                {
                    continue;
                }

                string eventName = eventDef.Name;

                TypeSymbol eventHandlerType = ResolveType(eventDef.EventType);

                if (eventHandlerType == null)
                {
                    continue;
                }

                EventSymbol eventSymbol = new EventSymbol(eventName, typeSymbol, eventHandlerType);
                ImportMemberDetails(eventSymbol, eventDef.AddMethod, eventDef);

                if (MetadataHelpers.GetScriptEventAccessors(eventDef, out string addAccessor, out string removeAccessor))
                {
                    eventSymbol.SetAccessors(addAccessor, removeAccessor);
                }

                typeSymbol.AddMember(eventSymbol);
            }
        }
コード例 #6
0
        private void ImportProperties(TypeSymbol typeSymbol)
        {
            TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference;

            foreach (PropertyDefinition property in type.Properties)
            {
                if (property.IsSpecialName)
                {
                    continue;
                }

                if (property.GetMethod == null)
                {
                    continue;
                }

                if (property.GetMethod.IsPrivate || property.GetMethod.IsAssembly ||
                    property.GetMethod.IsFamilyAndAssembly)
                {
                    continue;
                }

                string propertyName = property.Name;
                bool   scriptField  = MetadataHelpers.ShouldTreatAsScriptField(property);

                // TODO: Why are we ignoring the other bits...
                // bool dummyPreserveName;
                // bool preserveCase;
                // string dummyName = MetadataHelpers.GetScriptName(property, out dummyPreserveName, out preserveCase);

                TypeSymbol propertyType = ResolveType(property.PropertyType);

                if (propertyType == null)
                {
                    continue;
                }

                PropertySymbol propertySymbol = null;

                if (property.Parameters.Count != 0)
                {
                    IndexerSymbol indexerSymbol = new IndexerSymbol(typeSymbol, propertyType);
                    ImportMemberDetails(indexerSymbol, property.GetMethod, property);

                    if (scriptField)
                    {
                        indexerSymbol.SetScriptIndexer();
                    }

                    propertySymbol = indexerSymbol;
                    // propertySymbol.SetNameCasing(preserveCase);
                }
                else
                {
                    if (scriptField)
                    {
                        // Properties marked with this attribute are to be thought of as
                        // fields. If they are read-only, the C# compiler will enforce that,
                        // so we don't have to worry about making them read-write via a field
                        // instead of a property

                        FieldSymbol fieldSymbol = new FieldSymbol(propertyName, typeSymbol, propertyType);
                        ImportMemberDetails(fieldSymbol, property.GetMethod, property);

                        string transformedName = MetadataHelpers.GetTransformedName(property);

                        if (string.IsNullOrEmpty(transformedName) == false)
                        {
                            fieldSymbol.SetTransformName(transformedName);
                        }

                        typeSymbol.AddMember(fieldSymbol);
                    }
                    else
                    {
                        propertySymbol = new PropertySymbol(propertyName, typeSymbol, propertyType);
                        ImportMemberDetails(propertySymbol, property.GetMethod, property);
                        propertySymbol.SetNameCasing(true);

                        string transformedName = MetadataHelpers.GetTransformedName(property.GetMethod);

                        if (string.IsNullOrEmpty(transformedName) == false)
                        {
                            propertySymbol.SetTransformedName(transformedName);
                        }
                    }
                }

                if (propertySymbol != null)
                {
                    SymbolImplementationFlags implFlags = SymbolImplementationFlags.Regular;

                    if (property.SetMethod == null)
                    {
                        implFlags |= SymbolImplementationFlags.ReadOnly;
                    }

                    if (property.GetMethod.IsAbstract)
                    {
                        implFlags |= SymbolImplementationFlags.Abstract;
                    }

                    propertySymbol.SetImplementationState(implFlags);

                    typeSymbol.AddMember(propertySymbol);
                }
            }
        }
コード例 #7
0
        private void ImportMethods(TypeSymbol typeSymbol)
        {
            // NOTE: We do not import parameters for imported members.
            //       Parameters are used in the script model generation phase to populate
            //       symbol tables, which is not done for imported methods.

            TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference;

            foreach (MethodDefinition method in type.Methods)
            {
                if (method.IsSpecialName)
                {
                    continue;
                }

                if (method.IsPrivate || method.IsAssembly || method.IsFamilyAndAssembly)
                {
                    continue;
                }

                string methodName = method.Name;

                if (typeSymbol.GetMember(methodName) != null)
                {
                    // Ignore if its an overload since we don't care about parameters
                    // for imported methods, overloaded ctors don't matter.
                    // We just care about return values pretty much, and existence of the
                    // method.
                    continue;
                }

                TypeSymbol returnType = ResolveType(method.MethodReturnType.ReturnType);

                if (returnType == null)
                {
                    continue;
                }

                // skip symbol generation for members decorated with [ScriptIgnore]
                if (MetadataHelpers.IsIgnored(method))
                {
                    continue;
                }

                MethodSymbol methodSymbol = new MethodSymbol(
                    methodName,
                    typeSymbol,
                    returnType,
                    MetadataHelpers.IsExtensionMethod(method));

                if (MetadataHelpers.ShouldIgnoreMethodGeneratedTypeArguments(method))
                {
                    methodSymbol.IgnoreGeneratedTypeArguments = true;
                }

                methodSymbol.SetParseContext(method);
                ImportMemberDetails(methodSymbol, method, method);

                if (method.HasGenericParameters)
                {
                    List <GenericParameterSymbol> genericArguments = new List <GenericParameterSymbol>();

                    foreach (GenericParameter genericParameter in method.GenericParameters)
                    {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                       /* typeArgument */ false,
                                                       symbols.GlobalNamespace);
                        genericArguments.Add(arg);
                    }

                    methodSymbol.AddGenericArguments(genericArguments);
                }

                if (method.IsAbstract)
                {
                    // NOTE: We're ignoring the override scenario - it doesn't matter in terms
                    //       of the compilation and code generation
                    methodSymbol.SetImplementationState(SymbolImplementationFlags.Abstract);
                }

                if (MetadataHelpers.ShouldSkipFromScript(method))
                {
                    methodSymbol.SetSkipGeneration();
                }

                string transformedName = MetadataHelpers.GetTransformedName(method);

                if (string.IsNullOrEmpty(transformedName) == false)
                {
                    methodSymbol.SetTransformName(transformedName);
                }

                string scriptName = MetadataHelpers.GetScriptName(method, out _, out _);

                if (string.IsNullOrEmpty(scriptName) == false && !methodSymbol.IsTransformed)
                {
                    methodSymbol.SetTransformedName(scriptName);
                }

                string selector = MetadataHelpers.GetScriptMethodSelector(method);

                if (string.IsNullOrEmpty(selector) == false)
                {
                    methodSymbol.SetSelector(selector);
                }

                if (MetadataHelpers.ShouldTreatAsConditionalMethod(method, out ICollection <string> conditions))
                {
                    methodSymbol.SetConditions(conditions);
                }

                typeSymbol.AddMember(methodSymbol);
            }
        }
コード例 #8
0
        private void BuildMembers(TypeSymbol typeSymbol)
        {
            if (typeSymbol.Type == SymbolType.Delegate)
            {
                DelegateTypeNode delegateNode = (DelegateTypeNode)typeSymbol.ParseContext;

                TypeSymbol returnType = typeSymbol.SymbolSet.ResolveType(delegateNode.ReturnType, _symbolTable, typeSymbol);
                Debug.Assert(returnType != null);

                if (returnType != null)
                {
                    MethodSymbol invokeMethod = new MethodSymbol("Invoke", typeSymbol, returnType, MemberVisibility.Public);
                    invokeMethod.SetTransformedName(String.Empty);

                    // Mark the method as abstract, as there is no actual implementation of the method
                    // to be generated
                    invokeMethod.SetImplementationState(SymbolImplementationFlags.Abstract);

                    typeSymbol.AddMember(invokeMethod);
                }
                return;
            }

            CustomTypeNode typeNode = (CustomTypeNode)typeSymbol.ParseContext;

            foreach (MemberNode member in typeNode.Members)
            {
                MemberSymbol memberSymbol = null;
                switch (member.NodeType)
                {
                case ParseNodeType.FieldDeclaration:
                case ParseNodeType.ConstFieldDeclaration:
                    memberSymbol = BuildField((FieldDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.PropertyDeclaration:
                    memberSymbol = BuildPropertyAsField((PropertyDeclarationNode)member, typeSymbol);
                    if (memberSymbol == null)
                    {
                        memberSymbol = BuildProperty((PropertyDeclarationNode)member, typeSymbol);
                    }
                    break;

                case ParseNodeType.IndexerDeclaration:
                    memberSymbol = BuildIndexer((IndexerDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.ConstructorDeclaration:
                case ParseNodeType.MethodDeclaration:
                    if ((member.Modifiers & Modifiers.Extern) != 0)
                    {
                        // Extern methods are there for defining overload signatures, so
                        // we just skip them as far as metadata goes. The validator has
                        // taken care of the requirements/constraints around use of extern methods.
                        continue;
                    }
                    memberSymbol = BuildMethod((MethodDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.EventDeclaration:
                    memberSymbol = BuildEvent((EventDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.EnumerationFieldDeclaration:
                    memberSymbol = BuildEnumField((EnumerationFieldNode)member, typeSymbol);
                    break;
                }

                if (memberSymbol != null)
                {
                    memberSymbol.SetParseContext(member);

                    if ((typeSymbol.IsApplicationType == false) &&
                        ((memberSymbol.Type == SymbolType.Constructor) ||
                         (typeSymbol.GetMember(memberSymbol.Name) != null)))
                    {
                        // If the type is an imported type, then it is allowed to contain
                        // overloads, and we're simply going to ignore its existence, as long
                        // as one overload has been added to the member table.
                        continue;
                    }

                    typeSymbol.AddMember(memberSymbol);

                    if ((typeSymbol.Type == SymbolType.Class) && (memberSymbol.Type == SymbolType.Event))
                    {
                        EventSymbol eventSymbol = (EventSymbol)memberSymbol;
                        if (eventSymbol.DefaultImplementation)
                        {
                            // Add a private field that will serve as the backing member
                            // later on in the conversion (eg. in non-event expressions)
                            MemberVisibility visibility = MemberVisibility.PrivateInstance;
                            if ((eventSymbol.Visibility & MemberVisibility.Static) != 0)
                            {
                                visibility |= MemberVisibility.Static;
                            }

                            FieldSymbol fieldSymbol =
                                new FieldSymbol("__" + Utility.CreateCamelCaseName(eventSymbol.Name), typeSymbol,
                                                eventSymbol.AssociatedType);
                            fieldSymbol.SetVisibility(visibility);
                            fieldSymbol.SetParseContext(((EventDeclarationNode)eventSymbol.ParseContext).Field);

                            typeSymbol.AddMember(fieldSymbol);
                        }
                    }
                }
            }
        }