diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs
index 3ccc91692fde1..af03e0d23f713 100644
--- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.cs
@@ -34,7 +34,8 @@ public void DiagnosticAnalyzerAllInOne()
             missingSyntaxKinds.Add(SyntaxKind.FunctionPointerType);
 
             var analyzer = new CSharpTrackingDiagnosticAnalyzer();
-            CreateCompilationWithMscorlib45(source).VerifyAnalyzerDiagnostics(new[] { analyzer });
+            var options = new AnalyzerOptions(new[] { new TestAdditionalText() }.ToImmutableArray<AdditionalText>());
+            CreateCompilationWithMscorlib45(source).VerifyAnalyzerDiagnostics(new[] { analyzer }, options);
             analyzer.VerifyAllAnalyzerMembersWereCalled();
             analyzer.VerifyAnalyzeSymbolCalledForAllSymbolKinds();
             analyzer.VerifyAnalyzeNodeCalledForAllSyntaxKinds(missingSyntaxKinds);
diff --git a/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.vb b/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.vb
index afbe014eabcac..d246cc377540d 100644
--- a/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.vb
+++ b/src/Compilers/VisualBasic/Test/Semantic/Diagnostics/DiagnosticAnalyzerTests.AllInOne.vb
@@ -19,7 +19,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics
         Public Sub DiagnosticAnalyzerAllInOne()
             Dim source = TestResource.AllInOneVisualBasicBaseline
             Dim analyzer = New BasicTrackingDiagnosticAnalyzer()
-            CreateCompilationWithMscorlib40({source}).VerifyAnalyzerDiagnostics({analyzer})
+            Dim options = New AnalyzerOptions({DirectCast(New TestAdditionalText(), AdditionalText)}.ToImmutableArray())
+            CreateCompilationWithMscorlib40({source}).VerifyAnalyzerDiagnostics({analyzer}, options)
             analyzer.VerifyAllAnalyzerMembersWereCalled()
             analyzer.VerifyAnalyzeSymbolCalledForAllSymbolKinds()
             analyzer.VerifyAnalyzeNodeCalledForAllSyntaxKinds(New HashSet(Of SyntaxKind)())
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
index 691120f393770..c779d57265197 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs
@@ -50,7 +50,9 @@ public async Task DiagnosticAnalyzerDriverAllInOne()
             using var workspace = TestWorkspace.CreateCSharp(source, TestOptions.Regular);
 
             var analyzerReference = new AnalyzerImageReference(ImmutableArray.Create<DiagnosticAnalyzer>(analyzer));
-            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));
+            var newSolution = workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference })
+                .Projects.Single().AddAdditionalDocument(name: "dummy.txt", text: "", filePath: "dummy.txt").Project.Solution;
+            workspace.TryApplyChanges(newSolution);
 
             var document = workspace.CurrentSolution.Projects.Single().Documents.Single();
             AccessSupportedDiagnostics(analyzer);
diff --git a/src/EditorFeatures/Core/Shared/Preview/PreviewSolutionCrawlerRegistrationService.cs b/src/EditorFeatures/Core/Shared/Preview/PreviewSolutionCrawlerRegistrationService.cs
index 8ae114b651574..d41db3f891a5a 100644
--- a/src/EditorFeatures/Core/Shared/Preview/PreviewSolutionCrawlerRegistrationService.cs
+++ b/src/EditorFeatures/Core/Shared/Preview/PreviewSolutionCrawlerRegistrationService.cs
@@ -10,6 +10,7 @@
 using Microsoft.CodeAnalysis.Diagnostics;
 using Microsoft.CodeAnalysis.Host;
 using Microsoft.CodeAnalysis.Host.Mef;
+using Microsoft.CodeAnalysis.Shared.Extensions;
 using Microsoft.CodeAnalysis.Shared.TestHooks;
 using Microsoft.CodeAnalysis.SolutionCrawler;
 using Roslyn.Utilities;
@@ -73,7 +74,7 @@ public void Register(Workspace workspace)
             private async Task AnalyzeAsync()
             {
                 var workerBackOffTimeSpanInMS = _workspace.Options.GetOption(InternalSolutionCrawlerOptions.PreviewBackOffTimeSpanInMS);
-                var diagnosticAnalyzer = _owner._analyzerService.CreateIncrementalAnalyzer(_workspace);
+                var incrementalAnalyzer = _owner._analyzerService.CreateIncrementalAnalyzer(_workspace);
 
                 var solution = _workspace.CurrentSolution;
                 var documentIds = _workspace.GetOpenDocumentIds().ToImmutableArray();
@@ -82,8 +83,8 @@ private async Task AnalyzeAsync()
                 {
                     foreach (var documentId in documentIds)
                     {
-                        var document = solution.GetDocument(documentId);
-                        if (document == null)
+                        var textDocument = solution.GetTextDocument(documentId);
+                        if (textDocument == null)
                         {
                             continue;
                         }
@@ -92,8 +93,15 @@ private async Task AnalyzeAsync()
                         await Task.Delay(workerBackOffTimeSpanInMS, _source.Token).ConfigureAwait(false);
 
                         // do actual analysis
-                        await diagnosticAnalyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, _source.Token).ConfigureAwait(false);
-                        await diagnosticAnalyzer.AnalyzeDocumentAsync(document, bodyOpt: null, reasons: InvocationReasons.Empty, cancellationToken: _source.Token).ConfigureAwait(false);
+                        if (textDocument is Document document)
+                        {
+                            await incrementalAnalyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, _source.Token).ConfigureAwait(false);
+                            await incrementalAnalyzer.AnalyzeDocumentAsync(document, bodyOpt: null, reasons: InvocationReasons.Empty, cancellationToken: _source.Token).ConfigureAwait(false);
+                        }
+                        else if (incrementalAnalyzer is IIncrementalAnalyzer2 incrementalAnalyzer2)
+                        {
+                            await incrementalAnalyzer2.AnalyzeNonSourceDocumentAsync(textDocument, InvocationReasons.Empty, _source.Token).ConfigureAwait(false);
+                        }
 
                         // don't call project one.
                     }
diff --git a/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs b/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs
index 28e04485a4286..1b4bac408eed9 100644
--- a/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs
+++ b/src/EditorFeatures/Test/Diagnostics/DiagnosticAnalyzerServiceTests.cs
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Collections.Immutable;
 using System.Linq;
@@ -564,6 +565,105 @@ private async Task TestFullSolutionAnalysisForProjectAsync(Project project, bool
             Assert.Equal(expectAnalyzerExecuted, called);
         }
 
+        [Theory, CombinatorialData]
+        internal async Task TestAdditionalFileAnalyzer(bool registerFromInitialize, bool testMultiple, BackgroundAnalysisScope analysisScope)
+        {
+            using var workspace = new AdhocWorkspace();
+            var options = workspace.Options.WithChangedOption(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp, analysisScope);
+            workspace.SetOptions(options);
+
+            var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "CSharpProject", "CSharpProject", LanguageNames.CSharp);
+            var project = workspace.AddProject(projectInfo);
+
+            var diagnosticSpan = new TextSpan(2, 2);
+            var analyzer = new AdditionalFileAnalyzer(registerFromInitialize, diagnosticSpan, id: "ID0001");
+            var analyzers = ImmutableArray.Create<DiagnosticAnalyzer>(analyzer);
+            if (testMultiple)
+            {
+                analyzer = new AdditionalFileAnalyzer2(registerFromInitialize, diagnosticSpan, id: "ID0002");
+                analyzers = analyzers.Add(analyzer);
+            }
+
+            var analyzerReference = new AnalyzerImageReference(analyzers);
+            project = project.WithAnalyzerReferences(new[] { analyzerReference })
+                .AddAdditionalDocument(name: "dummy.txt", text: "Additional File Text", filePath: "dummy.txt").Project;
+            if (testMultiple)
+            {
+                project = project.AddAdditionalDocument(name: "dummy2.txt", text: "Additional File2 Text", filePath: "dummy2.txt").Project;
+            }
+
+            var applied = workspace.TryApplyChanges(project.Solution);
+            Assert.True(applied);
+
+            // create listener/service/analyzer
+            var listener = new AsynchronousOperationListener();
+            var service = new MyDiagnosticAnalyzerService(listener);
+
+            var diagnostics = new ConcurrentSet<DiagnosticData>();
+            service.DiagnosticsUpdated += (s, e) =>
+            {
+                diagnostics.AddRange(e.Diagnostics);
+            };
+
+            var incrementalAnalyzer = (DiagnosticIncrementalAnalyzer)service.CreateIncrementalAnalyzer(workspace);
+            var firstAdditionalDocument = project.AdditionalDocuments.FirstOrDefault();
+
+            switch (analysisScope)
+            {
+                case BackgroundAnalysisScope.ActiveFile:
+                case BackgroundAnalysisScope.OpenFilesAndProjects:
+                    workspace.OpenAdditionalDocument(firstAdditionalDocument.Id);
+                    await incrementalAnalyzer.AnalyzeNonSourceDocumentAsync(firstAdditionalDocument, InvocationReasons.SyntaxChanged, CancellationToken.None);
+                    break;
+
+                case BackgroundAnalysisScope.FullSolution:
+                    await incrementalAnalyzer.AnalyzeProjectAsync(project, semanticsChanged: true, InvocationReasons.Reanalyze, CancellationToken.None);
+                    break;
+
+                default:
+                    throw ExceptionUtilities.UnexpectedValue(analysisScope);
+            }
+
+            await listener.ExpeditedWaitAsync();
+
+            var expectedCount = !testMultiple
+                ? 1
+                : analysisScope == BackgroundAnalysisScope.FullSolution ? 4 : 2;
+            Assert.Equal(expectedCount, diagnostics.Count);
+
+            for (var i = 0; i < analyzers.Length; i++)
+            {
+                analyzer = (AdditionalFileAnalyzer)analyzers[i];
+                foreach (var additionalDoc in project.AdditionalDocuments)
+                {
+                    var applicableDiagnostics = diagnostics.Where(
+                        d => d.Id == analyzer.Descriptor.Id && d.DataLocation.OriginalFilePath == additionalDoc.FilePath);
+
+                    if (analysisScope != BackgroundAnalysisScope.FullSolution &&
+                        firstAdditionalDocument != additionalDoc)
+                    {
+                        Assert.Empty(applicableDiagnostics);
+                    }
+                    else
+                    {
+                        var diagnostic = Assert.Single(applicableDiagnostics);
+                        Assert.Equal(diagnosticSpan, diagnostic.GetTextSpan());
+                        diagnostics.Remove(diagnostic);
+                    }
+                }
+            }
+
+            Assert.Empty(diagnostics);
+        }
+
+        private class AdditionalFileAnalyzer2 : AdditionalFileAnalyzer
+        {
+            public AdditionalFileAnalyzer2(bool registerFromInitialize, TextSpan diagnosticSpan, string id)
+                : base(registerFromInitialize, diagnosticSpan, id)
+            {
+            }
+        }
+
         [Theory, CombinatorialData]
         internal async Task TestDiagnosticSuppressor(bool includeAnalyzer, bool includeSuppressor, BackgroundAnalysisScope analysisScope)
         {
@@ -678,11 +778,19 @@ private static (bool, bool) CompilerAnalyzerResultSetter(bool syntax, bool seman
             return (syntax, semantic);
         }
 
-        private static async Task RunAllAnalysisAsync(IIncrementalAnalyzer analyzer, Document document)
+        private static async Task RunAllAnalysisAsync(IIncrementalAnalyzer analyzer, TextDocument textDocument)
         {
-            await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None).ConfigureAwait(false);
-            await analyzer.AnalyzeDocumentAsync(document, bodyOpt: null, reasons: InvocationReasons.Empty, cancellationToken: CancellationToken.None).ConfigureAwait(false);
-            await analyzer.AnalyzeProjectAsync(document.Project, semanticsChanged: true, reasons: InvocationReasons.Empty, cancellationToken: CancellationToken.None).ConfigureAwait(false);
+            if (textDocument is Document document)
+            {
+                await analyzer.AnalyzeSyntaxAsync(document, InvocationReasons.Empty, CancellationToken.None).ConfigureAwait(false);
+                await analyzer.AnalyzeDocumentAsync(document, bodyOpt: null, reasons: InvocationReasons.Empty, cancellationToken: CancellationToken.None).ConfigureAwait(false);
+            }
+            else if (analyzer is IIncrementalAnalyzer2 analyzer2)
+            {
+                await analyzer2.AnalyzeNonSourceDocumentAsync(textDocument, InvocationReasons.Empty, CancellationToken.None).ConfigureAwait(false);
+            }
+
+            await analyzer.AnalyzeProjectAsync(textDocument.Project, semanticsChanged: true, reasons: InvocationReasons.Empty, cancellationToken: CancellationToken.None).ConfigureAwait(false);
         }
 
         private class MyDiagnosticAnalyzerService : DiagnosticAnalyzerService
diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs
index 28e91578978c7..47af60fbe9bd4 100644
--- a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs
+++ b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs
@@ -307,8 +307,7 @@ protected override void ApplyDocumentAdded(DocumentInfo info, SourceText text)
             var hostProject = this.GetTestProject(info.Id.ProjectId);
             var hostDocument = new TestHostDocument(
                 text.ToString(), info.Name, info.SourceCodeKind,
-                info.Id, folders: info.Folders,
-                exportProvider: ExportProvider);
+                info.Id, folders: info.Folders, exportProvider: ExportProvider);
             hostProject.AddDocument(hostDocument);
             this.OnDocumentAdded(hostDocument.ToDocumentInfo());
         }
@@ -330,7 +329,7 @@ protected override void ApplyAdditionalDocumentTextChanged(DocumentId document,
         protected override void ApplyAdditionalDocumentAdded(DocumentInfo info, SourceText text)
         {
             var hostProject = this.GetTestProject(info.Id.ProjectId);
-            var hostDocument = new TestHostDocument(text.ToString(), info.Name, id: info.Id);
+            var hostDocument = new TestHostDocument(text.ToString(), info.Name, id: info.Id, exportProvider: ExportProvider);
             hostProject.AddAdditionalDocument(hostDocument);
             this.OnAdditionalDocumentAdded(hostDocument.ToDocumentInfo());
         }
@@ -352,7 +351,7 @@ protected override void ApplyAnalyzerConfigDocumentTextChanged(DocumentId docume
         protected override void ApplyAnalyzerConfigDocumentAdded(DocumentInfo info, SourceText text)
         {
             var hostProject = this.GetTestProject(info.Id.ProjectId);
-            var hostDocument = new TestHostDocument(text.ToString(), info.Name, id: info.Id, filePath: info.FilePath, folders: info.Folders);
+            var hostDocument = new TestHostDocument(text.ToString(), info.Name, id: info.Id, filePath: info.FilePath, folders: info.Folders, exportProvider: ExportProvider);
             hostProject.AddAnalyzerConfigDocument(hostDocument);
             this.OnAnalyzerConfigDocumentAdded(hostDocument.ToDocumentInfo());
         }
diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb
index 7dbf5e70b41b8..a218a6b30ac51 100644
--- a/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb
+++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.vb
@@ -17,7 +17,9 @@ Public Class DiagnosticAnalyzerDriverTests
         Dim analyzer = New BasicTrackingDiagnosticAnalyzer()
         Using workspace = TestWorkspace.CreateVisualBasic(source)
             Dim analyzerReference = New AnalyzerImageReference(ImmutableArray.Create(Of DiagnosticAnalyzer)(analyzer))
-            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}))
+            Dim newSolution = workspace.CurrentSolution.WithAnalyzerReferences({analyzerReference}).
+                Projects.Single().AddAdditionalDocument(name:="dummy.txt", text:="", filePath:="dummy.txt").Project.Solution
+            workspace.TryApplyChanges(newSolution)
 
             Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single()
             AccessSupportedDiagnostics(analyzer)
diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs
index c7237894f9ede..1dd1b7d98dcf8 100644
--- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs
+++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs
@@ -303,19 +303,22 @@ private static void AssertCompilation(Project project, Compilation compilation1)
         /// </summary>
         public static async Task<IEnumerable<DiagnosticData>> ComputeDiagnosticsAsync(
             DiagnosticAnalyzer analyzer,
-            Document document,
+            TextDocument textDocument,
             AnalysisKind kind,
             DiagnosticAnalyzerInfoCache analyzerInfoCache,
             CompilationWithAnalyzers? compilationWithAnalyzers,
             TextSpan? span,
             CancellationToken cancellationToken)
         {
-            var loadDiagnostic = await document.State.GetLoadDiagnosticAsync(cancellationToken).ConfigureAwait(false);
+            var document = textDocument as Document;
+            RoslynDebug.Assert(document != null || kind == AnalysisKind.Syntax, "We only support syntactic analysis for non-source documents");
+
+            var loadDiagnostic = await textDocument.State.GetLoadDiagnosticAsync(cancellationToken).ConfigureAwait(false);
 
             if (analyzer == FileContentLoadAnalyzer.Instance)
             {
                 return loadDiagnostic != null ?
-                    SpecializedCollections.SingletonEnumerable(DiagnosticData.Create(loadDiagnostic, document)) :
+                    SpecializedCollections.SingletonEnumerable(DiagnosticData.Create(loadDiagnostic, textDocument)) :
                     SpecializedCollections.EmptyEnumerable<DiagnosticData>();
             }
 
@@ -324,9 +327,11 @@ public static async Task<IEnumerable<DiagnosticData>> ComputeDiagnosticsAsync(
                 return SpecializedCollections.EmptyEnumerable<DiagnosticData>();
             }
 
-            if (analyzer is DocumentDiagnosticAnalyzer documentAnalyzer)
+            ImmutableArray<Diagnostic> diagnostics;
+            if (document != null &&
+                analyzer is DocumentDiagnosticAnalyzer documentAnalyzer)
             {
-                var diagnostics = await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(
+                diagnostics = await ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(
                     documentAnalyzer, document, kind, compilationWithAnalyzers?.Compilation, cancellationToken).ConfigureAwait(false);
 
                 return diagnostics.ConvertToLocalDiagnostics(document);
@@ -338,14 +343,14 @@ public static async Task<IEnumerable<DiagnosticData>> ComputeDiagnosticsAsync(
                 if (kind == AnalysisKind.Syntax)
                 {
                     Logger.Log(FunctionId.Diagnostics_SyntaxDiagnostic,
-                        (r, d, a, k) => $"Driver: {r != null}, {d.Id}, {d.Project.Id}, {a}, {k}", compilationWithAnalyzers, document, analyzer, kind);
+                        (r, d, a, k) => $"Driver: {r != null}, {d.Id}, {d.Project.Id}, {a}, {k}", compilationWithAnalyzers, textDocument, analyzer, kind);
                 }
 
                 return SpecializedCollections.EmptyEnumerable<DiagnosticData>();
             }
 
             // if project is not loaded successfully then, we disable semantic errors for compiler analyzers
-            if (kind != AnalysisKind.Syntax && analyzer.IsCompilerAnalyzer())
+            if (kind != AnalysisKind.Syntax && analyzer.IsCompilerAnalyzer() && document != null)
             {
                 var isEnabled = await document.Project.HasSuccessfullyLoadedAsync(cancellationToken).ConfigureAwait(false);
 
@@ -359,52 +364,61 @@ public static async Task<IEnumerable<DiagnosticData>> ComputeDiagnosticsAsync(
 
             // REVIEW: more unnecessary allocations just to get diagnostics per analyzer
             var singleAnalyzer = ImmutableArray.Create(analyzer);
-            var skippedAnalyzerInfo = document.Project.GetSkippedAnalyzersInfo(analyzerInfoCache);
+            var skippedAnalyzerInfo = textDocument.Project.GetSkippedAnalyzersInfo(analyzerInfoCache);
             ImmutableArray<string> filteredIds;
 
             switch (kind)
             {
                 case AnalysisKind.Syntax:
-                    var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
-                    if (tree == null)
+                    if (document != null)
                     {
-                        return SpecializedCollections.EmptyEnumerable<DiagnosticData>();
-                    }
-
-                    var diagnostics = await compilationWithAnalyzers.GetAnalyzerSyntaxDiagnosticsAsync(tree, singleAnalyzer, cancellationToken).ConfigureAwait(false);
+                        var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
+                        if (tree == null)
+                        {
+                            return SpecializedCollections.EmptyEnumerable<DiagnosticData>();
+                        }
 
-                    if (diagnostics.IsDefaultOrEmpty)
-                    {
-                        Logger.Log(FunctionId.Diagnostics_SyntaxDiagnostic, (d, a, t) => $"{d.Id}, {d.Project.Id}, {a}, {t.Length}", document, analyzer, tree);
+                        diagnostics = await compilationWithAnalyzers.GetAnalyzerSyntaxDiagnosticsAsync(tree, singleAnalyzer, cancellationToken).ConfigureAwait(false);
                     }
-                    else if (skippedAnalyzerInfo.FilteredDiagnosticIdsForAnalyzers.TryGetValue(analyzer, out filteredIds))
+                    else
                     {
-                        diagnostics = diagnostics.Filter(filteredIds);
-                    }
+                        // Currently, we only support analysis for additional documents. In future, we may support analyzer config documents.
+                        if (textDocument.Kind == TextDocumentKind.AdditionalDocument)
+                        {
+                            var filePath = textDocument.FilePath ?? textDocument.Name;
+                            var additionalFile = compilationWithAnalyzers.AnalysisOptions.Options?.AdditionalFiles.FirstOrDefault(a => PathUtilities.Comparer.Equals(a.Path, filePath));
+                            if (additionalFile != null)
+                            {
+                                diagnostics = await compilationWithAnalyzers.GetAnalyzerAdditionalFileDiagnosticsAsync(additionalFile, singleAnalyzer, cancellationToken).ConfigureAwait(false);
+                                break;
+                            }
+                        }
 
-                    Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilationWithAnalyzers.Compilation).Count());
-                    return diagnostics.ConvertToLocalDiagnostics(document);
+                        return SpecializedCollections.EmptyEnumerable<DiagnosticData>();
+                    }
+                    break;
 
                 case AnalysisKind.Semantic:
-                    var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
+                    var model = await document!.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                     if (model == null)
                     {
                         return SpecializedCollections.EmptyEnumerable<DiagnosticData>();
                     }
 
                     diagnostics = await compilationWithAnalyzers.GetAnalyzerSemanticDiagnosticsAsync(model, span, singleAnalyzer, cancellationToken).ConfigureAwait(false);
-
-                    if (skippedAnalyzerInfo.FilteredDiagnosticIdsForAnalyzers.TryGetValue(analyzer, out filteredIds))
-                    {
-                        diagnostics = diagnostics.Filter(filteredIds);
-                    }
-
-                    Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilationWithAnalyzers.Compilation).Count());
-                    return diagnostics.ConvertToLocalDiagnostics(document);
+                    break;
 
                 default:
                     throw ExceptionUtilities.UnexpectedValue(kind);
             }
+
+            if (skippedAnalyzerInfo.FilteredDiagnosticIdsForAnalyzers.TryGetValue(analyzer, out filteredIds))
+            {
+                diagnostics = diagnostics.Filter(filteredIds);
+            }
+
+            Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilationWithAnalyzers.Compilation).Count());
+            return diagnostics.ConvertToLocalDiagnostics(textDocument);
         }
 
         public static async Task<ImmutableArray<Diagnostic>> ComputeDocumentDiagnosticAnalyzerDiagnosticsAsync(
@@ -567,60 +581,38 @@ async Task VerifyDiagnosticLocationAsync(string id, Location location)
         }
 #endif
 
-        public static IEnumerable<DiagnosticData> ConvertToLocalDiagnostics(this IEnumerable<Diagnostic> diagnostics, Document targetDocument, TextSpan? span = null)
+        public static IEnumerable<DiagnosticData> ConvertToLocalDiagnostics(this IEnumerable<Diagnostic> diagnostics, TextDocument targetDocument, TextSpan? span = null)
         {
-            var project = targetDocument.Project;
-
-            if (project.SupportsCompilation)
-            {
-                return ConvertToLocalDiagnosticsWithCompilation();
-            }
-
-            return ConvertToLocalDiagnosticsWithoutCompilation();
-
-            IEnumerable<DiagnosticData> ConvertToLocalDiagnosticsWithoutCompilation()
+            foreach (var diagnostic in diagnostics)
             {
-                Contract.ThrowIfTrue(project.SupportsCompilation);
-
-                foreach (var diagnostic in diagnostics)
+                if (!IsReportedInDocument(diagnostic, targetDocument))
                 {
-                    var location = diagnostic.Location;
-                    if (location.Kind != LocationKind.ExternalFile)
-                    {
-                        continue;
-                    }
-
-                    var lineSpan = location.GetLineSpan();
-
-                    var documentIds = project.Solution.GetDocumentIdsWithFilePath(lineSpan.Path);
-                    if (documentIds.IsEmpty || documentIds.All(id => id != targetDocument.Id))
-                    {
-                        continue;
-                    }
+                    continue;
+                }
 
-                    yield return DiagnosticData.Create(diagnostic, targetDocument);
+                if (span.HasValue && !span.Value.IntersectsWith(diagnostic.Location.SourceSpan))
+                {
+                    continue;
                 }
+
+                yield return DiagnosticData.Create(diagnostic, targetDocument);
             }
 
-            IEnumerable<DiagnosticData> ConvertToLocalDiagnosticsWithCompilation()
+            static bool IsReportedInDocument(Diagnostic diagnostic, TextDocument targetDocument)
             {
-                Contract.ThrowIfFalse(project.SupportsCompilation);
-
-                foreach (var diagnostic in diagnostics)
+                if (diagnostic.Location.SourceTree != null)
                 {
-                    var document = project.GetDocument(diagnostic.Location.SourceTree);
-                    if (document == null || document != targetDocument)
-                    {
-                        continue;
-                    }
-
-                    if (span.HasValue && !span.Value.IntersectsWith(diagnostic.Location.SourceSpan))
-                    {
-                        continue;
-                    }
+                    return targetDocument.Project.GetDocument(diagnostic.Location.SourceTree) == targetDocument;
+                }
+                else if (diagnostic.Location.Kind == LocationKind.ExternalFile)
+                {
+                    var lineSpan = diagnostic.Location.GetLineSpan();
 
-                    yield return DiagnosticData.Create(diagnostic, document);
+                    var documentIds = targetDocument.Project.Solution.GetDocumentIdsWithFilePath(lineSpan.Path);
+                    return documentIds.Any(id => id == targetDocument.Id);
                 }
+
+                return false;
             }
         }
 
@@ -708,6 +700,7 @@ public override void RegisterOperationAction(Action<OperationAnalysisContext> ac
             public override void RegisterOperationBlockAction(Action<OperationBlockAnalysisContext> action) { }
             public override void RegisterOperationBlockStartAction(Action<OperationBlockStartAnalysisContext> action) { }
             public override void RegisterSymbolStartAction(Action<SymbolStartAnalysisContext> action, SymbolKind symbolKind) { }
+            public override void RegisterAdditionalFileAction(Action<AdditionalFileAnalysisContext> action) { }
             #endregion
 
             private class CollectNestedCompilationContext : CompilationStartAnalysisContext
@@ -740,6 +733,7 @@ public override void RegisterOperationAction(Action<OperationAnalysisContext> ac
                 public override void RegisterOperationBlockAction(Action<OperationBlockAnalysisContext> action) { }
                 public override void RegisterOperationBlockStartAction(Action<OperationBlockStartAnalysisContext> action) { }
                 public override void RegisterSymbolStartAction(Action<SymbolStartAnalysisContext> action, SymbolKind symbolKind) { }
+                public override void RegisterAdditionalFileAction(Action<AdditionalFileAnalysisContext> action) { }
                 #endregion
             }
         }
diff --git a/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs
index 127f4d84c5e10..e34b02c4e4c7e 100644
--- a/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs
+++ b/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs
@@ -59,7 +59,7 @@ public ImmutableArray<DiagnosticData> GetDiagnostics(Workspace workspace, Projec
         internal void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs state)
             => DiagnosticsUpdated?.Invoke(this, state);
 
-        private class DefaultDiagnosticIncrementalAnalyzer : IIncrementalAnalyzer
+        private class DefaultDiagnosticIncrementalAnalyzer : IIncrementalAnalyzer2
         {
             private readonly DefaultDiagnosticAnalyzerService _service;
             private readonly Workspace _workspace;
@@ -82,7 +82,13 @@ public bool NeedsReanalysisOnOptionChanged(object sender, OptionChangedEventArgs
                 return false;
             }
 
-            public async Task AnalyzeSyntaxAsync(Document document, InvocationReasons reasons, CancellationToken cancellationToken)
+            public Task AnalyzeSyntaxAsync(Document document, InvocationReasons reasons, CancellationToken cancellationToken)
+                => AnalyzeSyntaxOrNonSourceDocumentAsync(document, cancellationToken);
+
+            public Task AnalyzeNonSourceDocumentAsync(TextDocument document, InvocationReasons reasons, CancellationToken cancellationToken)
+                => AnalyzeSyntaxOrNonSourceDocumentAsync(document, cancellationToken);
+
+            private async Task AnalyzeSyntaxOrNonSourceDocumentAsync(TextDocument document, CancellationToken cancellationToken)
             {
                 Debug.Assert(document.Project.Solution.Workspace == _workspace);
 
@@ -124,7 +130,7 @@ bool IsSemanticAnalysisOn()
                 }
             }
 
-            private async Task AnalyzeForKindAsync(Document document, AnalysisKind kind, CancellationToken cancellationToken)
+            private async Task AnalyzeForKindAsync(TextDocument document, AnalysisKind kind, CancellationToken cancellationToken)
             {
                 var diagnosticData = await GetDiagnosticsAsync(document, kind, cancellationToken).ConfigureAwait(false);
 
@@ -146,7 +152,7 @@ private async Task AnalyzeForKindAsync(Document document, AnalysisKind kind, Can
             /// that provide all kinds of knobs/cache/persistency/OOP to get better perf over simplicity.
             /// </summary>
             private async Task<ImmutableArray<DiagnosticData>> GetDiagnosticsAsync(
-               Document document, AnalysisKind kind, CancellationToken cancellationToken)
+               TextDocument document, AnalysisKind kind, CancellationToken cancellationToken)
             {
                 var loadDiagnostic = await document.State.GetLoadDiagnosticAsync(cancellationToken).ConfigureAwait(false);
                 if (loadDiagnostic != null)
@@ -203,9 +209,18 @@ public Task DocumentResetAsync(Document document, CancellationToken cancellation
                 return RemoveDocumentAsync(document.Id, cancellationToken);
             }
 
+            public Task NonSourceDocumentResetAsync(TextDocument document, CancellationToken cancellationToken)
+            {
+                // no closed file diagnostic and file is not opened, remove any existing diagnostics
+                return RemoveDocumentAsync(document.Id, cancellationToken);
+            }
+
             public Task DocumentCloseAsync(Document document, CancellationToken cancellationToken)
                 => DocumentResetAsync(document, cancellationToken);
 
+            public Task NonSourceDocumentCloseAsync(TextDocument document, CancellationToken cancellationToken)
+                => NonSourceDocumentResetAsync(document, cancellationToken);
+
             private void RaiseEmptyDiagnosticUpdated(AnalysisKind kind, DocumentId documentId)
             {
                 _service.RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs.DiagnosticsRemoved(
@@ -218,6 +233,9 @@ public Task AnalyzeProjectAsync(Project project, bool semanticsChanged, Invocati
             public Task DocumentOpenAsync(Document document, CancellationToken cancellationToken)
                 => Task.CompletedTask;
 
+            public Task NonSourceDocumentOpenAsync(TextDocument document, CancellationToken cancellationToken)
+                => Task.CompletedTask;
+
             public Task NewSolutionSnapshotAsync(Solution solution, CancellationToken cancellationToken)
                 => Task.CompletedTask;
 
diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerTelemetry.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerTelemetry.cs
index 246697b293e36..c7b55e5a38110 100644
--- a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerTelemetry.cs
+++ b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerTelemetry.cs
@@ -23,6 +23,7 @@ private readonly struct Data
             public readonly int CompilationEndActionsCount;
             public readonly int CompilationActionsCount;
             public readonly int SyntaxTreeActionsCount;
+            public readonly int AdditionalFileActionsCount;
             public readonly int SemanticModelActionsCount;
             public readonly int SymbolActionsCount;
             public readonly int SymbolStartActionsCount;
@@ -51,6 +52,7 @@ public Data(AnalyzerTelemetryInfo analyzerTelemetryInfo, bool isTelemetryCollect
                 SymbolActionsCount = analyzerTelemetryInfo.SymbolActionsCount;
                 SyntaxNodeActionsCount = analyzerTelemetryInfo.SyntaxNodeActionsCount;
                 SyntaxTreeActionsCount = analyzerTelemetryInfo.SyntaxTreeActionsCount;
+                AdditionalFileActionsCount = analyzerTelemetryInfo.AdditionalFileActionsCount;
                 OperationActionsCount = analyzerTelemetryInfo.OperationActionsCount;
                 OperationBlockActionsCount = analyzerTelemetryInfo.OperationBlockActionsCount;
                 OperationBlockEndActionsCount = analyzerTelemetryInfo.OperationBlockEndActionsCount;
@@ -114,6 +116,7 @@ public void ReportAndClear(int correlationId)
                     m["Analyzer.SemanticModel"] = analyzerInfo.SemanticModelActionsCount;
                     m["Analyzer.SyntaxNode"] = analyzerInfo.SyntaxNodeActionsCount;
                     m["Analyzer.SyntaxTree"] = analyzerInfo.SyntaxTreeActionsCount;
+                    m["Analyzer.AdditionalFile"] = analyzerInfo.AdditionalFileActionsCount;
                     m["Analyzer.Operation"] = analyzerInfo.OperationActionsCount;
                     m["Analyzer.OperationBlock"] = analyzerInfo.OperationBlockActionsCount;
                     m["Analyzer.OperationBlockStart"] = analyzerInfo.OperationBlockStartActionsCount;
diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticResultSerializer.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticResultSerializer.cs
index af68a61c56533..7b00eba9f8ff2 100644
--- a/src/Features/Core/Portable/Diagnostics/DiagnosticResultSerializer.cs
+++ b/src/Features/Core/Portable/Diagnostics/DiagnosticResultSerializer.cs
@@ -148,6 +148,7 @@ private static void WriteTelemetry(ObjectWriter writer, AnalyzerTelemetryInfo te
             writer.WriteInt32(telemetryInfo.CompilationEndActionsCount);
             writer.WriteInt32(telemetryInfo.CompilationActionsCount);
             writer.WriteInt32(telemetryInfo.SyntaxTreeActionsCount);
+            writer.WriteInt32(telemetryInfo.AdditionalFileActionsCount);
             writer.WriteInt32(telemetryInfo.SemanticModelActionsCount);
             writer.WriteInt32(telemetryInfo.SymbolActionsCount);
             writer.WriteInt32(telemetryInfo.SymbolStartActionsCount);
@@ -173,6 +174,7 @@ private static AnalyzerTelemetryInfo ReadTelemetry(ObjectReader reader, Cancella
             var compilationEndActionsCount = reader.ReadInt32();
             var compilationActionsCount = reader.ReadInt32();
             var syntaxTreeActionsCount = reader.ReadInt32();
+            var additionalFileActionsCount = reader.ReadInt32();
             var semanticModelActionsCount = reader.ReadInt32();
             var symbolActionsCount = reader.ReadInt32();
             var symbolStartActionsCount = reader.ReadInt32();
@@ -196,6 +198,7 @@ private static AnalyzerTelemetryInfo ReadTelemetry(ObjectReader reader, Cancella
                 CompilationActionsCount = compilationActionsCount,
 
                 SyntaxTreeActionsCount = syntaxTreeActionsCount,
+                AdditionalFileActionsCount = additionalFileActionsCount,
                 SemanticModelActionsCount = semanticModelActionsCount,
                 SymbolActionsCount = symbolActionsCount,
                 SymbolStartActionsCount = symbolStartActionsCount,
diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs
index c308fd4b66447..e946e676d380d 100644
--- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs
+++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.Executor.cs
@@ -26,7 +26,7 @@ internal partial class DiagnosticIncrementalAnalyzer
         /// Return all local diagnostics (syntax, semantic) that belong to given document for the given StateSet (analyzer) either from cache or by calculating them
         /// </summary>
         private async Task<DocumentAnalysisData> GetDocumentAnalysisDataAsync(
-            CompilationWithAnalyzers? compilation, Document document, StateSet stateSet, AnalysisKind kind, CancellationToken cancellationToken)
+            CompilationWithAnalyzers? compilation, TextDocument document, StateSet stateSet, AnalysisKind kind, CancellationToken cancellationToken)
         {
             // get log title and functionId
             GetLogFunctionIdAndTitle(kind, out var functionId, out var title);
diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs
index cf79282a1934e..7dcd99ec13024 100644
--- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs
+++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.ProjectState.cs
@@ -9,6 +9,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis.Host;
+using Microsoft.CodeAnalysis.Shared.Extensions;
 using Microsoft.CodeAnalysis.SolutionCrawler;
 using Microsoft.CodeAnalysis.Workspaces.Diagnostics;
 using Roslyn.Utilities;
@@ -111,7 +112,7 @@ public async Task<DiagnosticAnalysisResult> GetAnalysisDataAsync(IPersistentStor
             /// <summary>
             /// Return all diagnostics for the given document stored in this state including non local diagnostics for this document
             /// </summary>
-            public async Task<DiagnosticAnalysisResult> GetAnalysisDataAsync(IPersistentStorageService persistentService, Document document, bool avoidLoadingData, CancellationToken cancellationToken)
+            public async Task<DiagnosticAnalysisResult> GetAnalysisDataAsync(IPersistentStorageService persistentService, TextDocument document, bool avoidLoadingData, CancellationToken cancellationToken)
             {
                 // make a copy of last result.
                 var lastResult = _lastResult;
@@ -202,7 +203,7 @@ public async Task SaveAsync(IPersistentStorageService persistentService, Project
                 var serializer = new DiagnosticDataSerializer(_owner.AnalyzerVersion, result.Version);
                 foreach (var documentId in result.DocumentIds)
                 {
-                    var document = project.GetDocument(documentId);
+                    var document = project.GetTextDocument(documentId);
                     if (document == null)
                     {
                         // it can happen with build synchronization since, in build case, 
@@ -229,7 +230,7 @@ public void ResetVersion()
                 _lastResult = _lastResult.Reset();
             }
 
-            public async Task MergeAsync(IPersistentStorageService persistentService, ActiveFileState state, Document document)
+            public async Task MergeAsync(IPersistentStorageService persistentService, ActiveFileState state, TextDocument document)
             {
                 Contract.ThrowIfFalse(state.DocumentId == document.Id);
 
@@ -312,7 +313,7 @@ private async Task<DiagnosticAnalysisResult> LoadInitialAnalysisDataAsync(IPersi
                 return builder.ToResult();
             }
 
-            private async Task<DiagnosticAnalysisResult> LoadInitialAnalysisDataAsync(IPersistentStorageService persistentService, Document document, CancellationToken cancellationToken)
+            private async Task<DiagnosticAnalysisResult> LoadInitialAnalysisDataAsync(IPersistentStorageService persistentService, TextDocument document, CancellationToken cancellationToken)
             {
                 // loading data can be cancelled any time.
                 var project = document.Project;
@@ -344,7 +345,7 @@ private async Task<DiagnosticAnalysisResult> LoadInitialProjectAnalysisDataAsync
                 return builder.ToResult();
             }
 
-            private async Task SerializeAsync(IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, Project project, Document? document, object key, string stateKey, ImmutableArray<DiagnosticData> diagnostics)
+            private async Task SerializeAsync(IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, Project project, TextDocument? document, object key, string stateKey, ImmutableArray<DiagnosticData> diagnostics)
             {
                 Contract.ThrowIfFalse(document == null || document.Project == project);
 
@@ -360,7 +361,7 @@ private async Task SerializeAsync(IPersistentStorageService persistentService, D
                 InMemoryStorage.Cache(_owner.Analyzer, (key, stateKey), new CacheEntry(serializer.Version, diagnostics));
             }
 
-            private async Task<bool> TryDeserializeDocumentDiagnosticsAsync(IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, Document document, Builder builder, CancellationToken cancellationToken)
+            private async Task<bool> TryDeserializeDocumentDiagnosticsAsync(IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, TextDocument document, Builder builder, CancellationToken cancellationToken)
             {
                 var success = true;
                 var project = document.Project;
@@ -411,7 +412,7 @@ private async Task<bool> TryDeserializeProjectDiagnosticsAsync(IPersistentStorag
                 return false;
             }
 
-            private ValueTask<ImmutableArray<DiagnosticData>> DeserializeDiagnosticsAsync(IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, Project project, Document? document, object key, string stateKey, CancellationToken cancellationToken)
+            private ValueTask<ImmutableArray<DiagnosticData>> DeserializeDiagnosticsAsync(IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, Project project, TextDocument? document, object key, string stateKey, CancellationToken cancellationToken)
             {
                 Contract.ThrowIfFalse(document == null || document.Project == project);
 
diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs
index 3b174d098f4d4..a0d338bc57271 100644
--- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs
+++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateManager.cs
@@ -192,7 +192,7 @@ public ImmutableArray<StateSet> CreateBuildOnlyProjectStateSet(Project project)
                 return stateSets.ToImmutable();
             }
 
-            public static bool OnDocumentReset(IEnumerable<StateSet> stateSets, Document document)
+            public static bool OnDocumentReset(IEnumerable<StateSet> stateSets, TextDocument document)
             {
                 // can not be cancelled
                 var removed = false;
@@ -204,7 +204,7 @@ public static bool OnDocumentReset(IEnumerable<StateSet> stateSets, Document doc
                 return removed;
             }
 
-            public async Task<bool> OnDocumentOpenedAsync(IEnumerable<StateSet> stateSets, Document document)
+            public async Task<bool> OnDocumentOpenedAsync(IEnumerable<StateSet> stateSets, TextDocument document)
             {
                 // can not be cancelled
                 var opened = false;
@@ -216,7 +216,7 @@ public async Task<bool> OnDocumentOpenedAsync(IEnumerable<StateSet> stateSets, D
                 return opened;
             }
 
-            public async Task<bool> OnDocumentClosedAsync(IEnumerable<StateSet> stateSets, Document document)
+            public async Task<bool> OnDocumentClosedAsync(IEnumerable<StateSet> stateSets, TextDocument document)
             {
                 // can not be cancelled
                 var removed = false;
diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs
index 171823b7fff72..7c4873479858f 100644
--- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs
+++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.StateSet.cs
@@ -138,7 +138,7 @@ public ActiveFileState GetOrCreateActiveFileState(DocumentId documentId)
             public ProjectState GetOrCreateProjectState(ProjectId projectId)
                 => _projectStates.GetOrAdd(projectId, id => new ProjectState(this, id));
 
-            public async Task<bool> OnDocumentOpenedAsync(IPersistentStorageService persistentStorageService, Document document)
+            public async Task<bool> OnDocumentOpenedAsync(IPersistentStorageService persistentStorageService, TextDocument document)
             {
                 // can not be cancelled
                 if (!TryGetProjectState(document.Project.Id, out var projectState) ||
@@ -159,7 +159,7 @@ public async Task<bool> OnDocumentOpenedAsync(IPersistentStorageService persiste
                 return true;
             }
 
-            public async Task<bool> OnDocumentClosedAsync(IPersistentStorageService persistentStorageService, Document document)
+            public async Task<bool> OnDocumentClosedAsync(IPersistentStorageService persistentStorageService, TextDocument document)
             {
                 // can not be cancelled
                 // remove active file state and put it in project state
@@ -174,7 +174,7 @@ public async Task<bool> OnDocumentClosedAsync(IPersistentStorageService persiste
                 return true;
             }
 
-            public bool OnDocumentReset(Document document)
+            public bool OnDocumentReset(TextDocument document)
             {
                 var changed = false;
                 // can not be cancelled
diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.cs
index 92994854a0fca..a7cb47e034732 100644
--- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.cs
+++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer.cs
@@ -29,7 +29,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics.EngineV2
     /// 
     /// This one follows pattern compiler has set for diagnostic analyzer.
     /// </summary>
-    internal partial class DiagnosticIncrementalAnalyzer : IIncrementalAnalyzer
+    internal partial class DiagnosticIncrementalAnalyzer : IIncrementalAnalyzer2
     {
         private readonly int _correlationId;
         private readonly DiagnosticAnalyzerTelemetry _telemetry;
@@ -187,7 +187,7 @@ private void RaiseDiagnosticsRemoved(
         }
 
         private void RaiseDiagnosticsCreated(
-            Document document, StateSet stateSet, AnalysisKind kind, ImmutableArray<DiagnosticData> items, Action<DiagnosticsUpdatedArgs> raiseEvents)
+            TextDocument document, StateSet stateSet, AnalysisKind kind, ImmutableArray<DiagnosticData> items, Action<DiagnosticsUpdatedArgs> raiseEvents)
         {
             Contract.ThrowIfFalse(document.Project.Solution.Workspace == Workspace);
 
@@ -238,16 +238,16 @@ public void LogAnalyzerCountSummary()
         internal IEnumerable<DiagnosticAnalyzer> GetAnalyzersTestOnly(Project project)
             => _stateManager.GetOrCreateStateSets(project).Select(s => s.Analyzer);
 
-        private static string GetDocumentLogMessage(string title, Document document, DiagnosticAnalyzer analyzer)
+        private static string GetDocumentLogMessage(string title, TextDocument document, DiagnosticAnalyzer analyzer)
             => $"{title}: ({document.Id}, {document.Project.Id}), ({analyzer})";
 
         private static string GetProjectLogMessage(Project project, IEnumerable<StateSet> stateSets)
             => $"project: ({project.Id}), ({string.Join(Environment.NewLine, stateSets.Select(s => s.Analyzer.ToString()))})";
 
-        private static string GetResetLogMessage(Document document)
+        private static string GetResetLogMessage(TextDocument document)
             => $"document close/reset: ({document.FilePath ?? document.Name})";
 
-        private static string GetOpenLogMessage(Document document)
+        private static string GetOpenLogMessage(TextDocument document)
             => $"document open: ({document.FilePath ?? document.Name})";
 
         private static string GetRemoveLogMessage(DocumentId id)
diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs
index cb6b5f0be52a2..f104babdf67e5 100644
--- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs
+++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_IncrementalAnalyzer.cs
@@ -32,7 +32,10 @@ public Task AnalyzeSyntaxAsync(Document document, InvocationReasons reasons, Can
         public Task AnalyzeDocumentAsync(Document document, SyntaxNode bodyOpt, InvocationReasons reasons, CancellationToken cancellationToken)
             => AnalyzeDocumentForKindAsync(document, AnalysisKind.Semantic, cancellationToken);
 
-        private async Task AnalyzeDocumentForKindAsync(Document document, AnalysisKind kind, CancellationToken cancellationToken)
+        public Task AnalyzeNonSourceDocumentAsync(TextDocument textDocument, InvocationReasons reasons, CancellationToken cancellationToken)
+            => AnalyzeDocumentForKindAsync(textDocument, AnalysisKind.Syntax, cancellationToken);
+
+        private async Task AnalyzeDocumentForKindAsync(TextDocument document, AnalysisKind kind, CancellationToken cancellationToken)
         {
             try
             {
@@ -133,7 +136,13 @@ private async Task AnalyzeProjectAsync(Project project, bool forceAnalyzerRun, C
             }
         }
 
-        public async Task DocumentOpenAsync(Document document, CancellationToken cancellationToken)
+        public Task DocumentOpenAsync(Document document, CancellationToken cancellationToken)
+            => TextDocumentOpenAsync(document, cancellationToken);
+
+        public Task NonSourceDocumentOpenAsync(TextDocument document, CancellationToken cancellationToken)
+            => TextDocumentOpenAsync(document, cancellationToken);
+
+        private async Task TextDocumentOpenAsync(TextDocument document, CancellationToken cancellationToken)
         {
             using (Logger.LogBlock(FunctionId.Diagnostics_DocumentOpen, GetOpenLogMessage, document, cancellationToken))
             {
@@ -145,7 +154,13 @@ public async Task DocumentOpenAsync(Document document, CancellationToken cancell
             }
         }
 
-        public async Task DocumentCloseAsync(Document document, CancellationToken cancellationToken)
+        public Task DocumentCloseAsync(Document document, CancellationToken cancellationToken)
+            => TextDocumentCloseAsync(document, cancellationToken);
+
+        public Task NonSourceDocumentCloseAsync(TextDocument document, CancellationToken cancellationToken)
+            => TextDocumentCloseAsync(document, cancellationToken);
+
+        private async Task TextDocumentCloseAsync(TextDocument document, CancellationToken cancellationToken)
         {
             using (Logger.LogBlock(FunctionId.Diagnostics_DocumentClose, GetResetLogMessage, document, cancellationToken))
             {
@@ -159,6 +174,12 @@ public async Task DocumentCloseAsync(Document document, CancellationToken cancel
         }
 
         public Task DocumentResetAsync(Document document, CancellationToken cancellationToken)
+            => TextDocumentResetAsync(document, cancellationToken);
+
+        public Task NonSourceDocumentResetAsync(TextDocument document, CancellationToken cancellationToken)
+            => TextDocumentResetAsync(document, cancellationToken);
+
+        private Task TextDocumentResetAsync(TextDocument document, CancellationToken cancellationToken)
         {
             using (Logger.LogBlock(FunctionId.Diagnostics_DocumentReset, GetResetLogMessage, document, cancellationToken))
             {
@@ -173,7 +194,7 @@ public Task DocumentResetAsync(Document document, CancellationToken cancellation
             return Task.CompletedTask;
         }
 
-        private void RaiseDiagnosticsRemovedIfRequiredForClosedOrResetDocument(Document document, IEnumerable<StateSet> stateSets, bool documentHadDiagnostics)
+        private void RaiseDiagnosticsRemovedIfRequiredForClosedOrResetDocument(TextDocument document, IEnumerable<StateSet> stateSets, bool documentHadDiagnostics)
         {
             // if there was no diagnostic reported for this document OR Full solution analysis is enabled, nothing to clean up
             if (!documentHadDiagnostics ||
@@ -266,7 +287,7 @@ public Task NewSolutionSnapshotAsync(Solution solution, CancellationToken cancel
             return Task.CompletedTask;
         }
 
-        private static bool AnalysisEnabled(Document document)
+        private static bool AnalysisEnabled(TextDocument document)
         {
             if (document.Services.GetService<DocumentPropertiesService>()?.DiagnosticsLspClientName != null)
             {
@@ -407,17 +428,17 @@ private void RaiseProjectDiagnosticsIfNeeded(
             });
         }
 
-        private void RaiseDocumentDiagnosticsIfNeeded(Document document, StateSet stateSet, AnalysisKind kind, ImmutableArray<DiagnosticData> items)
+        private void RaiseDocumentDiagnosticsIfNeeded(TextDocument document, StateSet stateSet, AnalysisKind kind, ImmutableArray<DiagnosticData> items)
             => RaiseDocumentDiagnosticsIfNeeded(document, stateSet, kind, ImmutableArray<DiagnosticData>.Empty, items);
 
         private void RaiseDocumentDiagnosticsIfNeeded(
-            Document document, StateSet stateSet, AnalysisKind kind, ImmutableArray<DiagnosticData> oldItems, ImmutableArray<DiagnosticData> newItems)
+            TextDocument document, StateSet stateSet, AnalysisKind kind, ImmutableArray<DiagnosticData> oldItems, ImmutableArray<DiagnosticData> newItems)
         {
             RaiseDocumentDiagnosticsIfNeeded(document, stateSet, kind, oldItems, newItems, AnalyzerService.RaiseDiagnosticsUpdated, forceUpdate: false);
         }
 
         private void RaiseDocumentDiagnosticsIfNeeded(
-            Document document, StateSet stateSet, AnalysisKind kind,
+            TextDocument document, StateSet stateSet, AnalysisKind kind,
             DiagnosticAnalysisResult oldResult, DiagnosticAnalysisResult newResult,
             Action<DiagnosticsUpdatedArgs> raiseEvents)
         {
@@ -438,7 +459,7 @@ private void RaiseDocumentDiagnosticsIfNeeded(
         }
 
         private void RaiseDocumentDiagnosticsIfNeeded(
-            Document document, StateSet stateSet, AnalysisKind kind,
+            TextDocument document, StateSet stateSet, AnalysisKind kind,
             ImmutableArray<DiagnosticData> oldItems, ImmutableArray<DiagnosticData> newItems,
             Action<DiagnosticsUpdatedArgs> raiseEvents,
             bool forceUpdate)
@@ -458,7 +479,7 @@ private void RaiseProjectDiagnosticsCreated(Project project, StateSet stateSet,
 
             foreach (var documentId in newAnalysisResult.DocumentIds)
             {
-                var document = project.GetDocument(documentId);
+                var document = project.GetTextDocument(documentId);
                 if (document == null)
                 {
                     // it can happen with build synchronization since, in build case, 
@@ -505,7 +526,7 @@ private void RaiseProjectDiagnosticsRemoved(StateSet stateSet, ProjectId project
             RaiseDiagnosticsRemoved(projectId, solution: null, stateSet, raiseEvents);
         }
 
-        private async Task ReportAnalyzerPerformanceAsync(Document document, CompilationWithAnalyzers? compilation, CancellationToken cancellationToken)
+        private async Task ReportAnalyzerPerformanceAsync(TextDocument document, CompilationWithAnalyzers? compilation, CancellationToken cancellationToken)
         {
             try
             {
diff --git a/src/Features/Core/Portable/SolutionCrawler/AggregateIncrementalAnalyzer.cs b/src/Features/Core/Portable/SolutionCrawler/AggregateIncrementalAnalyzer.cs
index 5c4aef52807d2..a8cf77d146f8c 100644
--- a/src/Features/Core/Portable/SolutionCrawler/AggregateIncrementalAnalyzer.cs
+++ b/src/Features/Core/Portable/SolutionCrawler/AggregateIncrementalAnalyzer.cs
@@ -18,7 +18,7 @@
 
 namespace Microsoft.CodeAnalysis.SolutionCrawler
 {
-    internal class AggregateIncrementalAnalyzer : IIncrementalAnalyzer
+    internal class AggregateIncrementalAnalyzer : IIncrementalAnalyzer2
     {
         public readonly ImmutableDictionary<string, Lazy<IIncrementalAnalyzer>> Analyzers;
 
@@ -126,5 +126,41 @@ public async Task RemoveProjectAsync(ProjectId projectId, CancellationToken canc
                 }
             }
         }
+
+        public async Task NonSourceDocumentOpenAsync(TextDocument document, CancellationToken cancellationToken)
+        {
+            if (TryGetAnalyzer(document.Project, out var analyzer) &&
+                analyzer is IIncrementalAnalyzer2 analyzer2)
+            {
+                await analyzer2.NonSourceDocumentOpenAsync(document, cancellationToken).ConfigureAwait(false);
+            }
+        }
+
+        public async Task NonSourceDocumentCloseAsync(TextDocument document, CancellationToken cancellationToken)
+        {
+            if (TryGetAnalyzer(document.Project, out var analyzer) &&
+                analyzer is IIncrementalAnalyzer2 analyzer2)
+            {
+                await analyzer2.NonSourceDocumentCloseAsync(document, cancellationToken).ConfigureAwait(false);
+            }
+        }
+
+        public async Task NonSourceDocumentResetAsync(TextDocument document, CancellationToken cancellationToken)
+        {
+            if (TryGetAnalyzer(document.Project, out var analyzer) &&
+                analyzer is IIncrementalAnalyzer2 analyzer2)
+            {
+                await analyzer2.NonSourceDocumentResetAsync(document, cancellationToken).ConfigureAwait(false);
+            }
+        }
+
+        public async Task AnalyzeNonSourceDocumentAsync(TextDocument document, InvocationReasons reasons, CancellationToken cancellationToken)
+        {
+            if (TryGetAnalyzer(document.Project, out var analyzer) &&
+                analyzer is IIncrementalAnalyzer2 analyzer2)
+            {
+                await analyzer2.AnalyzeNonSourceDocumentAsync(document, reasons, cancellationToken).ConfigureAwait(false);
+            }
+        }
     }
 }
diff --git a/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.IncrementalAnalyzerProcessor.cs b/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.IncrementalAnalyzerProcessor.cs
index 54910f9581b5a..84217fe489888 100644
--- a/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.IncrementalAnalyzerProcessor.cs
+++ b/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.IncrementalAnalyzerProcessor.cs
@@ -237,13 +237,19 @@ private void ReportPendingWorkItemCount()
                 }
 
                 private async Task ProcessDocumentAnalyzersAsync(
-                    Document document, ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, CancellationToken cancellationToken)
+                    TextDocument textDocument, ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, CancellationToken cancellationToken)
                 {
                     // process all analyzers for each categories in this order - syntax, body, document
                     var reasons = workItem.InvocationReasons;
                     if (workItem.MustRefresh || reasons.Contains(PredefinedInvocationReasons.SyntaxChanged))
                     {
-                        await RunAnalyzersAsync(analyzers, document, workItem, (a, d, c) => a.AnalyzeSyntaxAsync(d, reasons, c), cancellationToken).ConfigureAwait(false);
+                        await RunAnalyzersAsync(analyzers, textDocument, workItem, (a, d, c) => AnalyzeSyntaxAsync(a, d, reasons, c), cancellationToken).ConfigureAwait(false);
+                    }
+
+                    if (!(textDocument is Document document))
+                    {
+                        // Semantic analysis is not supported for non-source documents.
+                        return;
                     }
 
                     if (workItem.MustRefresh || reasons.Contains(PredefinedInvocationReasons.SemanticChanged))
@@ -255,6 +261,20 @@ private async Task ProcessDocumentAnalyzersAsync(
                         // if we don't need to re-analyze whole body, see whether we need to at least re-analyze one method.
                         await RunBodyAnalyzersAsync(analyzers, workItem, document, cancellationToken).ConfigureAwait(false);
                     }
+
+                    return;
+
+                    static async Task AnalyzeSyntaxAsync(IIncrementalAnalyzer analyzer, TextDocument textDocument, InvocationReasons reasons, CancellationToken cancellationToken)
+                    {
+                        if (textDocument is Document document)
+                        {
+                            await analyzer.AnalyzeSyntaxAsync(document, reasons, cancellationToken).ConfigureAwait(false);
+                        }
+                        else if (analyzer is IIncrementalAnalyzer2 analyzer2)
+                        {
+                            await analyzer2.AnalyzeNonSourceDocumentAsync(textDocument, reasons, cancellationToken).ConfigureAwait(false);
+                        }
+                    }
                 }
 
                 private async Task RunAnalyzersAsync<T>(
diff --git a/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.NormalPriorityProcessor.cs b/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.NormalPriorityProcessor.cs
index 5844f27fa6fbe..5ecee271076fe 100644
--- a/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.NormalPriorityProcessor.cs
+++ b/src/Features/Core/Portable/SolutionCrawler/WorkCoordinator.NormalPriorityProcessor.cs
@@ -334,7 +334,7 @@ private async Task ProcessDocumentAsync(ImmutableArray<IIncrementalAnalyzer> ana
                         {
                             using (Logger.LogBlock(FunctionId.WorkCoordinator_ProcessDocumentAsync, w => w.ToString(), workItem, cancellationToken))
                             {
-                                var document = solution.GetDocument(documentId);
+                                var document = solution.GetTextDocument(documentId);
 
                                 if (document != null)
                                 {
@@ -389,7 +389,7 @@ private async Task ProcessDocumentAsync(ImmutableArray<IIncrementalAnalyzer> ana
                         }
                     }
 
-                    private async Task ProcessOpenDocumentIfNeededAsync(ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, Document document, bool isOpen, CancellationToken cancellationToken)
+                    private async Task ProcessOpenDocumentIfNeededAsync(ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, TextDocument document, bool isOpen, CancellationToken cancellationToken)
                     {
                         if (!isOpen || !workItem.InvocationReasons.Contains(PredefinedInvocationReasons.DocumentOpened))
                         {
@@ -398,10 +398,23 @@ private async Task ProcessOpenDocumentIfNeededAsync(ImmutableArray<IIncrementalA
 
                         SolutionCrawlerLogger.LogProcessOpenDocument(Processor._logAggregator, document.Id.Id);
 
-                        await Processor.RunAnalyzersAsync(analyzers, document, workItem, (a, d, c) => a.DocumentOpenAsync(d, c), cancellationToken).ConfigureAwait(false);
+                        await Processor.RunAnalyzersAsync(analyzers, document, workItem, DocumentOpenAsync, cancellationToken).ConfigureAwait(false);
+                        return;
+
+                        static async Task DocumentOpenAsync(IIncrementalAnalyzer analyzer, TextDocument textDocument, CancellationToken cancellationToken)
+                        {
+                            if (textDocument is Document document)
+                            {
+                                await analyzer.DocumentOpenAsync(document, cancellationToken).ConfigureAwait(false);
+                            }
+                            else if (analyzer is IIncrementalAnalyzer2 analyzer2)
+                            {
+                                await analyzer2.NonSourceDocumentOpenAsync(textDocument, cancellationToken).ConfigureAwait(false);
+                            }
+                        }
                     }
 
-                    private async Task ProcessCloseDocumentIfNeededAsync(ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, Document document, bool isOpen, CancellationToken cancellationToken)
+                    private async Task ProcessCloseDocumentIfNeededAsync(ImmutableArray<IIncrementalAnalyzer> analyzers, WorkItem workItem, TextDocument document, bool isOpen, CancellationToken cancellationToken)
                     {
                         if (isOpen || !workItem.InvocationReasons.Contains(PredefinedInvocationReasons.DocumentClosed))
                         {
@@ -410,10 +423,23 @@ private async Task ProcessCloseDocumentIfNeededAsync(ImmutableArray<IIncremental
 
                         SolutionCrawlerLogger.LogProcessCloseDocument(Processor._logAggregator, document.Id.Id);
 
-                        await Processor.RunAnalyzersAsync(analyzers, document, workItem, (a, d, c) => a.DocumentCloseAsync(d, c), cancellationToken).ConfigureAwait(false);
+                        await Processor.RunAnalyzersAsync(analyzers, document, workItem, DocumentCloseAsync, cancellationToken).ConfigureAwait(false);
+                        return;
+
+                        static async Task DocumentCloseAsync(IIncrementalAnalyzer analyzer, TextDocument textDocument, CancellationToken cancellationToken)
+                        {
+                            if (textDocument is Document document)
+                            {
+                                await analyzer.DocumentCloseAsync(document, cancellationToken).ConfigureAwait(false);
+                            }
+                            else if (analyzer is IIncrementalAnalyzer2 analyzer2)
+                            {
+                                await analyzer2.NonSourceDocumentCloseAsync(textDocument, cancellationToken).ConfigureAwait(false);
+                            }
+                        }
                     }
 
-                    private async Task ProcessReanalyzeDocumentAsync(WorkItem workItem, Document document, CancellationToken cancellationToken)
+                    private async Task ProcessReanalyzeDocumentAsync(WorkItem workItem, TextDocument document, CancellationToken cancellationToken)
                     {
                         try
                         {
@@ -421,7 +447,7 @@ private async Task ProcessReanalyzeDocumentAsync(WorkItem workItem, Document doc
                             Debug.Assert(!workItem.InvocationReasons.Contains(PredefinedInvocationReasons.Reanalyze) || workItem.SpecificAnalyzers.Count > 0);
 #endif
 
-                            // no-reanalyze request or we already have a request to re-analyze every thing
+                            // No-reanalyze request or we already have a request to re-analyze every thing
                             if (workItem.MustRefresh || !workItem.InvocationReasons.Contains(PredefinedInvocationReasons.Reanalyze))
                             {
                                 return;
@@ -429,25 +455,53 @@ private async Task ProcessReanalyzeDocumentAsync(WorkItem workItem, Document doc
 
                             // First reset the document state in analyzers.
                             var reanalyzers = workItem.SpecificAnalyzers.ToImmutableArray();
-                            await Processor.RunAnalyzersAsync(reanalyzers, document, workItem, (a, d, c) => a.DocumentResetAsync(d, c), cancellationToken).ConfigureAwait(false);
+                            await Processor.RunAnalyzersAsync(reanalyzers, document, workItem, DocumentResetAsync, cancellationToken).ConfigureAwait(false);
 
-                            // no request to re-run syntax change analysis. run it here
+                            // No request to re-run syntax change analysis. run it here
                             var reasons = workItem.InvocationReasons;
                             if (!reasons.Contains(PredefinedInvocationReasons.SyntaxChanged))
                             {
-                                await Processor.RunAnalyzersAsync(reanalyzers, document, workItem, (a, d, c) => a.AnalyzeSyntaxAsync(d, reasons, c), cancellationToken).ConfigureAwait(false);
+                                await Processor.RunAnalyzersAsync(reanalyzers, document, workItem, (a, d, c) => AnalyzeSyntaxAsync(a, d, reasons, c), cancellationToken).ConfigureAwait(false);
                             }
 
-                            // no request to re-run semantic change analysis. run it here
-                            if (!workItem.InvocationReasons.Contains(PredefinedInvocationReasons.SemanticChanged))
+                            // No request to re-run semantic change analysis. run it here
+                            // Note: Semantic analysis is not supported for non-source documents.
+                            if (document is Document sourceDocument &&
+                                !workItem.InvocationReasons.Contains(PredefinedInvocationReasons.SemanticChanged))
                             {
-                                await Processor.RunAnalyzersAsync(reanalyzers, document, workItem, (a, d, c) => a.AnalyzeDocumentAsync(d, null, reasons, c), cancellationToken).ConfigureAwait(false);
+                                await Processor.RunAnalyzersAsync(reanalyzers, sourceDocument, workItem, (a, d, c) => a.AnalyzeDocumentAsync(d, null, reasons, c), cancellationToken).ConfigureAwait(false);
                             }
                         }
                         catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
                         {
                             throw ExceptionUtilities.Unreachable;
                         }
+
+                        return;
+
+                        static async Task DocumentResetAsync(IIncrementalAnalyzer analyzer, TextDocument textDocument, CancellationToken cancellationToken)
+                        {
+                            if (textDocument is Document document)
+                            {
+                                await analyzer.DocumentResetAsync(document, cancellationToken).ConfigureAwait(false);
+                            }
+                            else if (analyzer is IIncrementalAnalyzer2 analyzer2)
+                            {
+                                await analyzer2.NonSourceDocumentResetAsync(textDocument, cancellationToken).ConfigureAwait(false);
+                            }
+                        }
+
+                        static async Task AnalyzeSyntaxAsync(IIncrementalAnalyzer analyzer, TextDocument textDocument, InvocationReasons reasons, CancellationToken cancellationToken)
+                        {
+                            if (textDocument is Document document)
+                            {
+                                await analyzer.AnalyzeSyntaxAsync((Document)document, reasons, cancellationToken).ConfigureAwait(false);
+                            }
+                            else if (analyzer is IIncrementalAnalyzer2 analyzer2)
+                            {
+                                await analyzer2.AnalyzeNonSourceDocumentAsync(textDocument, reasons, cancellationToken).ConfigureAwait(false);
+                            }
+                        }
                     }
 
                     private Task RemoveDocumentAsync(DocumentId documentId, CancellationToken cancellationToken)
diff --git a/src/Test/Utilities/Portable/Diagnostics/CommonDiagnosticAnalyzers.cs b/src/Test/Utilities/Portable/Diagnostics/CommonDiagnosticAnalyzers.cs
index da4802867cc3a..42e1b857bd6d2 100644
--- a/src/Test/Utilities/Portable/Diagnostics/CommonDiagnosticAnalyzers.cs
+++ b/src/Test/Utilities/Portable/Diagnostics/CommonDiagnosticAnalyzers.cs
@@ -2146,7 +2146,7 @@ private void OnOperationBlockStart(OperationBlockStartAnalysisContext context)
         }
 
         [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
-        public sealed class AdditionalFileAnalyzer : DiagnosticAnalyzer
+        public class AdditionalFileAnalyzer : DiagnosticAnalyzer
         {
             private readonly bool _registerFromInitialize;
             private readonly TextSpan _diagnosticSpan;
diff --git a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs
index 20ff953ba976e..817b030f828f3 100644
--- a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs
+++ b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs
@@ -464,6 +464,7 @@ private static void WriteTelemetry(string analyzerName, AnalyzerTelemetryInfo te
             WriteLine($"Symbol End Actions:             {telemetry.SymbolEndActionsCount}", ConsoleColor.White);
             WriteLine($"Syntax Node Actions:            {telemetry.SyntaxNodeActionsCount}", ConsoleColor.White);
             WriteLine($"Syntax Tree Actions:            {telemetry.SyntaxTreeActionsCount}", ConsoleColor.White);
+            WriteLine($"Additional File Actions:        {telemetry.AdditionalFileActionsCount}", ConsoleColor.White);
 
             WriteLine($"Suppression Actions:            {telemetry.SuppressionActionsCount}", ConsoleColor.White);
         }
diff --git a/src/Tools/AnalyzerRunner/Extensions.cs b/src/Tools/AnalyzerRunner/Extensions.cs
index 80cf66d64818a..d4156887be9b3 100644
--- a/src/Tools/AnalyzerRunner/Extensions.cs
+++ b/src/Tools/AnalyzerRunner/Extensions.cs
@@ -26,6 +26,7 @@ internal static void Add(this AnalyzerTelemetryInfo analyzerTelemetryInfo, Analy
             analyzerTelemetryInfo.SymbolEndActionsCount += addendum.SymbolEndActionsCount;
             analyzerTelemetryInfo.SyntaxNodeActionsCount += addendum.SyntaxNodeActionsCount;
             analyzerTelemetryInfo.SyntaxTreeActionsCount += addendum.SyntaxTreeActionsCount;
+            analyzerTelemetryInfo.AdditionalFileActionsCount += addendum.AdditionalFileActionsCount;
             analyzerTelemetryInfo.SuppressionActionsCount += addendum.SuppressionActionsCount;
         }
     }
diff --git a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResult.cs b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResult.cs
index ebed68d65ba84..c21cf402f684e 100644
--- a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResult.cs
+++ b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResult.cs
@@ -10,6 +10,7 @@
 using Microsoft.CodeAnalysis.Diagnostics;
 using Microsoft.CodeAnalysis.Host;
 using Microsoft.CodeAnalysis.PooledObjects;
+using Microsoft.CodeAnalysis.Shared.Extensions;
 using Roslyn.Utilities;
 
 namespace Microsoft.CodeAnalysis.Workspaces.Diagnostics
@@ -318,7 +319,7 @@ private static void VerifyDocumentMap(Project project, ImmutableDictionary<Docum
         {
             foreach (var documentId in map.Keys)
             {
-                Debug.Assert(project.GetDocument(documentId)?.SupportsDiagnostics() == true);
+                Debug.Assert(project.GetTextDocument(documentId)?.SupportsDiagnostics() == true);
             }
         }
     }
diff --git a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs
index f47a834cda678..a9dbdec569328 100644
--- a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs
+++ b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticAnalysisResultBuilder.cs
@@ -10,6 +10,7 @@
 using System.Linq;
 using Microsoft.CodeAnalysis.Diagnostics;
 using Microsoft.CodeAnalysis.Host;
+using Microsoft.CodeAnalysis.Shared.Extensions;
 using Roslyn.Utilities;
 
 namespace Microsoft.CodeAnalysis.Workspaces.Diagnostics
@@ -51,21 +52,20 @@ public DiagnosticAnalysisResultBuilder(Project project, VersionStamp version)
 
         public void AddExternalSyntaxDiagnostics(DocumentId documentId, IEnumerable<Diagnostic> diagnostics)
         {
-            // this is for diagnostic producer that doesnt use compiler based DiagnosticAnalyzer such as TypeScript.
             AddExternalDiagnostics(ref _lazySyntaxLocals, documentId, diagnostics);
         }
 
         public void AddExternalSemanticDiagnostics(DocumentId documentId, IEnumerable<Diagnostic> diagnostics)
         {
             // this is for diagnostic producer that doesnt use compiler based DiagnosticAnalyzer such as TypeScript.
+            Contract.ThrowIfTrue(Project.SupportsCompilation);
+
             AddExternalDiagnostics(ref _lazySemanticLocals, documentId, diagnostics);
         }
 
         private void AddExternalDiagnostics(
             ref Dictionary<DocumentId, List<DiagnosticData>>? lazyLocals, DocumentId documentId, IEnumerable<Diagnostic> diagnostics)
         {
-            Contract.ThrowIfTrue(Project.SupportsCompilation);
-
             foreach (var diagnostic in diagnostics)
             {
                 // REVIEW: what is our plan for additional locations? 
@@ -73,16 +73,16 @@ private void AddExternalDiagnostics(
                 {
                     case LocationKind.ExternalFile:
                         {
-                            var diagnosticDocumentId = GetExternalDocumentId(Project, diagnostic);
+                            var diagnosticDocumentId = Project.GetDocumentForExternalLocation(diagnostic.Location);
                             if (documentId == diagnosticDocumentId)
                             {
                                 // local diagnostics to a file
-                                AddDocumentDiagnostic(ref lazyLocals, Project.GetDocument(diagnosticDocumentId), diagnostic);
+                                AddDocumentDiagnostic(ref lazyLocals, Project.GetTextDocument(diagnosticDocumentId), diagnostic);
                             }
                             else if (diagnosticDocumentId != null)
                             {
                                 // non local diagnostics to a file
-                                AddDocumentDiagnostic(ref _lazyNonLocals, Project.GetDocument(diagnosticDocumentId), diagnostic);
+                                AddDocumentDiagnostic(ref _lazyNonLocals, Project.GetTextDocument(diagnosticDocumentId), diagnostic);
                             }
                             else
                             {
@@ -109,7 +109,7 @@ private void AddExternalDiagnostics(
             }
         }
 
-        private void AddDocumentDiagnostic(ref Dictionary<DocumentId, List<DiagnosticData>>? map, Document? document, Diagnostic diagnostic)
+        private void AddDocumentDiagnostic(ref Dictionary<DocumentId, List<DiagnosticData>>? map, TextDocument? document, Diagnostic diagnostic)
         {
             if (document is null || !document.SupportsDiagnostics())
             {
@@ -191,14 +191,6 @@ private void AddDiagnostics(
             }
         }
 
-        private static DocumentId GetExternalDocumentId(Project project, Diagnostic diagnostic)
-        {
-            var projectId = project.Id;
-            var lineSpan = diagnostic.Location.GetLineSpan();
-
-            return project.Solution.GetDocumentIdsWithFilePath(lineSpan.Path).FirstOrDefault(id => id.ProjectId == projectId);
-        }
-
         private static ImmutableDictionary<DocumentId, ImmutableArray<DiagnosticData>> Convert(Dictionary<DocumentId, List<DiagnosticData>>? map)
         {
             return map == null ?
diff --git a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticData.cs b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticData.cs
index 14ca51dbd6ed1..934f8e10f3cdd 100644
--- a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticData.cs
+++ b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticData.cs
@@ -301,7 +301,7 @@ private static void SwapIfNeeded(ref LinePosition startLinePosition, ref LinePos
             }
         }
 
-        private static DiagnosticDataLocation? CreateLocation(Document? document, Location location)
+        private static DiagnosticDataLocation? CreateLocation(TextDocument? document, Location location)
         {
             if (document == null)
             {
@@ -337,7 +337,7 @@ public static DiagnosticData Create(Diagnostic diagnostic, Project project)
             return Create(diagnostic, project.Id, project.Language, project.Solution.Options, location: null, additionalLocations: null, additionalProperties: null);
         }
 
-        public static DiagnosticData Create(Diagnostic diagnostic, Document document)
+        public static DiagnosticData Create(Diagnostic diagnostic, TextDocument document)
         {
             var project = document.Project;
             var location = CreateLocation(document, diagnostic.Location);
@@ -403,9 +403,9 @@ private static DiagnosticData Create(
                 isSuppressed: diagnostic.IsSuppressed);
         }
 
-        private static ImmutableDictionary<string, string?>? GetAdditionalProperties(Document document, Diagnostic diagnostic)
+        private static ImmutableDictionary<string, string?>? GetAdditionalProperties(TextDocument document, Diagnostic diagnostic)
         {
-            var service = document.GetLanguageService<IDiagnosticPropertiesService>();
+            var service = document.Project.GetLanguageService<IDiagnosticPropertiesService>();
             return service?.GetAdditionalProperties(diagnostic);
         }
 
@@ -465,7 +465,7 @@ private static DiagnosticSeverity GetEffectiveSeverity(ReportDiagnostic effectiv
             }
         }
 
-        private static void GetLocationInfo(Document document, Location location, out TextSpan sourceSpan, out FileLinePositionSpan originalLineInfo, out FileLinePositionSpan mappedLineInfo)
+        private static void GetLocationInfo(TextDocument document, Location location, out TextSpan sourceSpan, out FileLinePositionSpan originalLineInfo, out FileLinePositionSpan mappedLineInfo)
         {
             var diagnosticSpanMappingService = document.Project.Solution.Workspace.Services.GetService<IWorkspaceVenusSpanMappingService>();
             if (diagnosticSpanMappingService != null)
diff --git a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticDataSerializer.cs b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticDataSerializer.cs
index 5741cee5afee8..9e657d9263f0b 100644
--- a/src/Workspaces/Core/Portable/Diagnostics/DiagnosticDataSerializer.cs
+++ b/src/Workspaces/Core/Portable/Diagnostics/DiagnosticDataSerializer.cs
@@ -39,9 +39,9 @@ public DiagnosticDataSerializer(VersionStamp analyzerVersion, VersionStamp versi
             Version = version;
         }
 
-        public async Task<bool> SerializeAsync(IPersistentStorageService persistentService, Project project, Document? document, string key, ImmutableArray<DiagnosticData> items, CancellationToken cancellationToken)
+        public async Task<bool> SerializeAsync(IPersistentStorageService persistentService, Project project, TextDocument? textDocument, string key, ImmutableArray<DiagnosticData> items, CancellationToken cancellationToken)
         {
-            Contract.ThrowIfFalse(document == null || document.Project == project);
+            Contract.ThrowIfFalse(textDocument == null || textDocument.Project == project);
 
             using var stream = SerializableBytes.CreateWritableStream();
 
@@ -54,21 +54,28 @@ public async Task<bool> SerializeAsync(IPersistentStorageService persistentServi
 
             stream.Position = 0;
 
-            var writeTask = (document != null) ?
-                storage.WriteStreamAsync(document, key, stream, cancellationToken) :
+            var writeTask = (textDocument != null) ?
+                textDocument is Document document ?
+                    storage.WriteStreamAsync(document, key, stream, cancellationToken) :
+                    storage.WriteStreamAsync(GetSerializationKeyForNonSourceDocument(textDocument, key), stream, cancellationToken) :
                 storage.WriteStreamAsync(project, key, stream, cancellationToken);
 
             return await writeTask.ConfigureAwait(false);
         }
 
-        public async ValueTask<ImmutableArray<DiagnosticData>> DeserializeAsync(IPersistentStorageService persistentService, Project project, Document? document, string key, CancellationToken cancellationToken)
+        private static string GetSerializationKeyForNonSourceDocument(TextDocument document, string key)
+            => document.Id + ";" + key;
+
+        public async ValueTask<ImmutableArray<DiagnosticData>> DeserializeAsync(IPersistentStorageService persistentService, Project project, TextDocument? textDocument, string key, CancellationToken cancellationToken)
         {
-            Contract.ThrowIfFalse(document == null || document.Project == project);
+            Contract.ThrowIfFalse(textDocument == null || textDocument.Project == project);
 
             using var storage = persistentService.GetStorage(project.Solution);
 
-            var readTask = (document != null) ?
-                storage.ReadStreamAsync(document, key, cancellationToken) :
+            var readTask = (textDocument != null) ?
+                textDocument is Document document ?
+                    storage.ReadStreamAsync(document, key, cancellationToken) :
+                    storage.ReadStreamAsync(GetSerializationKeyForNonSourceDocument(textDocument, key), cancellationToken) :
                 storage.ReadStreamAsync(project, key, cancellationToken);
 
             using var stream = await readTask.ConfigureAwait(false);
@@ -79,7 +86,7 @@ public async ValueTask<ImmutableArray<DiagnosticData>> DeserializeAsync(IPersist
                 return default;
             }
 
-            return ReadDiagnosticData(reader, project, document, cancellationToken);
+            return ReadDiagnosticData(reader, project, textDocument, cancellationToken);
         }
 
         public void WriteDiagnosticData(ObjectWriter writer, ImmutableArray<DiagnosticData> items, CancellationToken cancellationToken)
@@ -176,7 +183,7 @@ private static void WriteLocation(ObjectWriter writer, DiagnosticDataLocation? i
             writer.WriteInt32(item.MappedEndColumn);
         }
 
-        public ImmutableArray<DiagnosticData> ReadDiagnosticData(ObjectReader reader, Project project, Document? document, CancellationToken cancellationToken)
+        public ImmutableArray<DiagnosticData> ReadDiagnosticData(ObjectReader reader, Project project, TextDocument? document, CancellationToken cancellationToken)
         {
             try
             {
@@ -207,7 +214,7 @@ public ImmutableArray<DiagnosticData> ReadDiagnosticData(ObjectReader reader, Pr
             }
         }
 
-        private static ImmutableArray<DiagnosticData> ReadDiagnosticDataArray(ObjectReader reader, Project project, Document? document, CancellationToken cancellationToken)
+        private static ImmutableArray<DiagnosticData> ReadDiagnosticDataArray(ObjectReader reader, Project project, TextDocument? document, CancellationToken cancellationToken)
         {
             var count = reader.ReadInt32();
             if (count == 0)
@@ -272,7 +279,7 @@ private static ImmutableArray<DiagnosticData> ReadDiagnosticDataArray(ObjectRead
             return builder.ToImmutableAndFree();
         }
 
-        private static DiagnosticDataLocation? ReadLocation(Project project, ObjectReader reader, Document? document)
+        private static DiagnosticDataLocation? ReadLocation(Project project, ObjectReader reader, TextDocument? document)
         {
             var exists = reader.ReadBoolean();
             if (!exists)
diff --git a/src/Workspaces/Core/Portable/Diagnostics/Extensions.cs b/src/Workspaces/Core/Portable/Diagnostics/Extensions.cs
index 43f7a8a782ce6..0cde7b6e4edfb 100644
--- a/src/Workspaces/Core/Portable/Diagnostics/Extensions.cs
+++ b/src/Workspaces/Core/Portable/Diagnostics/Extensions.cs
@@ -14,6 +14,7 @@
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis.Options;
 using Microsoft.CodeAnalysis.PooledObjects;
+using Microsoft.CodeAnalysis.Shared.Extensions;
 using Microsoft.CodeAnalysis.Text;
 using Microsoft.CodeAnalysis.Workspaces.Diagnostics;
 using Roslyn.Utilities;
@@ -174,6 +175,24 @@ public static ImmutableDictionary<DiagnosticAnalyzer, DiagnosticAnalysisResultBu
                     }
                 }
 
+                foreach (var (file, diagnosticsByAnalyzerMap) in analysisResult.NonSourceFileDiagnostics)
+                {
+                    if (diagnosticsByAnalyzerMap.TryGetValue(analyzer, out diagnostics))
+                    {
+                        diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
+                        Debug.Assert(diagnostics.Length == CompilationWithAnalyzers.GetEffectiveDiagnostics(diagnostics, compilation).Count());
+
+                        if (project.GetDocumentForFile(file) is DocumentId documentId)
+                        {
+                            result.AddExternalSyntaxDiagnostics(documentId, diagnostics);
+                        }
+                        else
+                        {
+                            result.AddCompilationDiagnostics(diagnostics);
+                        }
+                    }
+                }
+
                 if (analysisResult.CompilationDiagnostics.TryGetValue(analyzer, out diagnostics))
                 {
                     diagnostics = diagnostics.Filter(diagnosticIdsToFilter);
diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ProjectExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ProjectExtensions.cs
index 186a696af6f16..fa0d0fad3d3c9 100644
--- a/src/Workspaces/Core/Portable/Shared/Extensions/ProjectExtensions.cs
+++ b/src/Workspaces/Core/Portable/Shared/Extensions/ProjectExtensions.cs
@@ -4,6 +4,8 @@
 
 #nullable enable
 
+using System.Diagnostics;
+using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.CodeAnalysis.Options;
@@ -36,5 +38,20 @@ public static async Task<bool> IsForkedProjectWithSemanticChangesAsync(this Proj
 
         internal static Project WithSolutionOptions(this Project project, OptionSet options)
             => project.Solution.WithOptions(options).GetProject(project.Id)!;
+
+        public static TextDocument? GetTextDocument(this Project project, DocumentId? documentId)
+            => project.Solution.GetTextDocument(documentId);
+
+        internal static DocumentId? GetDocumentForExternalLocation(this Project project, Location location)
+        {
+            Debug.Assert(location.Kind == LocationKind.ExternalFile);
+            return project.GetDocumentIdWithFilePath(location.GetLineSpan().Path);
+        }
+
+        internal static DocumentId? GetDocumentForFile(this Project project, AdditionalText additionalText)
+            => project.GetDocumentIdWithFilePath(additionalText.Path);
+
+        private static DocumentId? GetDocumentIdWithFilePath(this Project project, string filePath)
+            => project.Solution.GetDocumentIdsWithFilePath(filePath).FirstOrDefault(id => id.ProjectId == project.Id);
     }
 }
diff --git a/src/Workspaces/Core/Portable/SolutionCrawler/IIncrementalAnalyzer2.cs b/src/Workspaces/Core/Portable/SolutionCrawler/IIncrementalAnalyzer2.cs
new file mode 100644
index 0000000000000..0423fce9120da
--- /dev/null
+++ b/src/Workspaces/Core/Portable/SolutionCrawler/IIncrementalAnalyzer2.cs
@@ -0,0 +1,24 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Microsoft.CodeAnalysis.SolutionCrawler
+{
+    // CONSIDER: We can merge IIncrementalAnalyzer2 with IIncrementalAnalyzer once all of our
+    //           IVT partners that use IIncrementalAnalyzer have migrated to ExternalAccess layer.
+    internal interface IIncrementalAnalyzer2 : IIncrementalAnalyzer
+    {
+        Task NonSourceDocumentOpenAsync(TextDocument document, CancellationToken cancellationToken);
+        Task NonSourceDocumentCloseAsync(TextDocument document, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Resets all the document state cached by the analyzer.
+        /// </summary>
+        Task NonSourceDocumentResetAsync(TextDocument document, CancellationToken cancellationToken);
+
+        Task AnalyzeNonSourceDocumentAsync(TextDocument document, InvocationReasons reasons, CancellationToken cancellationToken);
+    }
+}
diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs
index e4a5b9310dfe4..bae54bfa04efd 100644
--- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs
+++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/DocumentExtensions.cs
@@ -58,7 +58,7 @@ public static async Task<SyntaxNode> GetRequiredSyntaxRootAsync(this Document do
             return root ?? throw new InvalidOperationException(string.Format(WorkspaceExtensionsResources.SyntaxTree_is_required_to_accomplish_the_task_but_is_not_supported_by_document_0, document.Name));
         }
 
-        public static bool IsOpen(this Document document)
+        public static bool IsOpen(this TextDocument document)
         {
             var workspace = document.Project.Solution.Workspace as Workspace;
             return workspace != null && workspace.IsDocumentOpen(document.Id);