internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var diagnosticWaiter = new DiagnosticServiceWaiter();
            var diagnosticListeners = SpecializedCollections.SingletonEnumerable(new Lazy<IAsynchronousOperationListener, FeatureMetadata>(
                () => diagnosticWaiter, new FeatureMetadata(new Dictionary<string, object>() { { "FeatureName", FeatureAttribute.DiagnosticService } })));

            var optionsService = workspace.Services.GetService<IOptionService>();
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), diagnosticListeners);

            var squiggleWaiter = new ErrorSquiggleWaiter();
            var foregroundService = new TestForegroundNotificationService();

            var buffer = document.GetTextBuffer();
            var taggerSource = new DiagnosticsSquiggleTaggerProvider.TagSource(buffer, foregroundService, diagnosticService, optionsService, squiggleWaiter);

            source.RaiseDiagnosticsUpdated(updateArgs);

            diagnosticWaiter.CreateWaitTask().PumpingWait();
            squiggleWaiter.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var intervalTree = taggerSource.GetTagIntervalTreeForBuffer(buffer);
            var spans = intervalTree.GetIntersectingSpans(new SnapshotSpan(snapshot, 0, snapshot.Length));

            taggerSource.TestOnly_Dispose();

            return spans;
        }
        internal static IList<ITagSpan<IErrorTag>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();

            var listener = new AsynchronousOperationListener();
            var listeners = AsynchronousOperationListener.CreateListeners(
                ValueTuple.Create(FeatureAttribute.DiagnosticService, listener),
                ValueTuple.Create(FeatureAttribute.ErrorSquiggles, listener));

            var optionsService = workspace.Services.GetService<IOptionService>();
            var diagnosticService = new DiagnosticService(SpecializedCollections.SingletonEnumerable<IDiagnosticUpdateSource>(source), listeners);

            var foregroundService = workspace.GetService<IForegroundNotificationService>();  //new TestForegroundNotificationService();

            var buffer = document.GetTextBuffer();
            var provider = new DiagnosticsSquiggleTaggerProvider(optionsService, diagnosticService, foregroundService, listeners);
            var tagger = provider.CreateTagger<IErrorTag>(buffer);

            source.RaiseDiagnosticsUpdated(updateArgs);

            listener.CreateWaitTask().PumpingWait();

            var snapshot = buffer.CurrentSnapshot;
            var spans = tagger.GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(snapshot, 0, snapshot.Length))).ToImmutableArray();

            ((IDisposable)tagger).Dispose();

            return spans;
        }
        public EncapsulateFieldTestState(TestWorkspace workspace)
        {
            Workspace = workspace;
            _testDocument = Workspace.Documents.Single(d => d.CursorPosition.HasValue || d.SelectedSpans.Any());
            TargetDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id);

            var notificationService = Workspace.Services.GetService<INotificationService>() as INotificationServiceCallback;
            var callback = new Action<string, string, NotificationSeverity>((message, title, severity) => NotificationMessage = message);
            notificationService.NotificationCallback = callback;
        }
        public EncapsulateFieldTestState(string markup)
        {
            Workspace = CSharpWorkspaceFactory.CreateWorkspaceFromFile(markup, exportProvider: s_exportProvider);
            _testDocument = Workspace.Documents.Single(d => d.CursorPosition.HasValue || d.SelectedSpans.Any());
            TargetDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id);

            var notificationService = Workspace.Services.GetService<INotificationService>() as INotificationServiceCallback;
            var callback = new Action<string, string, NotificationSeverity>((message, title, severity) => NotificationMessage = message);
            notificationService.NotificationCallback = callback;
        }
        public RenameTrackingTestState(
            string markup,
            string languageName,
            bool onBeforeGlobalSymbolRenamedReturnValue = true,
            bool onAfterGlobalSymbolRenamedReturnValue = true)
        {
            this.Workspace = CreateTestWorkspace(markup, languageName, TestExportProvider.CreateExportProviderWithCSharpAndVisualBasic());

            _hostDocument = Workspace.Documents.First();
            _view = _hostDocument.GetTextView();
            _view.Caret.MoveTo(new SnapshotPoint(_view.TextSnapshot, _hostDocument.CursorPosition.Value));
            _editorOperations = Workspace.GetService<IEditorOperationsFactoryService>().GetEditorOperations(_view);
            _historyRegistry = Workspace.ExportProvider.GetExport<ITextUndoHistoryRegistry>().Value;
            _mockRefactorNotifyService = new MockRefactorNotifyService
            {
                OnBeforeSymbolRenamedReturnValue = onBeforeGlobalSymbolRenamedReturnValue,
                OnAfterSymbolRenamedReturnValue = onAfterGlobalSymbolRenamedReturnValue
            };

            var optionService = this.Workspace.Services.GetService<IOptionService>();

            // Mock the action taken by the workspace INotificationService
            var notificationService = Workspace.Services.GetService<INotificationService>() as INotificationServiceCallback;
            var callback = new Action<string, string, NotificationSeverity>((message, title, severity) => _notificationMessage = message);
            notificationService.NotificationCallback = callback;

            var tracker = new RenameTrackingTaggerProvider(
                _historyRegistry,
                Workspace.ExportProvider.GetExport<Host.IWaitIndicator>().Value,
                Workspace.ExportProvider.GetExport<IInlineRenameService>().Value,
                Workspace.ExportProvider.GetExport<IDiagnosticAnalyzerService>().Value,
                SpecializedCollections.SingletonEnumerable(_mockRefactorNotifyService),
                Workspace.ExportProvider.GetExports<IAsynchronousOperationListener, FeatureMetadata>());

            _tagger = tracker.CreateTagger<RenameTrackingTag>(_hostDocument.GetTextBuffer());

            if (languageName == LanguageNames.CSharp)
            {
                _codeFixProvider = new CSharpRenameTrackingCodeFixProvider(
                    Workspace.ExportProvider.GetExport<Host.IWaitIndicator>().Value,
                    _historyRegistry,
                    SpecializedCollections.SingletonEnumerable(_mockRefactorNotifyService));
            }
            else if (languageName == LanguageNames.VisualBasic)
            {
                _codeFixProvider = new VisualBasicRenameTrackingCodeFixProvider(
                    Workspace.ExportProvider.GetExport<Host.IWaitIndicator>().Value,
                    _historyRegistry,
                    SpecializedCollections.SingletonEnumerable(_mockRefactorNotifyService));
            }
            else
            {
                throw new ArgumentException("Invalid langauge name: " + languageName, "languageName");
            }
        }
        public ChangeSignatureTestState(TestWorkspace workspace)
        {
            Workspace = workspace;
            _testDocument = Workspace.Documents.SingleOrDefault(d => d.CursorPosition.HasValue);

            if (_testDocument == null)
            {
                throw new ArgumentException("markup does not contain a cursor position", "workspace");
            }

            InvocationDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id);
            ChangeSignatureService = InvocationDocument.GetLanguageService<AbstractChangeSignatureService>();
        }
        public ExtractInterfaceTestState(TestWorkspace workspace)
        {
            Workspace = workspace;

            OriginalSolution = Workspace.CurrentSolution;
            _testDocument = Workspace.Documents.SingleOrDefault(d => d.CursorPosition.HasValue);

            if (_testDocument == null)
            {
                throw new ArgumentException("markup does not contain a cursor position", nameof(workspace));
            }

            ExtractFromDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id);
            ExtractInterfaceService = ExtractFromDocument.GetLanguageService<AbstractExtractInterfaceService>();
        }
        internal static async Task<IList<ITagSpan<IErrorTag>>> GetErrorsFromUpdateSource(TestWorkspace workspace, TestHostDocument document, DiagnosticsUpdatedArgs updateArgs)
        {
            var source = new TestDiagnosticUpdateSource();
            using (var wrapper = new DiagnosticTaggerWrapper(workspace, source))
            {
                var tagger = wrapper.TaggerProvider.CreateTagger<IErrorTag>(workspace.Documents.First().GetTextBuffer());
                using (var disposable = tagger as IDisposable)
                {
                    source.RaiseDiagnosticsUpdated(updateArgs);

                    await wrapper.WaitForTags();

                    var snapshot = workspace.Documents.First().GetTextBuffer().CurrentSnapshot;
                    var spans = tagger.GetTags(snapshot.GetSnapshotSpanCollection()).ToImmutableArray();

                    return spans;
                }
            }
        }
Example #9
0
        private GenerateTypeTestState(string projectToBeModified, string typeName, string existingFileName, TestWorkspace testWorkspace)
        {
            Workspace = testWorkspace;
            _testDocument = Workspace.Documents.SingleOrDefault(d => d.CursorPosition.HasValue);

            if (_testDocument == null)
            {
                throw new ArgumentException("markup does not contain a cursor position", "workspace");
            }

            TriggeredProject = Workspace.CurrentSolution.GetProject(_testDocument.Project.Id);

            if (projectToBeModified == null)
            {
                // Select the project from which the Codefix was triggered
                ProjectToBeModified = Workspace.CurrentSolution.GetProject(_testDocument.Project.Id);
            }
            else
            {
                ProjectToBeModified = Workspace.CurrentSolution.Projects.FirstOrDefault(proj => proj.Name.Equals(projectToBeModified));
                if (ProjectToBeModified == null)
                {
                    throw new ArgumentException("Project with the given name does not exist", "workspace");
                }
            }

            InvocationDocument = Workspace.CurrentSolution.GetDocument(_testDocument.Id);
            if (projectToBeModified == null && existingFileName == null)
            {
                ExistingDocument = InvocationDocument;
            }
            else if (existingFileName != null)
            {
                ExistingDocument = ProjectToBeModified.Documents.FirstOrDefault(doc => doc.Name.Equals(existingFileName));
            }

            TypeName = typeName;
        }
Example #10
0
        public void TestGetCompilationOnCrossLanguageDependentProjectChangedInProgress()
        {
            using (var workspace = CreateWorkspace(disablePartialSolutions: false))
            {
                var solutionX = workspace.CurrentSolution;

                var document1 = new TestHostDocument(@"public class C { }");
                var project1 = new TestHostProject(workspace, document1, name: "project1");

                var document2 = new TestHostDocument("Public Class D \r\n  Inherits C\r\nEnd Class");
                var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 });

                workspace.AddTestProject(project1);
                workspace.AddTestProject(project2);

                var solutionY = workspace.CurrentSolution;
                var id1 = solutionY.Projects.First(p => p.Name == project1.Name).Id;
                var id2 = solutionY.Projects.First(p => p.Name == project2.Name).Id;

                var compilation2y = solutionY.GetProject(id2).GetCompilationAsync().Result;
                var errors = compilation2y.GetDiagnostics();
                var classDy = compilation2y.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                var classCy = classDy.BaseType;
                Assert.NotEqual(TypeKind.Error, classCy.TypeKind);

                // open both documents so background compiler works on their compilations
                workspace.OnDocumentOpened(document1.Id, document1.GetOpenTextContainer());
                workspace.OnDocumentOpened(document2.Id, document2.GetOpenTextContainer());

                // change C to X
                var buffer1 = document1.GetTextBuffer();
                buffer1.Replace(new Span(13, 1), "X");

                var foundTheError = false;
                for (int iter = 0; iter < 10; iter++)
                {
                    WaitHelper.WaitForDispatchedOperationsToComplete(System.Windows.Threading.DispatcherPriority.ApplicationIdle);
                    Thread.Sleep(1000);

                    // the current solution should eventually have the change
                    var cs = workspace.CurrentSolution;
                    var doc1Z = cs.GetDocument(document1.Id);
                    var hasX = doc1Z.GetTextAsync().Result.ToString().Contains("X");

                    if (hasX)
                    {
                        var doc2Z = cs.GetDocument(document2.Id);
                        var partialDoc2Z = doc2Z.WithFrozenPartialSemanticsAsync(CancellationToken.None).Result;
                        var compilation2Z = partialDoc2Z.Project.GetCompilationAsync().Result;
                        var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                        var classCz = classDz.BaseType;

                        if (classCz.TypeKind == TypeKind.Error)
                        {
                            foundTheError = true;
                            break;
                        }
                    }
                }

                Assert.True(foundTheError, "Did not find error");
            }
        }
Example #11
0
        public TestHostDocument CreateProjectionBufferDocument(
            string markup,
            IList <TestHostDocument> baseDocuments,
            string path = "projectionbufferdocumentpath",
            ProjectionBufferOptions options      = ProjectionBufferOptions.None,
            IProjectionEditResolver?editResolver = null)
        {
            GetSpansAndCaretFromSurfaceBufferMarkup(markup, baseDocuments,
                                                    out var projectionBufferSpans, out var mappedSpans, out var mappedCaretLocation);

            var projectionBufferFactory = this.GetService <IProjectionBufferFactoryService>();
            var projectionBuffer        = projectionBufferFactory.CreateProjectionBuffer(editResolver, projectionBufferSpans, options);

            // Add in mapped spans from each of the base documents
            foreach (var document in baseDocuments)
            {
                mappedSpans[string.Empty] = mappedSpans.ContainsKey(string.Empty)
                    ? mappedSpans[string.Empty]
                    : ImmutableArray <TextSpan> .Empty;
                foreach (var span in document.SelectedSpans)
                {
                    var snapshotSpan = span.ToSnapshotSpan(document.GetTextBuffer().CurrentSnapshot);
                    var mappedSpan   = projectionBuffer.CurrentSnapshot.MapFromSourceSnapshot(snapshotSpan).Single();
                    mappedSpans[string.Empty] = mappedSpans[string.Empty].Add(mappedSpan.ToTextSpan());
                }

                // Order unnamed spans as they would be ordered by the normal span finding
                // algorithm in MarkupTestFile
                mappedSpans[string.Empty] = mappedSpans[string.Empty].OrderBy(s => s.End).ThenBy(s => - s.Start).ToImmutableArray();

                foreach (var kvp in document.AnnotatedSpans)
                {
                    mappedSpans[kvp.Key] = mappedSpans.ContainsKey(kvp.Key)
                        ? mappedSpans[kvp.Key]
                        : ImmutableArray <TextSpan> .Empty;

                    foreach (var span in kvp.Value)
                    {
                        var snapshotSpan = span.ToSnapshotSpan(document.GetTextBuffer().CurrentSnapshot);
                        var mappedSpan   = projectionBuffer.CurrentSnapshot.MapFromSourceSnapshot(snapshotSpan).Cast <Span?>().SingleOrDefault();
                        if (mappedSpan == null)
                        {
                            // not all span on subject buffer needs to exist on surface buffer
                            continue;
                        }

                        // but if they do, it must be only 1
                        mappedSpans[kvp.Key] = mappedSpans[kvp.Key].Add(mappedSpan.Value.ToTextSpan());
                    }
                }
            }

            var projectionDocument = new TestHostDocument(
                ExportProvider,
                languageServiceProvider: null,
                projectionBuffer.CurrentSnapshot.GetText(),
                path,
                mappedCaretLocation,
                mappedSpans,
                textBuffer: projectionBuffer);

            this.ProjectionDocuments.Add(projectionDocument);
            return(projectionDocument);
        }
Example #12
0
 internal void AddAnalyzerConfigDocument(TestHostDocument document)
 {
     this.AnalyzerConfigDocuments = this.AnalyzerConfigDocuments.Concat(new TestHostDocument[] { document });
     document.SetProject(this);
 }
Example #13
0
        public void TestAdditionalFile_OpenClose()
        {
            using (var workspace = CreateWorkspace())
            {
                var startText = @"<setting value = ""foo""";
                var document = new TestHostDocument("public class C { }");
                var additionalDoc = new TestHostDocument(startText);
                var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc });

                workspace.AddTestProject(project1);
                var buffer = additionalDoc.GetTextBuffer();
                var doc = workspace.CurrentSolution.GetAdditionalDocument(additionalDoc.Id);
                var text = doc.GetTextAsync(CancellationToken.None).PumpingWaitResult();
                var version = doc.GetTextVersionAsync(CancellationToken.None).PumpingWaitResult();

                workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer());

                // We don't have a GetOpenAdditionalDocumentIds since we don't need it. But make sure additional documents
                // don't creep into OpenDocumentIds (Bug: 1087470)
                Assert.Empty(workspace.GetOpenDocumentIds());

                workspace.OnAdditionalDocumentClosed(additionalDoc.Id, TextLoader.From(TextAndVersion.Create(text, version)));

                // Reopen and close to make sure we are not leaking anything.
                workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer());
                workspace.OnAdditionalDocumentClosed(additionalDoc.Id, TextLoader.From(TextAndVersion.Create(text, version)));
                Assert.Empty(workspace.GetOpenDocumentIds());
            }
        }
Example #14
0
        public void TestAdditionalFile_Properties()
        {
            using (var workspace = CreateWorkspace())
            {
                var document = new TestHostDocument("public class C { }");
                var additionalDoc = new TestHostDocument("some text");
                var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc });

                workspace.AddTestProject(project1);

                var project = workspace.CurrentSolution.Projects.Single();

                Assert.Equal(1, project.Documents.Count());
                Assert.Equal(1, project.AdditionalDocuments.Count());
                Assert.Equal(1, project.AdditionalDocumentIds.Count);

                var doc = project.GetDocument(additionalDoc.Id);
                Assert.Null(doc);

                var additionalDocument = project.GetAdditionalDocument(additionalDoc.Id);

                Assert.Equal("some text", additionalDocument.GetTextAsync().PumpingWaitResult().ToString());
            }
        }
Example #15
0
 internal void RemoveAdditionalDocument(TestHostDocument document)
 => this.AdditionalDocuments = this.AdditionalDocuments.Where(d => d != document);
Example #16
0
        public void TestGetCompilationOnCrossLanguageDependentProject()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document1 = new TestHostDocument(@"public class C { }");
                var project1 = new TestHostProject(workspace, document1, name: "project1");

                var document2 = new TestHostDocument("Public Class D \r\n  Inherits C\r\nEnd Class");
                var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 });

                workspace.AddTestProject(project1);
                workspace.AddTestProject(project2);

                var snapshot = workspace.CurrentSolution;
                var id1 = snapshot.Projects.First(p => p.Name == project1.Name).Id;
                var id2 = snapshot.Projects.First(p => p.Name == project2.Name).Id;

                var compilation2 = snapshot.GetProject(id2).GetCompilationAsync().Result;
                var classD = compilation2.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                var classC = classD.BaseType;
            }
        }
Example #17
0
        public void TestRemoveOpenedDocument()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document = new TestHostDocument(string.Empty);
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);
                workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer());

                Assert.Throws<ArgumentException>(() => workspace.OnDocumentRemoved(document.Id));

                workspace.OnDocumentClosed(document.Id);
                workspace.OnProjectRemoved(project1.Id);
            }
        }
Example #18
0
 internal void RemoveAnalyzerConfigDocument(TestHostDocument document)
 => this.AnalyzerConfigDocuments = this.AnalyzerConfigDocuments.Where(d => d != document);
        private static IList <TestHostProject> CreateSubmissions(
            TestWorkspace workspace,
            IEnumerable <XElement> submissionElements,
            ExportProvider exportProvider)
        {
            var submissions     = new List <TestHostProject>();
            var submissionIndex = 0;

            foreach (var submissionElement in submissionElements)
            {
                var submissionName = "Submission" + (submissionIndex++);

                var languageName = GetLanguage(workspace, submissionElement);

                // The document
                var markupCode = submissionElement.NormalizedValue();
                MarkupTestFile.GetPositionAndSpans(markupCode,
                                                   out var code, out var cursorPosition, out IDictionary <string, ImmutableArray <TextSpan> > spans);

                var languageServices           = workspace.Services.GetLanguageServices(languageName);
                var contentTypeLanguageService = languageServices.GetService <IContentTypeLanguageService>();

                var contentType = contentTypeLanguageService.GetDefaultContentType();
                var textBuffer  = EditorFactory.CreateBuffer(contentType.TypeName, exportProvider, code);

                // The project

                var document  = new TestHostDocument(exportProvider, languageServices, textBuffer, submissionName, cursorPosition, spans, SourceCodeKind.Script);
                var documents = new List <TestHostDocument> {
                    document
                };

                if (languageName == NoCompilationConstants.LanguageName)
                {
                    submissions.Add(
                        new TestHostProject(
                            languageServices,
                            compilationOptions: null,
                            parseOptions: null,
                            assemblyName: submissionName,
                            projectName: submissionName,
                            references: null,
                            documents: documents,
                            isSubmission: true));
                    continue;
                }

                var syntaxFactory      = languageServices.GetService <ISyntaxTreeFactoryService>();
                var compilationFactory = languageServices.GetService <ICompilationFactoryService>();
                var compilationOptions = compilationFactory.GetDefaultCompilationOptions().WithOutputKind(OutputKind.DynamicallyLinkedLibrary);

                var parseOptions = syntaxFactory.GetDefaultParseOptions().WithKind(SourceCodeKind.Script);

                var references = CreateCommonReferences(workspace, submissionElement);

                var project = new TestHostProject(
                    languageServices,
                    compilationOptions,
                    parseOptions,
                    submissionName,
                    submissionName,
                    references,
                    documents,
                    isSubmission: true);

                submissions.Add(project);
            }

            return(submissions);
        }
Example #20
0
 internal void RemoveDocument(TestHostDocument document)
 => this.Documents = this.Documents.Where(d => d != document);
Example #21
0
 internal TestDocumentLoader(TestHostDocument hostDocument, string text)
 {
     _hostDocument = hostDocument;
     _text         = text;
 }
Example #22
0
        public void TestChangeOptions2()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document = new TestHostDocument(
@"#if FOO
class C { }
#else
class D { }
#endif");

                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);
                workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer());

                VerifyRootTypeName(workspace, "D");

                workspace.OnParseOptionsChanged(document.Id.ProjectId,
                    new CSharpParseOptions(preprocessorSymbols: new[] { "FOO" }));

                VerifyRootTypeName(workspace, "C");

                workspace.OnDocumentClosed(document.Id);
            }
        }
Example #23
0
        public void TestApplyChangesWithDocumentTextUpdated()
        {
            using (var workspace = CreateWorkspace())
            {
                var startText = "public class C { }";
                var newText = "public class D { }";

                var document = new TestHostDocument(startText);
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);
                var buffer = document.GetTextBuffer();
                workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer());

                // prove the document has the correct text
                Assert.Equal(startText, workspace.CurrentSolution.GetDocument(document.Id).GetTextAsync().PumpingWaitResult().ToString());

                // fork the solution to introduce a change.
                var oldSolution = workspace.CurrentSolution;
                var newSolution = oldSolution.WithDocumentText(document.Id, SourceText.From(newText));

                // prove that current document text is unchanged
                Assert.Equal(startText, workspace.CurrentSolution.GetDocument(document.Id).GetTextAsync().PumpingWaitResult().ToString());

                // prove buffer is unchanged too
                Assert.Equal(startText, buffer.CurrentSnapshot.GetText());

                workspace.TryApplyChanges(newSolution);

                // new text should have been pushed into buffer
                Assert.Equal(newText, buffer.CurrentSnapshot.GetText());
            }
        }
Example #24
0
        public void TestGetCompilation()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document = new TestHostDocument(@"class C { }");
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);
                VerifyRootTypeName(workspace, "C");

                var snapshot = workspace.CurrentSolution;
                var id1 = snapshot.Projects.First(p => p.Name == project1.Name).Id;

                var compilation = snapshot.GetProject(id1).GetCompilationAsync().Result;
                var classC = compilation.SourceModule.GlobalNamespace.GetMembers("C").Single();
            }
        }
Example #25
0
        public void TestApplyChangesWithDocumentRemoved()
        {
            using (var workspace = CreateWorkspace())
            {
                var doc1Text = "public class C { }";

                var document = new TestHostDocument(doc1Text);
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);

                // fork the solution to introduce a change.
                var oldSolution = workspace.CurrentSolution;
                var newSolution = oldSolution.RemoveDocument(document.Id);

                workspace.TryApplyChanges(newSolution);

                // document should have been removed
                Assert.Equal(0, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count());
            }
        }
Example #26
0
        public void TestGetCompilationOnCrossLanguageDependentProjectChanged()
        {
            using (var workspace = CreateWorkspace())
            {
                var solutionX = workspace.CurrentSolution;

                var document1 = new TestHostDocument(@"public class C { }");
                var project1 = new TestHostProject(workspace, document1, name: "project1");

                var document2 = new TestHostDocument("Public Class D \r\n  Inherits C\r\nEnd Class");
                var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 });

                workspace.AddTestProject(project1);
                workspace.AddTestProject(project2);

                var solutionY = workspace.CurrentSolution;
                var id1 = solutionY.Projects.First(p => p.Name == project1.Name).Id;
                var id2 = solutionY.Projects.First(p => p.Name == project2.Name).Id;

                var compilation2 = solutionY.GetProject(id2).GetCompilationAsync().Result;
                var errors = compilation2.GetDiagnostics();
                var classD = compilation2.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                var classC = classD.BaseType;
                Assert.NotEqual(TypeKind.Error, classC.TypeKind);

                // change the class name in document1
                workspace.OnDocumentOpened(document1.Id, document1.GetOpenTextContainer());
                var buffer1 = document1.GetTextBuffer();

                // change C to X
                buffer1.Replace(new Span(13, 1), "X");

                // this solution should have the change
                var solutionZ = workspace.CurrentSolution;
                var docZ = solutionZ.GetDocument(document1.Id);
                var docZText = docZ.GetTextAsync().PumpingWaitResult();

                var compilation2Z = solutionZ.GetProject(id2).GetCompilationAsync().Result;
                var classDz = compilation2Z.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                var classCz = classDz.BaseType;

                Assert.Equal(TypeKind.Error, classCz.TypeKind);
            }
        }
Example #27
0
 internal void AddAdditionalDocument(TestHostDocument document)
 {
     this.AdditionalDocuments = this.AdditionalDocuments.Concat(new TestHostDocument[] { document });
     document.SetProject(this);
 }
Example #28
0
        public void TestOpenAndChangeDocument()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document = new TestHostDocument(string.Empty);
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);
                var buffer = document.GetTextBuffer();
                workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer());

                buffer.Insert(0, "class C {}");

                solution = workspace.CurrentSolution;
                var doc = solution.Projects.Single().Documents.First();

                var syntaxTree = doc.GetSyntaxTreeAsync(CancellationToken.None).Result;
                Assert.True(syntaxTree.GetRoot().Width() > 0, "syntaxTree.GetRoot().Width should be > 0");

                workspace.OnDocumentClosed(document.Id);
                workspace.OnProjectRemoved(project1.Id);
            }
        }
Example #29
0
        public async Task TestChangeOptions1()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document = new TestHostDocument(
@"#if FOO
class C { }
#else
class D { }
#endif");

                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);

                await VerifyRootTypeNameAsync(workspace, "D");

                workspace.OnParseOptionsChanged(document.Id.ProjectId,
                    new CSharpParseOptions(preprocessorSymbols: new[] { "FOO" }));

                await VerifyRootTypeNameAsync(workspace, "C");
            }
        }
Example #30
0
        public void TestApplyChangesWithDocumentAdded()
        {
            using (var workspace = CreateWorkspace())
            {
                var doc1Text = "public class C { }";
                var doc2Text = "public class D { }";

                var document = new TestHostDocument(doc1Text);
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);

                // fork the solution to introduce a change.
                var oldSolution = workspace.CurrentSolution;
                var newSolution = oldSolution.AddDocument(DocumentId.CreateNewId(project1.Id), "Doc2", SourceText.From(doc2Text));

                workspace.TryApplyChanges(newSolution);

                // new document should have been added.
                Assert.Equal(2, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count());
            }
        }
Example #31
0
        public async void TestAddedSubmissionParseTreeHasEmptyFilePath()
        {
            using (var workspace = CreateWorkspace())
            {
                var document1 = new TestHostDocument("var x = 1;", displayName: "Sub1", sourceCodeKind: SourceCodeKind.Script);
                var project1 = new TestHostProject(workspace, document1, name: "Submission");

                var document2 = new TestHostDocument("var x = 2;", displayName: "Sub2", sourceCodeKind: SourceCodeKind.Script, filePath: "a.csx");
                var project2 = new TestHostProject(workspace, document2, name: "Script");

                workspace.AddTestProject(project1);
                workspace.AddTestProject(project2);

                workspace.TryApplyChanges(workspace.CurrentSolution);

                // Check that a parse tree for a submission has an empty file path.
                SyntaxTree tree1 = await workspace.CurrentSolution
                    .GetProjectState(project1.Id)
                    .GetDocumentState(document1.Id)
                    .GetSyntaxTreeAsync(CancellationToken.None);
                Assert.Equal("", tree1.FilePath);

                // Check that a parse tree for a script does not have an empty file path.
                SyntaxTree tree2 = await workspace.CurrentSolution
                    .GetProjectState(project2.Id)
                    .GetDocumentState(document2.Id)
                    .GetSyntaxTreeAsync(CancellationToken.None);
                Assert.Equal("a.csx", tree2.FilePath);
            }
        }
Example #32
0
        public void TestDocumentEvents()
        {
            using (var workspace = CreateWorkspace())
            {
                var doc1Text = "public class C { }";
                var document = new TestHostDocument(doc1Text);
                var project1 = new TestHostProject(workspace, document, name: "project1");
                var longEventTimeout = TimeSpan.FromMinutes(5);
                var shortEventTimeout = TimeSpan.FromSeconds(5);

                workspace.AddTestProject(project1);

                // Creating two waiters that will allow us to know for certain if the events have fired.
                using (var closeWaiter = new EventWaiter())
                using (var openWaiter = new EventWaiter())
                {
                    // Wrapping event handlers so they can notify us on being called.
                    var documentOpenedEventHandler = openWaiter.Wrap<DocumentEventArgs>(
                        (sender, args) => Assert.True(args.Document.Id == document.Id,
                        "The document given to the 'DocumentOpened' event handler did not have the same id as the one created for the test."));

                    var documentClosedEventHandler = closeWaiter.Wrap<DocumentEventArgs>(
                        (sender, args) => Assert.True(args.Document.Id == document.Id,
                        "The document given to the 'DocumentClosed' event handler did not have the same id as the one created for the test."));

                    workspace.DocumentOpened += documentOpenedEventHandler;
                    workspace.DocumentClosed += documentClosedEventHandler;

                    workspace.OpenDocument(document.Id);
                    workspace.CloseDocument(document.Id);

                    // Wait for all workspace tasks to finish.  After this is finished executing, all handlers should have been notified.
                    WaitForWorkspaceOperationsToComplete(workspace);

                    // Wait to recieve signal that events have fired.
                    Assert.True(openWaiter.WaitForEventToFire(longEventTimeout),
                                            string.Format("event 'DocumentOpened' was not fired within {0} minutes.",
                                            longEventTimeout.Minutes));

                    Assert.True(closeWaiter.WaitForEventToFire(longEventTimeout),
                                            string.Format("event 'DocumentClosed' was not fired within {0} minutes.",
                                            longEventTimeout.Minutes));

                    workspace.DocumentOpened -= documentOpenedEventHandler;
                    workspace.DocumentClosed -= documentClosedEventHandler;

                    workspace.OpenDocument(document.Id);
                    workspace.CloseDocument(document.Id);

                    // Wait for all workspace tasks to finish.  After this is finished executing, all handlers should have been notified.
                    WaitForWorkspaceOperationsToComplete(workspace);

                    // Verifiying that an event has not been called is difficult to prove.  
                    // All events should have already been called so we wait 5 seconds and then assume the event handler was removed correctly. 
                    Assert.False(openWaiter.WaitForEventToFire(shortEventTimeout),
                                            string.Format("event handler 'DocumentOpened' was called within {0} seconds though it was removed from the list.",
                                            shortEventTimeout.Seconds));

                    Assert.False(closeWaiter.WaitForEventToFire(shortEventTimeout),
                                            string.Format("event handler 'DocumentClosed' was called within {0} seconds though it was removed from the list.",
                                            shortEventTimeout.Seconds));
                }
            }
        }
Example #33
0
        public void TestRemoveProjectWithOpenedDocuments()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document = new TestHostDocument(string.Empty);
                var project1 = new TestHostProject(workspace, document, name: "project1");

                workspace.AddTestProject(project1);
                workspace.OnDocumentOpened(document.Id, document.GetOpenTextContainer());

                workspace.OnProjectRemoved(project1.Id);
                Assert.False(workspace.IsDocumentOpen(document.Id));
                Assert.Empty(workspace.CurrentSolution.Projects);
            }
        }
Example #34
0
        public void TestAdditionalFile_DocumentChanged()
        {
            using (var workspace = CreateWorkspace())
            {
                var startText = @"<setting value = ""foo""";
                var newText = @"<setting value = ""foo1""";
                var document = new TestHostDocument("public class C { }");
                var additionalDoc = new TestHostDocument(startText);
                var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc });

                workspace.AddTestProject(project1);
                var buffer = additionalDoc.GetTextBuffer();
                workspace.OnAdditionalDocumentOpened(additionalDoc.Id, additionalDoc.GetOpenTextContainer());

                var project = workspace.CurrentSolution.Projects.Single();
                var oldVersion = project.GetSemanticVersionAsync().PumpingWaitResult();

                // fork the solution to introduce a change.
                var oldSolution = workspace.CurrentSolution;
                var newSolution = oldSolution.WithAdditionalDocumentText(additionalDoc.Id, SourceText.From(newText));
                workspace.TryApplyChanges(newSolution);

                var doc = workspace.CurrentSolution.GetAdditionalDocument(additionalDoc.Id);

                // new text should have been pushed into buffer
                Assert.Equal(newText, buffer.CurrentSnapshot.GetText());

                // Text changes are considered top level changes and they change the project's semantic version.
                Assert.Equal(doc.GetTextVersionAsync().PumpingWaitResult(), doc.GetTopLevelChangeTextVersionAsync().PumpingWaitResult());
                Assert.NotEqual(oldVersion, doc.Project.GetSemanticVersionAsync().PumpingWaitResult());
            }
        }
Example #35
0
        public async Task TestGetCompilationOnDependentProject()
        {
            using (var workspace = CreateWorkspace())
            {
                var solution = workspace.CurrentSolution;

                var document1 = new TestHostDocument(@"public class C { }");
                var project1 = new TestHostProject(workspace, document1, name: "project1");

                var document2 = new TestHostDocument(@"class D : C { }");
                var project2 = new TestHostProject(workspace, document2, name: "project2", projectReferences: new[] { project1 });

                workspace.AddTestProject(project1);
                workspace.AddTestProject(project2);

                var snapshot = workspace.CurrentSolution;
                var id1 = snapshot.Projects.First(p => p.Name == project1.Name).Id;
                var id2 = snapshot.Projects.First(p => p.Name == project2.Name).Id;

                var compilation2 = await snapshot.GetProject(id2).GetCompilationAsync();
                var classD = compilation2.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                var classC = classD.BaseType;
            }
        }
Example #36
0
        public void TestAdditionalFile_AddRemove_FromProject()
        {
            using (var workspace = CreateWorkspace())
            {
                var startText = @"<setting value = ""foo""";
                var document = new TestHostDocument("public class C { }");
                var additionalDoc = new TestHostDocument(startText, "original.config");
                var project1 = new TestHostProject(workspace, name: "project1", documents: new[] { document }, additionalDocuments: new[] { additionalDoc });
                workspace.AddTestProject(project1);

                var project = workspace.CurrentSolution.Projects.Single();

                // fork the solution to introduce a change.
                var doc = project.AddAdditionalDocument("app.config", "text");
                workspace.TryApplyChanges(doc.Project.Solution);

                Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count());
                Assert.Equal(2, workspace.CurrentSolution.GetProject(project1.Id).AdditionalDocuments.Count());

                // Now remove the newly added document
                project = workspace.CurrentSolution.Projects.Single();
                workspace.TryApplyChanges(project.RemoveAdditionalDocument(doc.Id).Solution);

                Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).Documents.Count());
                Assert.Equal(1, workspace.CurrentSolution.GetProject(project1.Id).AdditionalDocuments.Count());
                Assert.Equal("original.config", workspace.CurrentSolution.GetProject(project1.Id).AdditionalDocuments.Single().Name);
            }
        }
Example #37
0
        public async Task TestDependentSemanticVersionChangesWhenNotOriginallyAccessed()
        {
            using (var workspace = CreateWorkspace(disablePartialSolutions: false))
            {
                var solutionX = workspace.CurrentSolution;

                var document1 = new TestHostDocument(@"public class C { }");
                var project1 = new TestHostProject(workspace, document1, name: "project1");

                var document2 = new TestHostDocument("Public Class D \r\n  Inherits C\r\nEnd Class");
                var project2 = new TestHostProject(workspace, document2, language: LanguageNames.VisualBasic, name: "project2", projectReferences: new[] { project1 });

                workspace.AddTestProject(project1);
                workspace.AddTestProject(project2);

                var solutionY = workspace.CurrentSolution;
                var id1 = solutionY.Projects.First(p => p.Name == project1.Name).Id;
                var id2 = solutionY.Projects.First(p => p.Name == project2.Name).Id;

                var compilation2y = await solutionY.GetProject(id2).GetCompilationAsync();
                var errors = compilation2y.GetDiagnostics();
                var classDy = compilation2y.SourceModule.GlobalNamespace.GetTypeMembers("D").Single();
                var classCy = classDy.BaseType;
                Assert.NotEqual(TypeKind.Error, classCy.TypeKind);

                // open both documents so background compiler works on their compilations
                workspace.OnDocumentOpened(document1.Id, document1.GetOpenTextContainer());
                workspace.OnDocumentOpened(document2.Id, document2.GetOpenTextContainer());

                // change C to X
                var buffer1 = document1.GetTextBuffer();
                buffer1.Replace(new Span(13, 1), "X");

                for (int iter = 0; iter < 10; iter++)
                {
                    WaitHelper.WaitForDispatchedOperationsToComplete(System.Windows.Threading.DispatcherPriority.ApplicationIdle);
                    Thread.Sleep(1000);

                    // the current solution should eventually have the change
                    var cs = workspace.CurrentSolution;
                    var doc1Z = cs.GetDocument(document1.Id);
                    var hasX = (await doc1Z.GetTextAsync()).ToString().Contains("X");

                    if (hasX)
                    {
                        var newVersion = await cs.GetProject(project1.Id).GetDependentSemanticVersionAsync();
                        var newVersionX = await doc1Z.Project.GetDependentSemanticVersionAsync();
                        Assert.NotEqual(VersionStamp.Default, newVersion);
                        Assert.Equal(newVersion, newVersionX);
                        break;
                    }
                }
            }
        }
Example #38
0
        protected static async Task<SyntaxNode> ExtractMethodAsync(
            TestWorkspace workspace,
            TestHostDocument testDocument,
            bool succeed = true,
            bool allowMovingDeclaration = true,
            bool dontPutOutOrRefOnStruct = true)
        {
            var document = workspace.CurrentSolution.GetDocument(testDocument.Id);
            Assert.NotNull(document);

            var originalOptions = await document.GetOptionsAsync();
            var options = originalOptions.WithChangedOption(ExtractMethodOptions.AllowMovingDeclaration, document.Project.Language, allowMovingDeclaration)
                                         .WithChangedOption(ExtractMethodOptions.DontPutOutOrRefOnStruct, document.Project.Language, dontPutOutOrRefOnStruct);

            var semanticDocument = await SemanticDocument.CreateAsync(document, CancellationToken.None);
            var validator = new CSharpSelectionValidator(semanticDocument, testDocument.SelectedSpans.Single(), options);

            var selectedCode = await validator.GetValidSelectionAsync(CancellationToken.None);
            if (!succeed && selectedCode.Status.FailedWithNoBestEffortSuggestion())
            {
                return null;
            }

            Assert.True(selectedCode.ContainsValidContext);

            // extract method
            var extractor = new CSharpMethodExtractor((CSharpSelectionResult)selectedCode);
            var result = await extractor.ExtractMethodAsync(CancellationToken.None);
            Assert.NotNull(result);
            Assert.Equal(succeed, result.Succeeded || result.SucceededWithSuggestion);

            return await result.Document.GetSyntaxRootAsync();
        }
Example #39
0
 internal TestDocumentLoader(TestHostDocument hostDocument)
 {
     _hostDocument = hostDocument;
 }