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

                MethodSymbol methodSymbol = new MethodSymbol(methodName, typeSymbol, returnType);
                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();
                }

                if ((methodSymbol.Visibility & MemberVisibility.Static) != 0) {
                    string alias = MetadataHelpers.GetScriptAlias(method);
                    if (String.IsNullOrEmpty(alias) == false) {
                        methodSymbol.SetAlias(alias);
                    }
                }

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

                typeSymbol.AddMember(methodSymbol);
            }
        }
예제 #2
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);
                        }
                    }
                }
            }
        }
예제 #3
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);
            }
        }