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); } } }
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); } } }
public static string InspectActiveStatementAndInstruction( ActiveStatement statement, SourceText text ) => InspectActiveStatementAndInstruction(statement) + $" '{GetFirstLineText(statement.Span, text)}'";
public static string InspectActiveStatementAndInstruction(ActiveStatement statement) => InspectActiveStatement(statement) + " " + statement.InstructionId.GetDebuggerDisplay();
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))}]";
public static string InspectActiveStatement(ActiveStatement statement) => $"{statement.Ordinal}: {statement.FileSpan} flags=[{statement.Flags}]";