Beispiel #1
0
        private MemberSymbol CreateGenericMember(MemberSymbol templateMember, IList <TypeSymbol> typeArguments)
        {
            TypeSymbol parentType = (TypeSymbol)templateMember.Parent;
            TypeSymbol instanceAssociatedType;

            if (templateMember.AssociatedType.Type == SymbolType.GenericParameter)
            {
                GenericParameterSymbol genericParameter = (GenericParameterSymbol)templateMember.AssociatedType;
                instanceAssociatedType = typeArguments[genericParameter.Index];
            }
            else
            {
                instanceAssociatedType = typeArguments[0];
            }

            if (templateMember.Type == SymbolType.Indexer)
            {
                IndexerSymbol templateIndexer = (IndexerSymbol)templateMember;
                IndexerSymbol instanceIndexer = new IndexerSymbol(parentType, instanceAssociatedType);

                if (templateIndexer.UseScriptIndexer)
                {
                    instanceIndexer.SetScriptIndexer();
                }
                instanceIndexer.SetVisibility(templateIndexer.Visibility);

                return(instanceIndexer);
            }
            else if (templateMember.Type == SymbolType.Property)
            {
                PropertySymbol templateProperty = (PropertySymbol)templateMember;
                PropertySymbol instanceProperty = new PropertySymbol(templateProperty.Name, parentType, instanceAssociatedType);

                if (templateProperty.IsTransformed)
                {
                    instanceProperty.SetTransformedName(templateProperty.GeneratedName);
                }
                instanceProperty.SetNameCasing(templateProperty.IsCasePreserved);
                instanceProperty.SetVisibility(templateProperty.Visibility);

                return(instanceProperty);
            }
            else if (templateMember.Type == SymbolType.Field)
            {
                FieldSymbol templateField = (FieldSymbol)templateMember;
                FieldSymbol instanceField = new FieldSymbol(templateField.Name, parentType, instanceAssociatedType);

                if (templateField.IsTransformed)
                {
                    instanceField.SetTransformedName(templateField.GeneratedName);
                }
                instanceField.SetNameCasing(templateField.IsCasePreserved);
                instanceField.SetVisibility(templateField.Visibility);

                return(instanceField);
            }
            else if (templateMember.Type == SymbolType.Method)
            {
                MethodSymbol templateMethod = (MethodSymbol)templateMember;
                MethodSymbol instanceMethod = new MethodSymbol(templateMethod.Name, parentType, instanceAssociatedType);

                if (templateMethod.IsAliased)
                {
                    instanceMethod.SetAlias(templateMethod.Alias);
                }
                else if (templateMethod.IsTransformed)
                {
                    instanceMethod.SetTransformedName(templateMethod.GeneratedName);
                }
                if (templateMethod.SkipGeneration)
                {
                    instanceMethod.SetSkipGeneration();
                }
                if (templateMethod.InterfaceMember != null)
                {
                    instanceMethod.SetInterfaceMember(templateMethod.InterfaceMember);
                }
                instanceMethod.SetNameCasing(templateMethod.IsCasePreserved);
                instanceMethod.SetVisibility(templateMethod.Visibility);

                return(instanceMethod);
            }

            Debug.Fail("Unexpected generic member '" + templateMember.Name + " on type '" + ((TypeSymbol)templateMember.Parent).FullName + "'.");
            return(null);
        }
        private void ImportType(MetadataSource mdSource, TypeDefinition type, bool inScriptCoreAssembly, string assemblyScriptNamespace, string assemblyScriptName)
        {
            if (type.IsPublic == false) {
                return;
            }
            if (inScriptCoreAssembly && (MetadataHelpers.ShouldImportScriptCoreType(type) == false)) {
                return;
            }

            string name = type.Name;
            string namespaceName = type.Namespace;
            string scriptNamespace = MetadataHelpers.GetScriptNamespace(type);
            string scriptName = MetadataHelpers.GetScriptName(type);

            if (String.IsNullOrEmpty(scriptNamespace) && (String.IsNullOrEmpty(assemblyScriptNamespace) == false)) {
                scriptNamespace = assemblyScriptNamespace;
            }

            NamespaceSymbol namespaceSymbol = _symbols.GetNamespace(namespaceName);
            TypeSymbol typeSymbol = null;

            if (type.IsInterface) {
                typeSymbol = new InterfaceSymbol(name, namespaceSymbol);
            }
            else if (MetadataHelpers.IsEnum(type)) {
                // NOTE: We don't care about the flags bit on imported enums
                //       because this is only consumed by the generation logic.
                typeSymbol = new EnumerationSymbol(name, namespaceSymbol, /* flags */ false);
                if (MetadataHelpers.ShouldUseEnumNames(type)) {
                    ((EnumerationSymbol)typeSymbol).SetNamedValues();
                }
                else if (MetadataHelpers.ShouldUseEnumValues(type)) {
                    ((EnumerationSymbol)typeSymbol).SetNumericValues();
                }
            }
            else if (MetadataHelpers.IsDelegate(type)) {
                typeSymbol = new DelegateSymbol(name, namespaceSymbol);
                typeSymbol.SetTransformedName("Function");
            }
            else {
                if (MetadataHelpers.ShouldTreatAsRecordType(type)) {
                    typeSymbol = new RecordSymbol(name, namespaceSymbol);
                }
                else {
                    typeSymbol = new ClassSymbol(name, namespaceSymbol);

                    string mixinRoot;
                    if (MetadataHelpers.ShouldGlobalizeMembers(type, out mixinRoot)) {
                        ((ClassSymbol)typeSymbol).SetGlobalMethods(mixinRoot);
                    }
                }
            }

            if (typeSymbol != null) {
                if (type.HasGenericParameters) {
                    List<GenericParameterSymbol> genericArguments = new List<GenericParameterSymbol>();
                    foreach (GenericParameter genericParameter in type.GenericParameters) {
                        GenericParameterSymbol arg =
                            new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                      /* typeArgument */ true,
                                                      _symbols.GlobalNamespace);
                        genericArguments.Add(arg);
                    }

                    typeSymbol.AddGenericParameters(genericArguments);
                }

                typeSymbol.SetImported(assemblyScriptName);
                typeSymbol.SetMetadataToken(type, inScriptCoreAssembly);

                bool ignoreNamespace = MetadataHelpers.ShouldIgnoreNamespace(type);
                if (ignoreNamespace) {
                    typeSymbol.SetIgnoreNamespace();
                }
                typeSymbol.SetPublic();

                if (String.IsNullOrEmpty(scriptNamespace) == false) {
                    typeSymbol.ScriptNamespace = scriptNamespace;
                }

                if (String.IsNullOrEmpty(scriptName) == false) {
                    typeSymbol.SetTransformedName(scriptName);
                }

                namespaceSymbol.AddType(typeSymbol);
                _importedTypes.Add(typeSymbol);
            }
        }
        private TypeSymbol ResolveType(TypeReference type)
        {
            int arrayDimensions = 0;
            while (type is ArrayType) {
                arrayDimensions++;
                type = ((ArrayType)type).ElementType;
            }

            GenericInstanceType genericType = type as GenericInstanceType;
            if (genericType != null) {
                type = genericType.ElementType;
            }

            string name = type.FullName;
            if (String.CompareOrdinal(name, "System.ValueType") == 0) {
                // Ignore this type - it is the base class for enums, and other primitive types
                // but we don't import it since it is not useful in script
                return null;
            }

            TypeSymbol typeSymbol;

            GenericParameter genericParameter = type as GenericParameter;
            if (genericParameter != null) {
                typeSymbol = new GenericParameterSymbol(genericParameter.Position, genericParameter.Name,
                                                       (genericParameter.Owner.GenericParameterType == GenericParameterType.Type),
                                                       _symbols.GlobalNamespace);
            }
            else {
                typeSymbol = (TypeSymbol)((ISymbolTable)_symbols).FindSymbol(name, null, SymbolFilter.Types);
                if (typeSymbol == null) {
                    _errorHandler.ReportError("Unable to resolve referenced type '" + name +
                                              "'. Make sure all needed assemblies have been explicitly referenced.",
                                              String.Empty);
                    _resolveError = true;
                }
            }

            if (genericType != null) {
                List<TypeSymbol> typeArgs = new List<TypeSymbol>();

                foreach (TypeReference argTypeRef in genericType.GenericArguments) {
                    TypeSymbol argType = ResolveType(argTypeRef);
                    typeArgs.Add(argType);
                }

                typeSymbol = _symbols.CreateGenericTypeSymbol(typeSymbol, typeArgs);
                Debug.Assert(typeSymbol != null);
            }

            if (arrayDimensions != 0) {
                for (int i = 0; i < arrayDimensions; i++) {
                    typeSymbol = _symbols.CreateArrayTypeSymbol(typeSymbol);
                }
            }

            return typeSymbol;
        }
        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);
            }
        }