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