private static Solution AddDefaultTestSolution(
            TestWorkspace workspace,
            string[] markedSources
        )
        {
            var solution = workspace.CurrentSolution;

            var project = solution
                .AddProject("proj", "proj", LanguageNames.CSharp)
                .WithMetadataReferences(
                    TargetFrameworkUtil.GetReferences(TargetFramework.Standard)
                );

            solution = project.Solution;

            for (var i = 0; i < markedSources.Length; i++)
            {
                var name = $"test{i + 1}.cs";
                var text = SourceText.From(
                    ActiveStatementsDescription.ClearTags(markedSources[i]),
                    Encoding.UTF8
                );
                var id = DocumentId.CreateNewId(project.Id, name);
                solution = solution.AddDocument(
                    id,
                    name,
                    text,
                    filePath: Path.Combine(TempRoot.Root, name)
                );
            }

            workspace.ChangeSolution(solution);
            return solution;
        }
        private void VerifyActiveStatementsAndExceptionRegions(
            ActiveStatementsDescription description,
            IReadOnlyList <ActiveStatement> oldActiveStatements,
            SourceText oldText,
            SourceText newText,
            SyntaxNode oldRoot,
            IReadOnlyList <ActiveStatement> actualNewActiveStatements,
            IReadOnlyList <ImmutableArray <LinePositionSpan> > actualNewExceptionRegions)
        {
            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements.Select(s => s.Span), newText);

            // check old exception regions:
            for (var i = 0; i < oldActiveStatements.Count; i++)
            {
                var oldRegions = Analyzer.GetExceptionRegions(
                    oldText,
                    oldRoot,
                    oldActiveStatements[i].Span,
                    isNonLeaf: oldActiveStatements[i].IsNonLeaf,
                    out _);

                AssertSpansEqual(description.OldRegions[i], oldRegions, oldText);
            }

            // check new exception regions:
            Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Count);
            for (var i = 0; i < description.NewRegions.Length; i++)
            {
                AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newText);
            }
        }
            public Validator(
                string[] markedSource,
                ImmutableArray <ActiveStatementDebugInfo> activeStatements,
                ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > nonRemappableRegions = null,
                Func <Solution, Solution> adjustSolution     = null,
                CommittedSolution.DocumentState initialState = CommittedSolution.DocumentState.MatchesBuildOutput,
                bool openDocuments = false)
            {
                Workspace = TestWorkspace.CreateCSharp(ActiveStatementsDescription.ClearTags(markedSource), composition: s_composition, openDocuments: openDocuments);

                if (adjustSolution != null)
                {
                    Workspace.ChangeSolution(adjustSolution(Workspace.CurrentSolution));
                }

                var solution = Workspace.CurrentSolution;

                var mockDebuggeModuleProvider      = new Mock <IDebuggeeModuleMetadataProvider>(MockBehavior.Strict);
                var mockCompilationOutputsProvider = new Func <Project, CompilationOutputs>(_ => new MockCompilationOutputs(Guid.NewGuid()));

                var debuggingSession = new DebuggingSession(solution, mockCompilationOutputsProvider);

                if (initialState != CommittedSolution.DocumentState.None)
                {
                    EditAndContinueWorkspaceServiceTests.SetDocumentsState(debuggingSession, solution, initialState);
                }

                debuggingSession.Test_SetNonRemappableRegions(nonRemappableRegions ?? ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > .Empty);

                var telemetry = new EditSessionTelemetry();

                EditSession = new EditSession(debuggingSession, telemetry, cancellationToken => Task.FromResult(activeStatements), mockDebuggeModuleProvider.Object);
            }
            public Validator(
                string[] markedSource,
                ImmutableArray <ActiveStatementDebugInfo> activeStatements,
                ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > nonRemappableRegions = null,
                Func <Solution, Solution> adjustSolution     = null,
                CommittedSolution.DocumentState initialState = CommittedSolution.DocumentState.MatchesBuildOutput)
            {
                var exportProviderFactory = ExportProviderCache.GetOrCreateExportProviderFactory(
                    TestExportProvider.MinimumCatalogWithCSharpAndVisualBasic.WithPart(typeof(CSharpEditAndContinueAnalyzer)).WithPart(typeof(DummyLanguageService)));

                var exportProvider = exportProviderFactory.CreateExportProvider();

                Workspace = TestWorkspace.CreateCSharp(ActiveStatementsDescription.ClearTags(markedSource), exportProvider: exportProvider, openDocuments: true);

                if (adjustSolution != null)
                {
                    Workspace.ChangeSolution(adjustSolution(Workspace.CurrentSolution));
                }

                var mockDebuggeModuleProvider      = new Mock <IDebuggeeModuleMetadataProvider>();
                var mockCompilationOutputsProvider = new Func <Project, CompilationOutputs>(_ => new MockCompilationOutputs(Guid.NewGuid()));

                var debuggingSession = new DebuggingSession(Workspace, mockDebuggeModuleProvider.Object, mockCompilationOutputsProvider);

                if (initialState != CommittedSolution.DocumentState.None)
                {
                    EditAndContinueWorkspaceServiceTests.SetDocumentsState(debuggingSession, Workspace.CurrentSolution, initialState);
                }

                debuggingSession.Test_SetNonRemappableRegions(nonRemappableRegions ?? ImmutableDictionary <ActiveMethodId, ImmutableArray <NonRemappableRegion> > .Empty);

                var telemetry = new EditSessionTelemetry();

                EditSession = new EditSession(debuggingSession, telemetry, cancellationToken => Task.FromResult(activeStatements));
            }
Пример #5
0
        internal static ImmutableArray <ManagedActiveStatementDebugInfo> GetActiveStatementDebugInfos(
            string[] markedSources,
            string extension             = ".cs",
            int[] methodRowIds           = null,
            Guid[] modules               = null,
            int[] methodVersions         = null,
            int[] ilOffsets              = null,
            ActiveStatementFlags[] flags = null)
        {
            IEnumerable <(TextSpan Span, int Id, SourceText Text, string DocumentName, DocumentId DocumentId)> EnumerateAllSpans()
            {
                var sourceIndex = 0;

                foreach (var markedSource in markedSources)
                {
                    var documentName = TestWorkspace.GetDefaultTestSourceDocumentName(sourceIndex, extension);
                    var documentId   = DocumentId.CreateNewId(ProjectId.CreateNewId(), documentName);
                    var text         = SourceText.From(markedSource);

                    foreach (var(span, id) in ActiveStatementsDescription.GetActiveSpans(markedSource))
                    {
                        yield return(span, id, text, documentName, documentId);
                    }

                    sourceIndex++;
                }
            }

            IEnumerable <ManagedActiveStatementDebugInfo> Enumerate()
            {
                var moduleId = new Guid("00000000-0000-0000-0000-000000000001");
                var threadId = new Guid("00000000-0000-0000-0000-000000000010");

                var index = 0;

                foreach (var(span, id, text, documentName, documentId) in EnumerateAllSpans().OrderBy(s => s.Id))
                {
                    yield return(new ManagedActiveStatementDebugInfo(
                                     new ManagedInstructionId(
                                         new ManagedMethodId(
                                             (modules != null) ? modules[index] : moduleId,
                                             new ManagedModuleMethodId(
                                                 token: 0x06000000 | (methodRowIds != null ? methodRowIds[index] : index + 1),
                                                 version: (methodVersions != null) ? methodVersions[index] : 1)),
                                         ilOffset: (ilOffsets != null) ? ilOffsets[index] : 0),
                                     documentName: documentName,
                                     sourceSpan: text.Lines.GetLinePositionSpan(span).ToSourceSpan(),
                                     flags: (flags != null) ? flags[index] : ((id == 0 ? ActiveStatementFlags.IsLeafFrame : ActiveStatementFlags.IsNonLeafFrame) | ActiveStatementFlags.MethodUpToDate)));

                    index++;
                }
            }

            return(Enumerate().ToImmutableArray());
        }
Пример #6
0
 public static ImmutableArray <ManagedActiveStatementDebugInfo> GetActiveStatementDebugInfosCSharp(
     string[] markedSources,
     string[]?filePaths           = null,
     int[]?methodRowIds           = null,
     Guid[]?modules               = null,
     int[]?methodVersions         = null,
     int[]?ilOffsets              = null,
     ActiveStatementFlags[]?flags = null)
 {
     return(ActiveStatementsDescription.GetActiveStatementDebugInfos(
                (source, path) => SyntaxFactory.ParseSyntaxTree(source, path: path),
                markedSources,
                filePaths,
                extension: ".cs",
                methodRowIds,
                modules,
                methodVersions,
                ilOffsets,
                flags));
 }
Пример #7
0
            public Validator(
                string[] markedSource,
                ImmutableArray <ManagedActiveStatementDebugInfo> activeStatements,
                ImmutableDictionary <ManagedMethodId, ImmutableArray <NonRemappableRegion> > nonRemappableRegions = null,
                Func <Solution, Solution> adjustSolution     = null,
                CommittedSolution.DocumentState initialState = CommittedSolution.DocumentState.MatchesBuildOutput,
                bool openDocuments = false)
            {
                Workspace = TestWorkspace.CreateCSharp(ActiveStatementsDescription.ClearTags(markedSource), composition: s_composition, openDocuments: openDocuments);

                if (adjustSolution != null)
                {
                    Workspace.ChangeSolution(adjustSolution(Workspace.CurrentSolution));
                }

                var solution = Workspace.CurrentSolution;

                var mockDebuggerService = new MockManagedEditAndContinueDebuggerService()
                {
                    GetActiveStatementsImpl = () => activeStatements
                };

                var mockCompilationOutputsProvider = new Func <Project, CompilationOutputs>(_ => new MockCompilationOutputs(Guid.NewGuid()));

                var debuggingSession = new DebuggingSession(solution, mockCompilationOutputsProvider, SpecializedCollections.EmptyEnumerable <KeyValuePair <DocumentId, CommittedSolution.DocumentState> >());

                if (initialState != CommittedSolution.DocumentState.None)
                {
                    EditAndContinueWorkspaceServiceTests.SetDocumentsState(debuggingSession, solution, initialState);
                }

                debuggingSession.Test_SetNonRemappableRegions(nonRemappableRegions ?? ImmutableDictionary <ManagedMethodId, ImmutableArray <NonRemappableRegion> > .Empty);

                var telemetry = new EditSessionTelemetry();

                EditSession = new EditSession(debuggingSession, telemetry, mockDebuggerService);
            }
Пример #8
0
        private void VerifyDocumentActiveStatementsAndExceptionRegions(
            ActiveStatementsDescription description,
            SyntaxTree oldTree,
            SyntaxTree newTree,
            ImmutableArray <ActiveStatement> actualNewActiveStatements,
            ImmutableArray <ImmutableArray <SourceFileSpan> > actualNewExceptionRegions)
        {
            // check active statements:
            AssertSpansEqual(description.NewMappedSpans, actualNewActiveStatements.OrderBy(x => x.Ordinal).Select(s => s.FileSpan), newTree);

            var oldRoot = oldTree.GetRoot();

            // check old exception regions:
            foreach (var oldStatement in description.OldStatements)
            {
                var oldRegions = Analyzer.GetExceptionRegions(
                    oldRoot,
                    oldStatement.UnmappedSpan,
                    isNonLeaf: oldStatement.Statement.IsNonLeaf,
                    CancellationToken.None);

                AssertSpansEqual(oldStatement.ExceptionRegions.Spans, oldRegions.Spans, oldTree);
            }

            // check new exception regions:
            if (!actualNewExceptionRegions.IsDefault)
            {
                Assert.Equal(actualNewActiveStatements.Length, actualNewExceptionRegions.Length);
                Assert.Equal(description.NewMappedRegions.Length, actualNewExceptionRegions.Length);
                for (var i = 0; i < actualNewActiveStatements.Length; i++)
                {
                    var activeStatement = actualNewActiveStatements[i];
                    AssertSpansEqual(description.NewMappedRegions[activeStatement.Ordinal], actualNewExceptionRegions[i], newTree);
                }
            }
        }
Пример #9
0
        internal void VerifyRudeDiagnostics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription description,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var oldActiveStatements = description.OldStatements;

            if (description.OldTrackingSpans != null)
            {
                Assert.Equal(oldActiveStatements.Length, description.OldTrackingSpans.Length);
            }

            string newSource = editScript.Match.NewRoot.SyntaxTree.ToString();
            string oldSource = editScript.Match.OldRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            var diagnostics = new List <RudeEditDiagnostic>();
            var actualNewActiveStatements  = new ActiveStatement[oldActiveStatements.Length];
            var actualNewExceptionRegions  = new ImmutableArray <LinePositionSpan> [oldActiveStatements.Length];
            var updatedActiveMethodMatches = new List <AbstractEditAndContinueAnalyzer.UpdatedMemberInfo>();
            var editMap = Analyzer.BuildEditMap(editScript);

            DocumentId documentId = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");

            TestActiveStatementTrackingService trackingService;

            if (description.OldTrackingSpans != null)
            {
                trackingService = new TestActiveStatementTrackingService(documentId, description.OldTrackingSpans);
            }
            else
            {
                trackingService = null;
            }

            Analyzer.GetTestAccessor().AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                documentId,
                trackingService,
                oldActiveStatements.AsImmutable(),
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource, expectedDiagnostics);

            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements.Select(s => s.Span), newSource, newText);

            if (diagnostics.Count == 0)
            {
                // check old exception regions:
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    var actualOldExceptionRegions = Analyzer.GetExceptionRegions(
                        oldText,
                        editScript.Match.OldRoot,
                        oldActiveStatements[i].Span,
                        isNonLeaf: oldActiveStatements[i].IsNonLeaf,
                        out _);

                    AssertSpansEqual(description.OldRegions[i], actualOldExceptionRegions, oldSource, oldText);
                }

                // check new exception regions:
                Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Length);
                for (int i = 0; i < description.NewRegions.Length; i++)
                {
                    AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newSource, newText);
                }
            }
            else
            {
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    Assert.Equal(0, description.NewRegions[i].Length);
                }
            }

            if (description.OldTrackingSpans != null)
            {
                // Verify that the new tracking spans are equal to the new active statements.
                AssertEx.Equal(trackingService.TrackingSpans, description.NewSpans.Select(s => (TextSpan?)s));
            }
        }
Пример #10
0
        internal void VerifySemantics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription activeStatements,
            IEnumerable <string> additionalOldSources           = null,
            IEnumerable <string> additionalNewSources           = null,
            SemanticEditDescription[] expectedSemanticEdits     = null,
            DiagnosticDescription expectedDeclarationError      = null,
            RudeEditDiagnosticDescription[] expectedDiagnostics = null)
        {
            var editMap = Analyzer.BuildEditMap(editScript);

            var oldRoot = editScript.Match.OldRoot;
            var newRoot = editScript.Match.NewRoot;

            var oldSource = oldRoot.SyntaxTree.ToString();
            var newSource = newRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            IEnumerable <SyntaxTree> oldTrees = new[] { oldRoot.SyntaxTree };
            IEnumerable <SyntaxTree> newTrees = new[] { newRoot.SyntaxTree };

            if (additionalOldSources != null)
            {
                oldTrees = oldTrees.Concat(additionalOldSources.Select(s => ParseText(s)));
            }

            if (additionalOldSources != null)
            {
                newTrees = newTrees.Concat(additionalNewSources.Select(s => ParseText(s)));
            }

            var oldCompilation = CreateLibraryCompilation("Old", oldTrees);
            var newCompilation = CreateLibraryCompilation("New", newTrees);

            var oldModel = oldCompilation.GetSemanticModel(oldRoot.SyntaxTree);
            var newModel = newCompilation.GetSemanticModel(newRoot.SyntaxTree);

            var oldActiveStatements        = activeStatements.OldStatements.AsImmutable();
            var updatedActiveMethodMatches = new List <AbstractEditAndContinueAnalyzer.UpdatedMemberInfo>();
            var triviaEdits         = new List <KeyValuePair <SyntaxNode, SyntaxNode> >();
            var actualLineEdits     = new List <LineChange>();
            var actualSemanticEdits = new List <SemanticEdit>();
            var diagnostics         = new List <RudeEditDiagnostic>();

            var actualNewActiveStatements = new ActiveStatement[activeStatements.OldStatements.Length];
            var actualNewExceptionRegions = new ImmutableArray <LinePositionSpan> [activeStatements.OldStatements.Length];

            Analyzer.GetTestAccessor().AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                null,
                null,
                oldActiveStatements,
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource);

            Analyzer.GetTestAccessor().AnalyzeTrivia(
                oldText,
                newText,
                editScript.Match,
                editMap,
                triviaEdits,
                actualLineEdits,
                diagnostics,
                CancellationToken.None);

            diagnostics.Verify(newSource);

            Analyzer.GetTestAccessor().AnalyzeSemantics(
                editScript,
                editMap,
                oldText,
                oldActiveStatements,
                triviaEdits,
                updatedActiveMethodMatches,
                oldModel,
                newModel,
                actualSemanticEdits,
                diagnostics,
                out var firstDeclarationErrorOpt,
                CancellationToken.None);

            var actualDeclarationErrors   = (firstDeclarationErrorOpt != null) ? new[] { firstDeclarationErrorOpt } : Array.Empty <Diagnostic>();
            var expectedDeclarationErrors = (expectedDeclarationError != null) ? new[] { expectedDeclarationError } : Array.Empty <DiagnosticDescription>();

            actualDeclarationErrors.Verify(expectedDeclarationErrors);

            diagnostics.Verify(newSource, expectedDiagnostics);

            if (expectedSemanticEdits == null)
            {
                return;
            }

            Assert.Equal(expectedSemanticEdits.Length, actualSemanticEdits.Count);

            for (int i = 0; i < actualSemanticEdits.Count; i++)
            {
                var editKind = expectedSemanticEdits[i].Kind;

                Assert.Equal(editKind, actualSemanticEdits[i].Kind);

                var expectedOldSymbol = (editKind == SemanticEditKind.Update) ? expectedSemanticEdits[i].SymbolProvider(oldCompilation) : null;
                var expectedNewSymbol = expectedSemanticEdits[i].SymbolProvider(newCompilation);
                var actualOldSymbol   = actualSemanticEdits[i].OldSymbol;
                var actualNewSymbol   = actualSemanticEdits[i].NewSymbol;

                Assert.Equal(expectedOldSymbol, actualOldSymbol);
                Assert.Equal(expectedNewSymbol, actualNewSymbol);

                var expectedSyntaxMap = expectedSemanticEdits[i].SyntaxMap;
                var actualSyntaxMap   = actualSemanticEdits[i].SyntaxMap;

                Assert.Equal(expectedSemanticEdits[i].PreserveLocalVariables, actualSemanticEdits[i].PreserveLocalVariables);

                if (expectedSyntaxMap != null)
                {
                    Assert.NotNull(actualSyntaxMap);
                    Assert.True(expectedSemanticEdits[i].PreserveLocalVariables);

                    var newNodes = new List <SyntaxNode>();

                    foreach (var expectedSpanMapping in expectedSyntaxMap)
                    {
                        var newNode         = FindNode(newRoot, expectedSpanMapping.Value);
                        var expectedOldNode = FindNode(oldRoot, expectedSpanMapping.Key);
                        var actualOldNode   = actualSyntaxMap(newNode);

                        Assert.Equal(expectedOldNode, actualOldNode);

                        newNodes.Add(newNode);
                    }
                }
                else if (!expectedSemanticEdits[i].PreserveLocalVariables)
                {
                    Assert.Null(actualSyntaxMap);
                }
            }
        }
Пример #11
0
        internal void VerifyRudeDiagnostics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription description,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var oldActiveStatements = description.OldStatements;

            if (description.OldTrackingSpans != null)
            {
                Assert.Equal(oldActiveStatements.Length, description.OldTrackingSpans.Length);
            }

            var newSource = editScript.Match.NewRoot.SyntaxTree.ToString();
            var oldSource = editScript.Match.OldRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            var diagnostics = new List <RudeEditDiagnostic>();
            var actualNewActiveStatements  = new ActiveStatement[oldActiveStatements.Length];
            var actualNewExceptionRegions  = new ImmutableArray <LinePositionSpan> [oldActiveStatements.Length];
            var updatedActiveMethodMatches = new List <UpdatedMemberInfo>();
            var editMap = BuildEditMap(editScript);

            var documentId = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");

            var spanTracker = new TestActiveStatementSpanTracker(
                (description.OldTrackingSpans != null) ? new Dictionary <DocumentId, TextSpan?[]> {
                { documentId, description.OldTrackingSpans }
            } : null);

            Analyzer.GetTestAccessor().AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                documentId,
                spanTracker,
                oldActiveStatements.AsImmutable(),
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource, expectedDiagnostics);

            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements.Select(s => s.Span), newSource, newText);

            if (diagnostics.Count == 0)
            {
                // check old exception regions:
                for (var i = 0; i < oldActiveStatements.Length; i++)
                {
                    var actualOldExceptionRegions = Analyzer.GetExceptionRegions(
                        oldText,
                        editScript.Match.OldRoot,
                        oldActiveStatements[i].Span,
                        isNonLeaf: oldActiveStatements[i].IsNonLeaf,
                        out _);

                    AssertSpansEqual(description.OldRegions[i], actualOldExceptionRegions, oldSource, oldText);
                }

                // check new exception regions:
                Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Length);
                for (var i = 0; i < description.NewRegions.Length; i++)
                {
                    AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newSource, newText);
                }
            }
            else
            {
                for (var i = 0; i < oldActiveStatements.Length; i++)
                {
                    Assert.Equal(0, description.NewRegions[i].Length);
                }
            }
        }
Пример #12
0
        internal void VerifyRudeDiagnostics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription description,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var oldActiveStatements = description.OldStatements;

            if (description.OldTrackingSpans != null)
            {
                Assert.Equal(oldActiveStatements.Length, description.OldTrackingSpans.Length);
            }

            var newSource = editScript.Match.NewRoot.SyntaxTree.ToString();
            var oldSource = editScript.Match.OldRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            var diagnostics = new ArrayBuilder <RudeEditDiagnostic>();
            var updatedActiveMethodMatches = new ArrayBuilder <UpdatedMemberInfo>();
            var actualNewActiveStatements  = ImmutableArray.CreateBuilder <ActiveStatement>(oldActiveStatements.Length);

            actualNewActiveStatements.Count = actualNewActiveStatements.Capacity;
            var actualNewExceptionRegions = ImmutableArray.CreateBuilder <ImmutableArray <LinePositionSpan> >(oldActiveStatements.Length);

            actualNewExceptionRegions.Count = actualNewExceptionRegions.Capacity;
            var editMap = BuildEditMap(editScript);

            var documentId   = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");
            var testAccessor = Analyzer.GetTestAccessor();

            testAccessor.AnalyzeMemberBodiesSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                oldActiveStatements.AsImmutable(),
                description.OldTrackingSpans.ToImmutableArrayOrEmpty(),
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            testAccessor.ReportTopLevelSynctactiveRudeEdits(diagnostics, editScript, editMap);

            diagnostics.Verify(newSource, expectedDiagnostics);

            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements.Select(s => s.Span), newSource, newText);

            if (diagnostics.Count == 0)
            {
                // check old exception regions:
                for (var i = 0; i < oldActiveStatements.Length; i++)
                {
                    var actualOldExceptionRegions = Analyzer.GetExceptionRegions(
                        oldText,
                        editScript.Match.OldRoot,
                        oldActiveStatements[i].Span,
                        isNonLeaf: oldActiveStatements[i].IsNonLeaf,
                        out _);

                    AssertSpansEqual(description.OldRegions[i], actualOldExceptionRegions, oldSource, oldText);
                }

                // check new exception regions:
                Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Count);
                for (var i = 0; i < description.NewRegions.Length; i++)
                {
                    AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newSource, newText);
                }
            }
            else
            {
                for (var i = 0; i < oldActiveStatements.Length; i++)
                {
                    Assert.Equal(0, description.NewRegions[i].Length);
                }
            }
        }
Пример #13
0
        internal void VerifySemantics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription activeStatements,
            IEnumerable <string> additionalOldSources,
            IEnumerable <string> additionalNewSources,
            SemanticEditDescription[] expectedSemanticEdits,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var editMap = Analyzer.BuildEditMap(editScript);

            var oldRoot = editScript.Match.OldRoot;
            var newRoot = editScript.Match.NewRoot;

            var oldSource = oldRoot.SyntaxTree.ToString();
            var newSource = newRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            IEnumerable <SyntaxTree> oldTrees = new[] { oldRoot.SyntaxTree };
            IEnumerable <SyntaxTree> newTrees = new[] { newRoot.SyntaxTree };

            if (additionalOldSources != null)
            {
                oldTrees = oldTrees.Concat(additionalOldSources.Select(s => ParseText(s)));
            }

            if (additionalOldSources != null)
            {
                newTrees = newTrees.Concat(additionalNewSources.Select(s => ParseText(s)));
            }

            var oldCompilation = CreateLibraryCompilation("Old", oldTrees);
            var newCompilation = CreateLibraryCompilation("New", newTrees);

            oldTrees.SelectMany(tree => tree.GetDiagnostics()).Where(d => d.Severity == DiagnosticSeverity.Error).Verify();
            newTrees.SelectMany(tree => tree.GetDiagnostics()).Where(d => d.Severity == DiagnosticSeverity.Error).Verify();

            var oldModel = oldCompilation.GetSemanticModel(oldRoot.SyntaxTree);
            var newModel = newCompilation.GetSemanticModel(newRoot.SyntaxTree);

            var oldActiveStatements        = activeStatements.OldSpans.AsImmutable();
            var updatedActiveMethodMatches = new List <ValueTuple <int, Match <SyntaxNode> > >();
            var triviaEdits         = new List <KeyValuePair <SyntaxNode, SyntaxNode> >();
            var actualLineEdits     = new List <LineChange>();
            var actualSemanticEdits = new List <SemanticEdit>();
            var diagnostics         = new List <RudeEditDiagnostic>();

            var actualNewActiveStatements = new LinePositionSpan[activeStatements.OldSpans.Length];
            var actualNewExceptionRegions = new ImmutableArray <LinePositionSpan> [activeStatements.OldSpans.Length];

            Analyzer.AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                null,
                null,
                oldActiveStatements,
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource);

            Analyzer.AnalyzeTrivia(
                oldText,
                newText,
                editScript.Match,
                editMap,
                triviaEdits,
                actualLineEdits,
                diagnostics,
                default(CancellationToken));

            diagnostics.Verify(newSource);

            Analyzer.AnalyzeSemantics(
                editScript,
                editMap,
                oldText,
                oldActiveStatements,
                triviaEdits,
                updatedActiveMethodMatches,
                oldModel,
                newModel,
                actualSemanticEdits,
                diagnostics,
                default(CancellationToken));

            diagnostics.Verify(newSource, expectedDiagnostics);

            if (expectedSemanticEdits == null)
            {
                return;
            }

            Assert.Equal(expectedSemanticEdits.Length, actualSemanticEdits.Count);

            for (int i = 0; i < actualSemanticEdits.Count; i++)
            {
                var editKind = expectedSemanticEdits[i].Kind;

                Assert.Equal(editKind, actualSemanticEdits[i].Kind);

                var expectedOldSymbol = (editKind == SemanticEditKind.Update) ? expectedSemanticEdits[i].SymbolProvider(oldCompilation) : null;
                var expectedNewSymbol = expectedSemanticEdits[i].SymbolProvider(newCompilation);
                var actualOldSymbol   = actualSemanticEdits[i].OldSymbol;
                var actualNewSymbol   = actualSemanticEdits[i].NewSymbol;

                Assert.Equal(expectedOldSymbol, actualOldSymbol);
                Assert.Equal(expectedNewSymbol, actualNewSymbol);

                var expectedSyntaxMap = expectedSemanticEdits[i].SyntaxMap;
                var actualSyntaxMap   = actualSemanticEdits[i].SyntaxMap;

                Assert.Equal(expectedSemanticEdits[i].PreserveLocalVariables, actualSemanticEdits[i].PreserveLocalVariables);

                if (expectedSyntaxMap != null)
                {
                    Assert.NotNull(actualSyntaxMap);
                    Assert.True(expectedSemanticEdits[i].PreserveLocalVariables);

                    var newNodes = new List <SyntaxNode>();

                    foreach (var expectedSpanMapping in expectedSyntaxMap)
                    {
                        var newNode         = FindNode(newRoot, expectedSpanMapping.Value);
                        var expectedOldNode = FindNode(oldRoot, expectedSpanMapping.Key);
                        var actualOldNode   = actualSyntaxMap(newNode);

                        Assert.Equal(expectedOldNode, actualOldNode);

                        newNodes.Add(newNode);
                    }

                    AssertEx.SetEqual(newNodes, GetDeclarators(actualNewSymbol));
                }
                else
                {
                    Assert.Null(actualSyntaxMap);
                }
            }
        }
Пример #14
0
        internal void VerifyRudeDiagnostics(
            EditScript <SyntaxNode> editScript,
            ActiveStatementsDescription description,
            RudeEditDiagnosticDescription[] expectedDiagnostics)
        {
            var oldActiveStatements = description.OldSpans;

            if (description.TrackingSpans != null)
            {
                Assert.Equal(oldActiveStatements.Length, description.TrackingSpans.Length);
            }

            string newSource = editScript.Match.NewRoot.SyntaxTree.ToString();
            string oldSource = editScript.Match.OldRoot.SyntaxTree.ToString();

            var oldText = SourceText.From(oldSource);
            var newText = SourceText.From(newSource);

            var diagnostics = new List <RudeEditDiagnostic>();
            var actualNewActiveStatements  = new LinePositionSpan[oldActiveStatements.Length];
            var actualNewExceptionRegions  = new ImmutableArray <LinePositionSpan> [oldActiveStatements.Length];
            var updatedActiveMethodMatches = new List <ValueTuple <int, IReadOnlyDictionary <SyntaxNode, SyntaxNode> > >();
            var editMap = Analyzer.BuildEditMap(editScript);

            DocumentId documentId = DocumentId.CreateNewId(ProjectId.CreateNewId("TestEnCProject"), "TestEnCDocument");

            TestActiveStatementTrackingService trackingService;

            if (description.TrackingSpans != null)
            {
                trackingService = new TestActiveStatementTrackingService(documentId, description.TrackingSpans);
            }
            else
            {
                trackingService = null;
            }

            Analyzer.AnalyzeSyntax(
                editScript,
                editMap,
                oldText,
                newText,
                documentId,
                trackingService,
                oldActiveStatements.AsImmutable(),
                actualNewActiveStatements,
                actualNewExceptionRegions,
                updatedActiveMethodMatches,
                diagnostics);

            diagnostics.Verify(newSource, expectedDiagnostics);

            // check active statements:
            AssertSpansEqual(description.NewSpans, actualNewActiveStatements, newSource, newText);

            if (diagnostics.Count == 0)
            {
                // check old exception regions:
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    var actualOldExceptionRegions = Analyzer.GetExceptionRegions(
                        oldText,
                        editScript.Match.OldRoot,
                        oldActiveStatements[i].Span,
                        isLeaf: (oldActiveStatements[i].Flags & ActiveStatementFlags.LeafFrame) != 0);

                    AssertSpansEqual(description.OldRegions[i], actualOldExceptionRegions, oldSource, oldText);
                }

                // check new exception regions:
                Assert.Equal(description.NewRegions.Length, actualNewExceptionRegions.Length);
                for (int i = 0; i < description.NewRegions.Length; i++)
                {
                    AssertSpansEqual(description.NewRegions[i], actualNewExceptionRegions[i], newSource, newText);
                }
            }
            else
            {
                for (int i = 0; i < oldActiveStatements.Length; i++)
                {
                    Assert.Equal(0, description.NewRegions[i].Length);
                }
            }

            if (description.TrackingSpans != null)
            {
                AssertEx.Equal(trackingService.TrackingSpans, description.NewSpans.Select(s => (TextSpan?)s));
            }
        }