コード例 #1
0
ファイル: MetadataImporter.cs プロジェクト: puslmbps/dsharp
        private ICollection <TypeSymbol> ImportAssemblies(MetadataSource mdSource)
        {
            _importedTypes = new List <TypeSymbol>();

            ImportScriptAssembly(mdSource, mdSource.CoreAssemblyPath, /* coreAssembly */ true);

            foreach (TypeSymbol typeSymbol in _importedTypes)
            {
                if ((typeSymbol.Type == SymbolType.Class) &&
                    (typeSymbol.Name.Equals("Array", StringComparison.Ordinal)))
                {
                    // Array is special - it is used to build other Arrays of more
                    // specific types we load members for in the second pass...
                    ImportMembers(typeSymbol);
                }
            }

            foreach (TypeSymbol typeSymbol in _importedTypes)
            {
                if (typeSymbol.IsGeneric)
                {
                    // Generics are also special - they are used to build other generic instances
                    // with specific types for generic arguments as we load members for other
                    // types subsequently...
                    ImportMembers(typeSymbol);
                }
            }

            foreach (TypeSymbol typeSymbol in _importedTypes)
            {
                if ((typeSymbol.IsGeneric == false) &&
                    ((typeSymbol.Type != SymbolType.Class) ||
                     (typeSymbol.Name.Equals("Array", StringComparison.Ordinal) == false)))
                {
                    ImportMembers(typeSymbol);
                }

                // There is some special-case logic to be performed on some members of the
                // global namespace.

                if (typeSymbol.Type == SymbolType.Class)
                {
                    if (typeSymbol.Name.Equals("Script", StringComparison.Ordinal))
                    {
                        // The Script class contains additional pseudo global methods that cannot
                        // be referenced at compile-time by the app author, but can be
                        // referenced by generated code during compilation.
                        ImportPseudoMembers(PseudoClassMembers.Script, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Object", StringComparison.Ordinal))
                    {
                        // We need to add a static GetType method

                        ImportPseudoMembers(PseudoClassMembers.Object, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Dictionary", StringComparison.Ordinal))
                    {
                        // The Dictionary class contains static methods at runtime, rather
                        // than instance methods.

                        ImportPseudoMembers(PseudoClassMembers.Dictionary, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Arguments", StringComparison.Ordinal))
                    {
                        // We need to add a static indexer, which isn't allowed in C#

                        ImportPseudoMembers(PseudoClassMembers.Arguments, (ClassSymbol)typeSymbol);
                    }
                }
            }

            // Import all the types first.
            // Types need to be loaded upfront so that they can be used in resolving types associated
            // with members.
            foreach (string assemblyPath in mdSource.Assemblies)
            {
                ImportScriptAssembly(mdSource, assemblyPath, /* coreAssembly */ false);
            }

            // Resolve Base Types
            foreach (TypeSymbol typeSymbol in _importedTypes)
            {
                if (typeSymbol.Type == SymbolType.Class)
                {
                    ImportBaseType((ClassSymbol)typeSymbol);
                }
                else if (typeSymbol.Type == SymbolType.Interface)
                {
                    ImportInterfaces((InterfaceSymbol)typeSymbol);
                }
            }

            // Import members
            foreach (TypeSymbol typeSymbol in _importedTypes)
            {
                if (typeSymbol.IsCoreType)
                {
                    // already processed above
                    continue;
                }

                ImportMembers(typeSymbol);
            }

            return(_importedTypes);
        }
コード例 #2
0
ファイル: MetadataImporter.cs プロジェクト: puslmbps/dsharp
        private void ImportType(MetadataSource mdSource, TypeDefinition type, bool inScriptCoreAssembly, string scriptNamespace)
        {
            if (type.IsPublic == false)
            {
                return;
            }
            if (inScriptCoreAssembly && (MetadataHelpers.ShouldImportScriptCoreType(type) == false))
            {
                return;
            }

            string name          = type.Name;
            string namespaceName = type.Namespace;

            bool   dummy;
            string scriptName = MetadataHelpers.GetScriptName(type, out dummy, out dummy);

            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);
                    typeSymbol.SetTransformedName("Object");
                }
                else
                {
                    typeSymbol = new ClassSymbol(name, namespaceSymbol);

                    string extendee;
                    if (MetadataHelpers.IsScriptExtension(type, out extendee))
                    {
                        ((ClassSymbol)typeSymbol).SetExtenderClass(extendee);
                    }

                    if (String.CompareOrdinal(scriptName, "Array") == 0)
                    {
                        typeSymbol.SetArray();
                    }
                }
            }

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

                ScriptReference dependency = null;
                string          dependencyIdentifier;
                string          dependencyName = MetadataHelpers.GetScriptDependencyName(type, out dependencyIdentifier);
                if (dependencyName != null)
                {
                    dependency      = new ScriptReference(dependencyName, dependencyIdentifier);
                    scriptNamespace = dependency.Identifier;
                }

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

                bool ignoreNamespace = MetadataHelpers.ShouldIgnoreNamespace(type);
                if (ignoreNamespace || String.IsNullOrEmpty(scriptNamespace))
                {
                    typeSymbol.SetIgnoreNamespace();
                }
                else
                {
                    typeSymbol.ScriptNamespace = scriptNamespace;
                }
                typeSymbol.SetPublic();

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

                namespaceSymbol.AddType(typeSymbol);
                _importedTypes.Add(typeSymbol);
            }
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        private void ImportScriptAssembly(MetadataSource mdSource, string assemblyPath, bool coreAssembly)
        {
            string scriptNamespace = null;
            string scriptName = null;

            AssemblyDefinition assembly;
            if (coreAssembly) {
                assembly = mdSource.CoreAssemblyMetadata;
            }
            else {
                assembly = mdSource.GetMetadata(assemblyPath);
                scriptNamespace = MetadataHelpers.GetScriptNamespace(assembly);
            }

            scriptName = MetadataHelpers.GetScriptAssemblyName(assembly);
            if (String.IsNullOrEmpty(scriptName) == false) {
                _options.AddReferencedDependency(scriptName);
            }

            if (coreAssembly) {
                // Always add an execution reference to the core assembly, since
                // it contains things like the type system, and other APIs assumed by the compiler
                Debug.Assert(String.IsNullOrEmpty(scriptName) == false);
                _options.AddExecutionDependency(scriptName);
            }

            foreach (TypeDefinition type in assembly.MainModule.Types) {
                try {
                    if (MetadataHelpers.IsCompilerGeneratedType(type)) {
                        continue;
                    }

                    ImportType(mdSource, type, coreAssembly, scriptNamespace, scriptName);
                }
                catch (Exception e) {
                    Debug.Fail(e.ToString());
                }
            }
        }
コード例 #6
0
        private ICollection<TypeSymbol> ImportAssemblies(MetadataSource mdSource)
        {
            _importedTypes = new List<TypeSymbol>();

            ImportScriptAssembly(mdSource, mdSource.CoreAssemblyPath, /* coreAssembly */ true);

            foreach (TypeSymbol typeSymbol in _importedTypes) {
                if ((typeSymbol.Type == SymbolType.Class) &&
                    (typeSymbol.Name.Equals("Array", StringComparison.Ordinal))) {
                    // Array is special - it is used to build other Arrays of more
                    // specific types we load members for in the second pass...
                    ImportMembers(typeSymbol);
                }
            }

            foreach (TypeSymbol typeSymbol in _importedTypes) {
                if (typeSymbol.IsGeneric) {
                    // Generics are also special - they are used to build other generic instances
                    // with specific types for generic arguments as we load members for other
                    // types subsequently...
                    ImportMembers(typeSymbol);
                }
            }

            foreach (TypeSymbol typeSymbol in _importedTypes) {
                if ((typeSymbol.IsGeneric == false) &&
                    ((typeSymbol.Type != SymbolType.Class) ||
                     (typeSymbol.Name.Equals("Array", StringComparison.Ordinal) == false))) {
                    ImportMembers(typeSymbol);
                }

                // There is some special-case logic to be performed on some members of the
                // global namespace.

                if (typeSymbol.Type == SymbolType.Class) {
                    if (typeSymbol.Name.Equals("Script", StringComparison.Ordinal)) {
                        // The Script class contains additional pseudo global methods that cannot
                        // be referenced at compile-time by the app author, but can be
                        // referenced by generated code during compilation.
                        ImportPseudoMembers(PseudoClassMembers.Script, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Object", StringComparison.Ordinal)) {
                        // We need to add a static GetType method

                        ImportPseudoMembers(PseudoClassMembers.Object, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Type", StringComparison.Ordinal)) {
                        ImportPseudoMembers(PseudoClassMembers.Type, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Dictionary", StringComparison.Ordinal)) {
                        // The Dictionary class contains static methods at runtime, rather
                        // than instance methods.

                        ImportPseudoMembers(PseudoClassMembers.Dictionary, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("Arguments", StringComparison.Ordinal)) {
                        // We need to add a static indexer, which isn't allowed in C#

                        ImportPseudoMembers(PseudoClassMembers.Arguments, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals("String", StringComparison.Ordinal)) {
                        // We need to change generated names on Replace methods

                        ImportPseudoMembers(PseudoClassMembers.String, (ClassSymbol)typeSymbol);
                    }
                }
            }

            // Import all the types first.
            // Types need to be loaded upfront so that they can be used in resolving types associated
            // with members.
            foreach (string assemblyPath in mdSource.Assemblies) {
                ImportScriptAssembly(mdSource, assemblyPath, /* coreAssembly */ false);
            }

            // Resolve Base Types
            foreach (TypeSymbol typeSymbol in _importedTypes) {
                if (typeSymbol.Type == SymbolType.Class) {
                    ImportBaseType((ClassSymbol)typeSymbol);
                }
            }

            // Import members
            foreach (TypeSymbol typeSymbol in _importedTypes) {
                if (typeSymbol.IsCoreType) {
                    // already processed above
                    continue;
                }

                ImportMembers(typeSymbol);
            }

            return _importedTypes;
        }
コード例 #7
0
        public ICollection<TypeSymbol> ImportMetadata(ICollection<string> references, SymbolSet symbols)
        {
            Debug.Assert(references != null);
            Debug.Assert(symbols != null);

            _symbols = symbols;

            MetadataSource mdSource = new MetadataSource();
            bool hasLoadErrors = mdSource.LoadReferences(references, _errorHandler);

            ICollection<TypeSymbol> importedTypes = null;
            if (hasLoadErrors == false) {
                importedTypes = ImportAssemblies(mdSource);
            }

            if (_resolveError) {
                return null;
            }

            #if STATIC_ARRAY_EXTENSIONS
                // Update instance members that need to be generated as static methods
                ConvertInstanceMembersToStaticMembers();
            #endif // STATIC_ARRAY_EXTENSIONS

            return importedTypes;
        }