internal void VerifyUnchangedDocument(
            string source,
            ActiveStatement[] oldActiveStatements,
            TextSpan[] expectedNewActiveStatements,
            ImmutableArray <TextSpan>[] expectedNewExceptionRegions)
        {
            var text = SourceText.From(source);
            var tree = ParseText(source);
            var root = tree.GetRoot();

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

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

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

            Analyzer.GetTestAccessor().AnalyzeUnchangedDocument(
                oldActiveStatements.AsImmutable(),
                text,
                root,
                actualNewActiveStatements,
                actualNewExceptionRegions);

            // check active statements:
            AssertSpansEqual(expectedNewActiveStatements, actualNewActiveStatements.Select(s => s.Span), source, text);

            // check new exception regions:
            Assert.Equal(expectedNewExceptionRegions.Length, actualNewExceptionRegions.Length);
            for (var i = 0; i < expectedNewExceptionRegions.Length; i++)
            {
                AssertSpansEqual(expectedNewExceptionRegions[i], actualNewExceptionRegions[i], source, text);
            }
        }
        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));
            }
        }
        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);
                }
            }
        }
Exemple #4
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);
                }
            }
        }
Exemple #5
0
 public static string InspectActiveStatementAndInstruction(
     ActiveStatement statement,
     SourceText text
     ) =>
 InspectActiveStatementAndInstruction(statement)
 + $" '{GetFirstLineText(statement.Span, text)}'";
Exemple #6
0
 public static string InspectActiveStatementAndInstruction(ActiveStatement statement) =>
 InspectActiveStatement(statement) + " " + statement.InstructionId.GetDebuggerDisplay();
Exemple #7
0
 public static string InspectActiveStatement(ActiveStatement statement) =>
 $"{statement.Ordinal}: {statement.Span} flags=[{statement.Flags}] pdid={statement.PrimaryDocumentId.DebugName} docs=[{string.Join(",", statement.DocumentIds.Select(d => d.DebugName))}]";
Exemple #8
0
 public static string InspectActiveStatement(ActiveStatement statement)
 => $"{statement.Ordinal}: {statement.FileSpan} flags=[{statement.Flags}]";