/// <summary> /// Appends all trees (including any trees from #load'ed files). /// </summary> private static void AppendAllSyntaxTrees( ArrayBuilder <SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, IDictionary <SyntaxTree, int> ordinalMapBuilder, IDictionary <SyntaxTree, ImmutableArray <LoadDirective> > loadDirectiveMapBuilder, IDictionary <string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary <SyntaxTree, Lazy <RootSingleNamespaceDeclaration> > declMapBuilder, ref DeclarationTable declTable) { var sourceCodeKind = tree.Options.Kind; if (sourceCodeKind == SourceCodeKind.Script) { AppendAllLoadedSyntaxTrees(treesBuilder, tree, scriptClassName, resolver, messageProvider, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, ref declTable); } AddSyntaxTreeToDeclarationMapAndTable(tree, scriptClassName, isSubmission, declMapBuilder, ref declTable); treesBuilder.Add(tree); ordinalMapBuilder.Add(tree, ordinalMapBuilder.Count); }
internal State( ImmutableArray <SyntaxTree> syntaxTrees, ImmutableDictionary <SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary <SyntaxTree, ImmutableArray <LoadDirective> > loadDirectiveMap, ImmutableDictionary <string, SyntaxTree> loadedSyntaxTreeMap, ImmutableDictionary < SyntaxTree, Lazy <RootSingleNamespaceDeclaration> > rootNamespaces, DeclarationTable declarationTable ) { Debug.Assert( syntaxTrees.All(tree => syntaxTrees[syntaxTreeOrdinalMap[tree]] == tree) ); Debug.Assert( syntaxTrees.SetEquals( rootNamespaces.Keys.AsImmutable(), EqualityComparer <SyntaxTree> .Default ) ); this.SyntaxTrees = syntaxTrees; this.OrdinalMap = syntaxTreeOrdinalMap; this.LoadDirectiveMap = loadDirectiveMap; this.LoadedSyntaxTreeMap = loadedSyntaxTreeMap; this.RootNamespaces = rootNamespaces; this.DeclarationTable = declarationTable; }
private static void RemoveSyntaxTreeFromDeclarationMapAndTable( SyntaxTree tree, IDictionary <SyntaxTree, Lazy <RootSingleNamespaceDeclaration> > declMap, ref DeclarationTable declTable) { var lazyRoot = declMap[tree]; declTable = declTable.RemoveRootDeclaration(lazyRoot); declMap.Remove(tree); }
private static void AddSyntaxTreeToDeclarationMapAndTable( SyntaxTree tree, string scriptClassName, bool isSubmission, IDictionary <SyntaxTree, Lazy <RootSingleNamespaceDeclaration> > declMapBuilder, ref DeclarationTable declTable) { var lazyRoot = new Lazy <RootSingleNamespaceDeclaration>(() => DeclarationTreeBuilder.ForTree(tree, scriptClassName, isSubmission)); declMapBuilder.Add(tree, lazyRoot); // Callers are responsible for checking for existing entries. declTable = declTable.AddRootDeclaration(lazyRoot); }
public Cache(DeclarationTable table) { this.MergedRoot = new Lazy<MergedNamespaceDeclaration>( () => MergedNamespaceDeclaration.Create(table._allOlderRootDeclarations.InInsertionOrder.AsImmutable<SingleNamespaceDeclaration>())); this.TypeNames = new Lazy<ISet<string>>( () => GetTypeNames(this.MergedRoot.Value)); this.NamespaceNames = new Lazy<ISet<string>>( () => GetNamespaceNames(this.MergedRoot.Value)); this.ReferenceDirectives = new Lazy<ImmutableArray<ReferenceDirective>>( () => MergedRoot.Value.Declarations.OfType<RootSingleNamespaceDeclaration>().SelectMany(r => r.ReferenceDirectives).AsImmutable()); }
public Cache(DeclarationTable table) { this.MergedRoot = new Lazy <MergedNamespaceDeclaration>( () => MergedNamespaceDeclaration.Create(table._allOlderRootDeclarations.InInsertionOrder.AsImmutable <SingleNamespaceDeclaration>())); this.TypeNames = new Lazy <ISet <string> >( () => GetTypeNames(this.MergedRoot.Value)); this.NamespaceNames = new Lazy <ISet <string> >( () => GetNamespaceNames(this.MergedRoot.Value)); this.ReferenceDirectives = new Lazy <ImmutableArray <ReferenceDirective> >( () => MergedRoot.Value.Declarations.OfType <RootSingleNamespaceDeclaration>().SelectMany(r => r.ReferenceDirectives).AsImmutable()); }
internal State( ImmutableArray<SyntaxTree> syntaxTrees, ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMap, ImmutableDictionary<string, SyntaxTree> loadedSyntaxTreeMap, ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> rootNamespaces, DeclarationTable declarationTable) { Debug.Assert(syntaxTrees.All(tree => syntaxTrees[syntaxTreeOrdinalMap[tree]] == tree)); Debug.Assert(syntaxTrees.SetEquals(rootNamespaces.Keys.AsImmutable(), EqualityComparer<SyntaxTree>.Default)); this.SyntaxTrees = syntaxTrees; this.OrdinalMap = syntaxTreeOrdinalMap; this.LoadDirectiveMap = loadDirectiveMap; this.LoadedSyntaxTreeMap = loadedSyntaxTreeMap; this.RootNamespaces = rootNamespaces; this.DeclarationTable = declarationTable; }
private static void RemoveSyntaxTreeFromDeclarationMapAndTable( SyntaxTree tree, ref ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMap, ref DeclarationTable declTable, ref bool referenceDirectivesChanged) { Lazy<RootSingleNamespaceDeclaration> lazyRoot; if (!declMap.TryGetValue(tree, out lazyRoot)) { throw new ArgumentException(string.Format(CSharpResources.SyntaxTreeNotFoundTo, tree), "trees"); } declTable = declTable.RemoveRootDeclaration(lazyRoot); declMap = declMap.Remove(tree); referenceDirectivesChanged = referenceDirectivesChanged || tree.HasReferenceDirectives(); }
private CSharpCompilation UpdateSyntaxTrees( ImmutableArray<SyntaxTree> syntaxTrees, ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> rootNamespaces, DeclarationTable declarationTable, bool referenceDirectivesChanged) { return new CSharpCompilation( this.AssemblyName, this.options, this.ExternalReferences, syntaxTrees, syntaxTreeOrdinalMap, rootNamespaces, declarationTable, this.previousSubmission, this.SubmissionReturnType, this.HostObjectType, this.IsSubmission, this.referenceManager, reuseReferenceManager: !referenceDirectivesChanged); }
private static void AddSyntaxTreeToDeclarationMapAndTable( SyntaxTree tree, CSharpCompilationOptions options, bool isSubmission, ref ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMap, ref DeclarationTable declTable, ref bool referenceDirectivesChanged) { var lazyRoot = new Lazy<RootSingleNamespaceDeclaration>(() => DeclarationTreeBuilder.ForTree(tree, options.ScriptClassName ?? "", isSubmission)); declMap = declMap.SetItem(tree, lazyRoot); declTable = declTable.AddRootDeclaration(lazyRoot); referenceDirectivesChanged = referenceDirectivesChanged || tree.HasReferenceDirectives(); }
private static void RemoveSyntaxTreeFromDeclarationMapAndTable( SyntaxTree tree, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMap, ref DeclarationTable declTable) { var lazyRoot = declMap[tree]; declTable = declTable.RemoveRootDeclaration(lazyRoot); declMap.Remove(tree); }
private CSharpCompilation( string assemblyName, CSharpCompilationOptions options, ImmutableArray<MetadataReference> references, ImmutableArray<SyntaxTree> syntaxTrees, ImmutableDictionary<SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> rootNamespaces, DeclarationTable declarationTable, CSharpCompilation previousSubmission, Type submissionReturnType, Type hostObjectType, bool isSubmission, ReferenceManager referenceManager, bool reuseReferenceManager, AsyncQueue<CompilationEvent> eventQueue = null) : base(assemblyName, references, submissionReturnType, hostObjectType, isSubmission, syntaxTreeOrdinalMap, eventQueue) { using (Logger.LogBlock(FunctionId.CSharp_Compilation_Create, message: assemblyName)) { this.wellKnownMemberSignatureComparer = new WellKnownMembersSignatureComparer(this); this.options = options; this.syntaxTrees = syntaxTrees; this.rootNamespaces = rootNamespaces; this.declarationTable = declarationTable; Debug.Assert(syntaxTrees.All(tree => syntaxTrees[syntaxTreeOrdinalMap[tree]] == tree)); Debug.Assert(syntaxTrees.SetEquals(rootNamespaces.Keys.AsImmutable(), EqualityComparer<SyntaxTree>.Default)); this.builtInOperators = new BuiltInOperators(this); this.scriptClass = new Lazy<ImplicitNamedTypeSymbol>(BindScriptClass); this.globalImports = new Lazy<Imports>(BindGlobalUsings); this.globalNamespaceAlias = new Lazy<AliasSymbol>(CreateGlobalNamespaceAlias); this.anonymousTypeManager = new AnonymousTypeManager(this); if (isSubmission) { Debug.Assert(previousSubmission == null || previousSubmission.HostObjectType == hostObjectType); this.previousSubmission = previousSubmission; } else { Debug.Assert(previousSubmission == null && submissionReturnType == null && hostObjectType == null); } if (reuseReferenceManager) { referenceManager.AssertCanReuseForCompilation(this); this.referenceManager = referenceManager; } else { this.referenceManager = new ReferenceManager( MakeSourceAssemblySimpleName(), options.AssemblyIdentityComparer, (referenceManager != null) ? referenceManager.ObservedMetadata : null); } Debug.Assert((object)this.lazyAssemblySymbol == null); if (EventQueue != null) EventQueue.Enqueue(new CompilationStartedEvent(this)); } }
private static void AddSyntaxTreeToDeclarationMapAndTable( SyntaxTree tree, string scriptClassName, bool isSubmission, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMapBuilder, ref DeclarationTable declTable) { var lazyRoot = new Lazy<RootSingleNamespaceDeclaration>(() => DeclarationTreeBuilder.ForTree(tree, scriptClassName, isSubmission)); declMapBuilder.Add(tree, lazyRoot); // Callers are responsible for checking for existing entries. declTable = declTable.AddRootDeclaration(lazyRoot); }
private static void AppendAllLoadedSyntaxTrees( ArrayBuilder<SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, IDictionary<SyntaxTree, int> ordinalMapBuilder, IDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMapBuilder, IDictionary<string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMapBuilder, ref DeclarationTable declTable) { ArrayBuilder<LoadDirective> loadDirectives = null; foreach (var directive in tree.GetCompilationUnitRoot().GetLoadDirectives()) { var fileToken = directive.File; var path = (string)fileToken.Value; if (path == null) { // If there is no path, the parser should have some Diagnostics to report (if we're in an active region). Debug.Assert(!directive.IsActive || tree.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error)); continue; } var diagnostics = DiagnosticBag.GetInstance(); string resolvedFilePath = null; if (resolver == null) { diagnostics.Add( messageProvider.CreateDiagnostic( (int)ErrorCode.ERR_SourceFileReferencesNotSupported, directive.Location)); } else { resolvedFilePath = resolver.ResolveReference(path, baseFilePath: tree.FilePath); if (resolvedFilePath == null) { diagnostics.Add( messageProvider.CreateDiagnostic( (int)ErrorCode.ERR_NoSourceFile, fileToken.GetLocation(), path, CSharpResources.CouldNotFindFile)); } else if (!loadedSyntaxTreeMapBuilder.ContainsKey(resolvedFilePath)) { try { var code = resolver.ReadText(resolvedFilePath); var loadedTree = SyntaxFactory.ParseSyntaxTree( code, tree.Options, // Use ParseOptions propagated from "external" tree. resolvedFilePath); // All #load'ed trees should have unique path information. loadedSyntaxTreeMapBuilder.Add(loadedTree.FilePath, loadedTree); AppendAllSyntaxTrees( treesBuilder, loadedTree, scriptClassName, resolver, messageProvider, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, ref declTable); } catch (Exception e) { diagnostics.Add( CommonCompiler.ToFileReadDiagnostics(messageProvider, e, resolvedFilePath), fileToken.GetLocation()); } } else { // The path resolved, but we've seen this file before, // so don't attempt to load it again. Debug.Assert(diagnostics.IsEmptyWithoutResolution); } } if (loadDirectives == null) { loadDirectives = ArrayBuilder<LoadDirective>.GetInstance(); } loadDirectives.Add(new LoadDirective(resolvedFilePath, diagnostics.ToReadOnlyAndFree())); } if (loadDirectives != null) { loadDirectiveMapBuilder.Add(tree, loadDirectives.ToImmutableAndFree()); } }
/// <summary> /// Appends all trees (including any trees from #load'ed files). /// </summary> private static void AppendAllSyntaxTrees( ArrayBuilder<SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, IDictionary<SyntaxTree, int> ordinalMapBuilder, IDictionary<SyntaxTree, ImmutableArray<LoadDirective>> loadDirectiveMapBuilder, IDictionary<string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary<SyntaxTree, Lazy<RootSingleNamespaceDeclaration>> declMapBuilder, ref DeclarationTable declTable) { var sourceCodeKind = tree.Options.Kind; if (sourceCodeKind == SourceCodeKind.Script) { AppendAllLoadedSyntaxTrees(treesBuilder, tree, scriptClassName, resolver, messageProvider, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, ref declTable); } AddSyntaxTreeToDeclarationMapAndTable(tree, scriptClassName, isSubmission, declMapBuilder, ref declTable); treesBuilder.Add(tree); ordinalMapBuilder.Add(tree, ordinalMapBuilder.Count); }
public Cache(DeclarationTable table) { _table = table; }
private static void AppendAllLoadedSyntaxTrees( ArrayBuilder <SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, CommonMessageProvider messageProvider, bool isSubmission, IDictionary <SyntaxTree, int> ordinalMapBuilder, IDictionary <SyntaxTree, ImmutableArray <LoadDirective> > loadDirectiveMapBuilder, IDictionary <string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary <SyntaxTree, Lazy <RootSingleNamespaceDeclaration> > declMapBuilder, ref DeclarationTable declTable) { ArrayBuilder <LoadDirective> loadDirectives = null; foreach (var directive in tree.GetCompilationUnitRoot().GetLoadDirectives()) { var fileToken = directive.File; var path = (string)fileToken.Value; if (path == null) { // If there is no path, the parser should have some Diagnostics to report (if we're in an active region). Debug.Assert(!directive.IsActive || tree.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error)); continue; } var diagnostics = DiagnosticBag.GetInstance(); string resolvedFilePath = null; if (resolver == null) { diagnostics.Add( messageProvider.CreateDiagnostic( (int)ErrorCode.ERR_SourceFileReferencesNotSupported, directive.Location)); } else { resolvedFilePath = resolver.ResolveReference(path, baseFilePath: tree.FilePath); if (resolvedFilePath == null) { diagnostics.Add( messageProvider.CreateDiagnostic( (int)ErrorCode.ERR_NoSourceFile, fileToken.GetLocation(), path, CSharpResources.CouldNotFindFile)); } else if (!loadedSyntaxTreeMapBuilder.ContainsKey(resolvedFilePath)) { try { var code = resolver.ReadText(resolvedFilePath); var loadedTree = SyntaxFactory.ParseSyntaxTree( code, tree.Options, // Use ParseOptions propagated from "external" tree. resolvedFilePath); // All #load'ed trees should have unique path information. loadedSyntaxTreeMapBuilder.Add(loadedTree.FilePath, loadedTree); AppendAllSyntaxTrees( treesBuilder, loadedTree, scriptClassName, resolver, messageProvider, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, ref declTable); } catch (Exception e) { diagnostics.Add( CommonCompiler.ToFileReadDiagnostics(messageProvider, e, resolvedFilePath), fileToken.GetLocation()); } } else { // The path resolved, but we've seen this file before, // so don't attempt to load it again. Debug.Assert(diagnostics.IsEmptyWithoutResolution); } } if (loadDirectives == null) { loadDirectives = ArrayBuilder <LoadDirective> .GetInstance(); } loadDirectives.Add(new LoadDirective(resolvedFilePath, diagnostics.ToReadOnlyAndFree())); } if (loadDirectives != null) { loadDirectiveMapBuilder.Add(tree, loadDirectives.ToImmutableAndFree()); } }