/// <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, Language language, bool isSubmission, IDictionary <SyntaxTree, int> ordinalMapBuilder, IDictionary <SyntaxTree, ImmutableArray <DeclarationLoadDirective> > loadDirectiveMapBuilder, IDictionary <string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary <SyntaxTree, Lazy <RootSingleDeclaration> > declMapBuilder, ref DeclarationTable declTable) { var sourceCodeKind = tree.Options.Kind; if (sourceCodeKind == SourceCodeKind.Script) { AppendAllLoadedSyntaxTrees(treesBuilder, tree, scriptClassName, resolver, language, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, ref declTable); } AddSyntaxTreeToDeclarationMapAndTable(tree, scriptClassName, isSubmission, declMapBuilder, ref declTable); treesBuilder.Add(tree); ordinalMapBuilder.Add(tree, ordinalMapBuilder.Count); }
private static void RemoveSyntaxTreeFromDeclarationMapAndTable( SyntaxTree tree, IDictionary <SyntaxTree, Lazy <RootSingleDeclaration> > 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 <RootSingleDeclaration> > declMapBuilder, ref DeclarationTable declTable) { var languageTree = (LanguageSyntaxTree)tree; var language = languageTree.Language; var lazyRoot = new Lazy <RootSingleDeclaration>(() => language.CompilationFactory.CreateDeclarationTree(languageTree, 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 <MergedDeclaration>( () => MergedDeclaration.Create(table._allOlderRootDeclarations.InInsertionOrder.AsImmutable <SingleDeclaration>())); 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 <RootSingleDeclaration>().SelectMany(r => r.ReferenceDirectives).AsImmutable()); }
public State( ImmutableArray <SyntaxTree> syntaxTrees, ImmutableDictionary <SyntaxTree, int> syntaxTreeOrdinalMap, ImmutableDictionary <SyntaxTree, ImmutableArray <DeclarationLoadDirective> > loadDirectiveMap, ImmutableDictionary <string, SyntaxTree> loadedSyntaxTreeMap, ImmutableDictionary <SyntaxTree, Lazy <RootSingleDeclaration> > 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 AppendAllLoadedSyntaxTrees( ArrayBuilder <SyntaxTree> treesBuilder, SyntaxTree tree, string scriptClassName, SourceReferenceResolver resolver, Language language, bool isSubmission, IDictionary <SyntaxTree, int> ordinalMapBuilder, IDictionary <SyntaxTree, ImmutableArray <DeclarationLoadDirective> > loadDirectiveMapBuilder, IDictionary <string, SyntaxTree> loadedSyntaxTreeMapBuilder, IDictionary <SyntaxTree, Lazy <RootSingleDeclaration> > declMapBuilder, ref DeclarationTable declTable) { ArrayBuilder <DeclarationLoadDirective> loadDirectives = null; foreach (var d in tree.GetCompilationUnitRoot().GetLoadDirectives()) { var directive = (LoadDirective)d.Directive; var node = (LanguageSyntaxNode)d; var path = directive.File; 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(diag => diag.Severity == DiagnosticSeverity.Error)); continue; } var diagnostics = DiagnosticBag.GetInstance(); string resolvedFilePath = null; if (resolver == null) { diagnostics.Add(InternalErrorCode.ERR_SourceFileReferencesNotSupported.ToDiagnosticInfo().ToDiagnostic(node.Location)); } else { resolvedFilePath = resolver.ResolveReference(path, baseFilePath: tree.FilePath); if (resolvedFilePath == null) { diagnostics.Add(InternalErrorCode.ERR_NoSourceFile.ToDiagnosticInfo(path).ToDiagnostic(node.Location)); } else if (!loadedSyntaxTreeMapBuilder.ContainsKey(resolvedFilePath)) { try { var code = resolver.ReadText(resolvedFilePath); var loadedTree = language.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, language, isSubmission, ordinalMapBuilder, loadDirectiveMapBuilder, loadedSyntaxTreeMapBuilder, declMapBuilder, ref declTable); } catch (Exception e) { diagnostics.Add(ModelErrorCode.ERR_FileReadError.ToDiagnosticInfo(resolvedFilePath, e).ToDiagnostic(node.Location)); } } 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 <DeclarationLoadDirective> .GetInstance(); } loadDirectives.Add(new DeclarationLoadDirective(resolvedFilePath, diagnostics.ToReadOnlyAndFree())); } if (loadDirectives != null) { loadDirectiveMapBuilder.Add(tree, loadDirectives.ToImmutableAndFree()); } }