internal void VerifyUnchangedDocument( string source, ActiveStatement[] oldActiveStatements, TextSpan?[]?trackingSpans, TextSpan[] expectedNewActiveStatements, ImmutableArray <TextSpan>[] expectedOldExceptionRegions, 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 spanTracker = new TestActiveStatementSpanTracker( (trackingSpans != null) ? new Dictionary <DocumentId, TextSpan?[]> { { documentId, trackingSpans } } : null); 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); } }
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 solution = Workspace.CurrentSolution; var mockDebuggeModuleProvider = new Mock <IDebuggeeModuleMetadataProvider>(); 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 mockActiveStatementTrackingService = new TestActiveStatementSpanTracker(); var telemetry = new EditSessionTelemetry(); EditSession = new EditSession(debuggingSession, telemetry, cancellationToken => Task.FromResult(activeStatements), mockActiveStatementTrackingService, mockDebuggeModuleProvider.Object); }
public TestActiveStatementSpanTrackerFactory() { ActiveStatementSpanTracker = new TestActiveStatementSpanTracker(); }
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); } } }
internal void VerifySemantics( EditScript <SyntaxNode> editScript, ActiveStatementsDescription?activeStatements = null, IEnumerable <string>?additionalOldSources = null, IEnumerable <string>?additionalNewSources = null, SemanticEditDescription[]?expectedSemanticEdits = null, DiagnosticDescription?expectedDeclarationError = null, RudeEditDiagnosticDescription[]?expectedDiagnostics = null) { activeStatements ??= ActiveStatementsDescription.Empty; var editMap = 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 <UpdatedMemberInfo>(); var triviaEdits = new List <(SyntaxNode OldNode, SyntaxNode NewNode)>(); var actualLineEdits = new List <LineChange>(); var actualSemanticEdits = new List <SemanticEdit>(); var diagnostics = new List <RudeEditDiagnostic>(); var spanTracker = new TestActiveStatementSpanTracker(); var documentId = DocumentId.CreateNewId(ProjectId.CreateNewId()); var actualNewActiveStatements = new ActiveStatement[activeStatements.OldStatements.Length]; var actualNewExceptionRegions = new ImmutableArray <LinePositionSpan> [activeStatements.OldStatements.Length]; Analyzer.GetTestAccessor().AnalyzeSyntax( editScript, editMap, oldText, newText, documentId, spanTracker, 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 (var 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) { Contract.ThrowIfNull(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); } } }