Ejemplo n.º 1
0
        private ICollection <TypeSymbol> ImportAssemblies(string applicationAssemblyName, MetadataSource mdSource, string intermediaryAssembly = null)
        {
            importedTypes = new List <TypeSymbol>();
            var isApplicationAssembly = Path.GetFullPath(mdSource.CoreAssemblyPath) == intermediaryAssembly;

            ImportScriptAssembly(applicationAssemblyName, mdSource, mdSource.CoreAssemblyPath, coreAssembly: true, applicationAssembly: isApplicationAssembly);

            foreach (TypeSymbol typeSymbol in importedTypes)
            {
                if (typeSymbol.Type == SymbolType.Class &&
                    typeSymbol.Name.Equals(nameof(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(nameof(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(nameof(Object), StringComparison.Ordinal))
                    {
                        // We need to add a static GetType method

                        ImportPseudoMembers(PseudoClassMembers.Object, (ClassSymbol)typeSymbol);
                    }
                    else if (typeSymbol.Name.Equals(typeof(Dictionary <,>).Name, 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)
            {
                isApplicationAssembly = Path.GetFullPath(assemblyPath) == intermediaryAssembly;
                ImportScriptAssembly(applicationAssemblyName, mdSource, assemblyPath, coreAssembly: false, applicationAssembly: isApplicationAssembly);
            }

            // Resolve Base Types
            foreach (TypeSymbol typeSymbol in importedTypes)
            {
                if (typeSymbol is ClassSymbol classSymbol)
                {
                    ImportBaseType(classSymbol);
                    BuildInterfaceAssociations(classSymbol);
                }
                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);
            }

            foreach (TypeSymbol typeSymbol in importedTypes)
            {
                if (typeSymbol is ClassSymbol classSymbol && classSymbol.IsPublic)
                {
                    foreach (var method in GetExtensionMethods(typeSymbol.Members))
                    {
                        ParameterDefinition parameter = ((MethodDefinition)method.ParseContext).Parameters.First();
                        symbols.AddExtensionMethod(method, parameter.ParameterType.FullName, false);
                    }
                }
            }

            return(importedTypes);
        }