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