public void ProjectSnapshotManager_WorkspacePopulated_DoesNotFireTwice()
        {
            // Arrange
            var responseRouterReturns = new Mock <IResponseRouterReturns>(MockBehavior.Strict);

            responseRouterReturns.Setup(r => r.ReturningVoid(It.IsAny <CancellationToken>()))
            .Returns(() => Task.CompletedTask);

            var clientNotifierService = new Mock <ClientNotifierServiceBase>(MockBehavior.Strict);

            clientNotifierService.Setup(l => l.SendRequestAsync(_razorServerReadyEndpoint))
            .Returns(Task.FromResult(responseRouterReturns.Object));

            var razorServerReadyPublisher = new RazorServerReadyPublisher(Dispatcher, clientNotifierService.Object);

            var projectManager = TestProjectSnapshotManager.Create(Dispatcher);

            projectManager.AllowNotifyListeners = true;

            razorServerReadyPublisher.Initialize(projectManager);
            var document = TestDocumentSnapshot.Create("C:/file.cshtml");

            document.TryGetText(out var text);
            document.TryGetTextVersion(out var textVersion);
            var textAndVersion = TextAndVersion.Create(text, textVersion);

            projectManager.ProjectAdded(document.ProjectInternal.HostProject);

            // Act
            projectManager.ProjectWorkspaceStateChanged(document.ProjectInternal.HostProject.FilePath, CreateProjectWorkspace());

            clientNotifierService.VerifyAll();
            responseRouterReturns.VerifyAll();

            projectManager.ProjectWorkspaceStateChanged(document.ProjectInternal.HostProject.FilePath, CreateProjectWorkspace());

            // Assert
            clientNotifierService.VerifyAll();
            responseRouterReturns.Verify(r => r.ReturningVoid(It.IsAny <CancellationToken>()), Times.Once);
        }
示例#2
0
        public static IEnumerable <ProjectId> AddProjectToWorkspace(OmniSharpWorkspace workspace, string filePath, string[] frameworks, TestFile[] testFiles, ImmutableArray <AnalyzerReference> analyzerRefs = default)
        {
            var versionStamp = VersionStamp.Create();
            var references   = GetReferences();

            frameworks = frameworks ?? new[] { string.Empty };
            var projectsIds = new List <ProjectId>();

            foreach (var framework in frameworks)
            {
                var projectInfo = ProjectInfo.Create(
                    id: ProjectId.CreateNewId(),
                    version: versionStamp,
                    name: "OmniSharp+" + framework,
                    assemblyName: "AssemblyName",
                    language: LanguageNames.CSharp,
                    filePath: filePath,
                    metadataReferences: references,
                    analyzerReferences: analyzerRefs);

                workspace.AddProject(projectInfo);

                foreach (var testFile in testFiles)
                {
                    var documentInfo = DocumentInfo.Create(
                        id: DocumentId.CreateNewId(projectInfo.Id),
                        name: testFile.FileName,
                        sourceCodeKind: SourceCodeKind.Regular,
                        loader: TextLoader.From(TextAndVersion.Create(testFile.Content.Text, versionStamp)),
                        filePath: testFile.FileName);

                    workspace.AddDocument(documentInfo);
                }

                projectsIds.Add(projectInfo.Id);
            }

            return(projectsIds);
        }
示例#3
0
        public static AdhocWorkspace CreateWithCode(string csharpCode, string[] references, out Project project)
        {
            var sourceText = SourceText.From(csharpCode);

            var workspace    = new AdhocWorkspace();
            var projectId    = ProjectId.CreateNewId();
            var documentInfo = DocumentInfo.Create(
                DocumentId.CreateNewId(projectId, "Source.cs"),
                name: "Source.cs",
                loader: TextLoader.From(TextAndVersion.Create(sourceText, VersionStamp.Create())));

            var allReferencedAssemblyPaths = GetSystemAssemblyPaths().Concat(references);

            var projectInfo = ProjectInfo
                              .Create(projectId, VersionStamp.Create(), "Test", "Test", LanguageNames.CSharp)
                              .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
                              .WithMetadataReferences(allReferencedAssemblyPaths.Select(path => MetadataReference.CreateFromFile(path)))
                              .WithDocuments(new[] { documentInfo });

            project = workspace.AddProject(projectInfo);
            return(workspace);
        }
        public async Task DocumentChanged_Loader_UpdatesDocument()
        {
            // Arrange
            ProjectManager.ProjectAdded(HostProject);
            ProjectManager.DocumentAdded(HostProject, Documents[0], null);
            ProjectManager.DocumentOpened(HostProject.FilePath, Documents[0].FilePath, SourceText);
            ProjectManager.Reset();

            var expected       = SourceText.From("Hi");
            var textAndVersion = TextAndVersion.Create(expected, VersionStamp.Create());

            // Act
            ProjectManager.DocumentChanged(HostProject.FilePath, Documents[0].FilePath, TextLoader.From(textAndVersion));

            // Assert
            Assert.Equal(ProjectChangeKind.DocumentChanged, ProjectManager.ListenersNotifiedOf);

            var snapshot = ProjectManager.GetSnapshot(HostProject);
            var text     = await snapshot.GetDocument(Documents[0].FilePath).GetTextAsync();

            Assert.Same(expected, text);
        }
示例#5
0
        private (OmniSharpWorkspace, ChangeBufferService, DocumentInfo) CreateSimpleWorkspace(string fileName, string contents)
        {
            var workspace = new OmniSharpWorkspace(
                new HostServicesAggregator(
                    Enumerable.Empty <IHostServicesProvider>(), new LoggerFactory()),
                new LoggerFactory());

            var service = new ChangeBufferService(workspace);

            var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(),
                                                 "ProjectNameVal", "AssemblyNameVal", LanguageNames.CSharp);

            var documentInfo = DocumentInfo.Create(DocumentId.CreateNewId(projectInfo.Id), fileName,
                                                   null, SourceCodeKind.Regular,
                                                   TextLoader.From(TextAndVersion.Create(SourceText.From(contents), VersionStamp.Create())),
                                                   fileName);

            workspace.AddProject(projectInfo);
            workspace.AddDocument(documentInfo);

            return(workspace, service, documentInfo);
        }
示例#6
0
        public async Task UpdateBuffer_TransientDocumentsDisappearWhenProjectAddsThem()
        {
            var testFile = new TestFile("test.cs", "class C {}");

            using (var host = CreateOmniSharpHost(testFile))
            {
                await host.Workspace.BufferManager.UpdateBufferAsync(new Request()
                {
                    FileName = "transient.cs", Buffer = "interface I {}"
                });

                var docIds = host.Workspace.CurrentSolution.GetDocumentIdsWithFilePath("transient.cs");
                Assert.Equal(2, docIds.Length);

                // simulate a project system adding the file for real
                var project1 = host.Workspace.CurrentSolution.Projects.First();
                var document = DocumentInfo.Create(DocumentId.CreateNewId(project1.Id), "transient.cs",
                                                   loader: TextLoader.From(TextAndVersion.Create(SourceText.From("enum E{}"), VersionStamp.Create())),
                                                   filePath: "transient.cs");

                var newSolution = host.Workspace.CurrentSolution.AddDocument(document);
                host.Workspace.TryApplyChanges(newSolution);

                docIds = host.Workspace.CurrentSolution.GetDocumentIdsWithFilePath("transient.cs");
                Assert.Equal(2, docIds.Length);

                await host.Workspace.BufferManager.UpdateBufferAsync(new Request()
                {
                    FileName = "transient.cs", Buffer = "enum E {}"
                });

                var sourceText = await host.Workspace.CurrentSolution.GetDocument(docIds.First()).GetTextAsync();

                Assert.Equal("enum E {}", sourceText.ToString());
                sourceText = await host.Workspace.CurrentSolution.GetDocument(docIds.Last()).GetTextAsync();

                Assert.Equal("enum E {}", sourceText.ToString());
            }
        }
示例#7
0
        public void TestOpenCloseAnnalyzerConfigDocument()
        {
            var pid     = ProjectId.CreateNewId();
            var text    = SourceText.From("public class C { }");
            var version = VersionStamp.Create();
            var analyzerConfigDocFilePath = PathUtilities.CombineAbsoluteAndRelativePaths(Temp.CreateDirectory().Path, ".editorconfig");
            var docInfo = DocumentInfo.Create(
                DocumentId.CreateNewId(pid),
                name: ".editorconfig",
                loader: TextLoader.From(TextAndVersion.Create(text, version, analyzerConfigDocFilePath)),
                filePath: analyzerConfigDocFilePath);
            var projInfo = ProjectInfo.Create(
                pid,
                version: VersionStamp.Default,
                name: "TestProject",
                assemblyName: "TestProject.dll",
                language: LanguageNames.CSharp)
                           .WithAnalyzerConfigDocuments(new[] { docInfo });

            using (var ws = new AdhocWorkspace())
            {
                ws.AddProject(projInfo);
                var doc = ws.CurrentSolution.GetAnalyzerConfigDocument(docInfo.Id);
                Assert.False(doc.TryGetText(out var currentText));

                ws.OpenAnalyzerConfigDocument(docInfo.Id);

                doc = ws.CurrentSolution.GetAnalyzerConfigDocument(docInfo.Id);
                Assert.True(doc.TryGetText(out currentText));
                Assert.True(doc.TryGetTextVersion(out var currentVersion));
                Assert.Same(text, currentText);
                Assert.Equal(version, currentVersion);

                ws.CloseAnalyzerConfigDocument(docInfo.Id);

                doc = ws.CurrentSolution.GetAnalyzerConfigDocument(docInfo.Id);
                Assert.False(doc.TryGetText(out currentText));
            }
        }
        public async Task UpdateBuffer_TransientDocumentsDisappearWhenProjectAddsThem()
        {
            var workspace = await TestHelpers.CreateSimpleWorkspace(new Dictionary <string, string>
            {
                { "test.cs", "class C {}" }
            });

            await workspace.BufferManager.UpdateBuffer(new OmniSharp.Models.Request()
            {
                FileName = "transient.cs", Buffer = "interface I {}"
            });

            var docIds = workspace.CurrentSolution.GetDocumentIdsWithFilePath("transient.cs");

            Assert.Equal(2, docIds.Length);

            // simulate a project system adding the file for real
            var project1 = workspace.CurrentSolution.Projects.First();
            var document = DocumentInfo.Create(DocumentId.CreateNewId(project1.Id), "transient.cs",
                                               loader: TextLoader.From(TextAndVersion.Create(SourceText.From("enum E{}"), VersionStamp.Create())),
                                               filePath: "transient.cs");

            workspace.CurrentSolution.AddDocument(document);

            docIds = workspace.CurrentSolution.GetDocumentIdsWithFilePath("transient.cs");
            Assert.Equal(2, docIds.Length);

            await workspace.BufferManager.UpdateBuffer(new OmniSharp.Models.Request()
            {
                FileName = "transient.cs", Buffer = "enum E {}"
            });

            var sourceText = await workspace.CurrentSolution.GetDocument(docIds.First()).GetTextAsync();

            Assert.Equal("enum E {}", sourceText.ToString());
            sourceText = await workspace.CurrentSolution.GetDocument(docIds.Last()).GetTextAsync();

            Assert.Equal("enum E {}", sourceText.ToString());
        }
示例#9
0
        public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
        {
            var prevLastWriteTime = File.GetLastWriteTimeUtc(_filePath);

            TextAndVersion textAndVersion;

            using (var stream = File.OpenRead(_filePath))
            {
                var version = VersionStamp.Create(prevLastWriteTime);
                var text    = SourceText.From(stream);
                textAndVersion = TextAndVersion.Create(text, version, _filePath);
            }

            var newLastWriteTime = File.GetLastWriteTimeUtc(_filePath);

            if (!newLastWriteTime.Equals(prevLastWriteTime))
            {
                throw new IOException($"File was externally modified: {_filePath}");
            }

            return(Task.FromResult(textAndVersion));
        }
示例#10
0
            public Document AddDocument(ProjectId projectId, string name, SourceText text)
            {
                if (projectId == null)
                {
                    throw new ArgumentNullException(nameof(projectId));
                }

                if (name == null)
                {
                    throw new ArgumentNullException(nameof(name));
                }

                if (text == null)
                {
                    throw new ArgumentNullException(nameof(text));
                }

                var id     = DocumentId.CreateNewId(projectId);
                var loader = TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create()));

                return(this.AddDocument(DocumentInfo.Create(id, name, loader: loader)));
            }
示例#11
0
        public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
        {
            var prevLastWriteTime = File.GetLastWriteTimeUtc(_filePath);

            var script = _scriptService.Generate(new FileChange
            {
                FileName = _filePath,
                FromDisk = true
            });
            var version        = VersionStamp.Create(prevLastWriteTime);
            var text           = SourceText.From(script.Source);
            var textAndVersion = TextAndVersion.Create(text, version, _filePath);

            var newLastWriteTime = File.GetLastWriteTimeUtc(_filePath);

            if (!newLastWriteTime.Equals(prevLastWriteTime))
            {
                throw new IOException($"File was externally modified: {_filePath}");
            }

            return(Task.FromResult(textAndVersion));
        }
示例#12
0
        private async Task <DocumentInfo> CreateDocumentInfoAsync(Checksum documentChecksum)
        {
            var documentSnapshot = await _assetService.GetAssetAsync <DocumentStateChecksums>(documentChecksum, _cancellationToken).ConfigureAwait(false);

            var documentInfo = await _assetService.GetAssetAsync <DocumentInfo.DocumentAttributes>(documentSnapshot.Info, _cancellationToken).ConfigureAwait(false);

            var textLoader = TextLoader.From(
                TextAndVersion.Create(
                    await _assetService.GetAssetAsync <SourceText>(documentSnapshot.Text, _cancellationToken).ConfigureAwait(false),
                    VersionStamp.Create(),
                    documentInfo.FilePath));

            // TODO: do we need version?
            return(DocumentInfo.Create(
                       documentInfo.Id,
                       documentInfo.Name,
                       documentInfo.Folders,
                       documentInfo.SourceCodeKind,
                       textLoader,
                       documentInfo.FilePath,
                       documentInfo.IsGenerated));
        }
示例#13
0
        public void TestAddProject_TryApplyChanges()
        {
            using (var ws = new AdhocWorkspace())
            {
                ProjectId pid = ProjectId.CreateNewId();

                var docInfo = DocumentInfo.Create(
                    DocumentId.CreateNewId(pid),
                    "MyDoc.cs",
                    loader: TextLoader.From(TextAndVersion.Create(SourceText.From(""), VersionStamp.Create())));

                var projInfo = ProjectInfo.Create(
                    pid,
                    VersionStamp.Create(),
                    "NewProject",
                    "NewProject.dll",
                    LanguageNames.CSharp,
                    documents: new[] { docInfo });

                var newSolution = ws.CurrentSolution.AddProject(projInfo);

                Assert.Equal(0, ws.CurrentSolution.Projects.Count());

                var result = ws.TryApplyChanges(newSolution);
                Assert.Equal(result, true);

                Assert.Equal(1, ws.CurrentSolution.Projects.Count());
                var proj = ws.CurrentSolution.Projects.First();

                Assert.Equal("NewProject", proj.Name);
                Assert.Equal("NewProject.dll", proj.AssemblyName);
                Assert.Equal(LanguageNames.CSharp, proj.Language);
                Assert.Equal(1, proj.Documents.Count());

                var doc = proj.Documents.First();
                Assert.Equal("MyDoc.cs", doc.Name);
            }
        }
示例#14
0
        public void TestOpenCloseAdditionalDocument()
        {
            var pid     = ProjectId.CreateNewId();
            var text    = SourceText.From("public class C { }");
            var version = VersionStamp.Create();
            var docInfo = DocumentInfo.Create(
                DocumentId.CreateNewId(pid),
                "c.cs",
                loader: TextLoader.From(TextAndVersion.Create(text, version))
                );
            var projInfo = ProjectInfo.Create(
                pid,
                version: VersionStamp.Default,
                name: "TestProject",
                assemblyName: "TestProject.dll",
                language: LanguageNames.CSharp,
                additionalDocuments: new[] { docInfo }
                );

            using var ws = new AdhocWorkspace();
            ws.AddProject(projInfo);
            var doc = ws.CurrentSolution.GetAdditionalDocument(docInfo.Id);

            Assert.False(doc.TryGetText(out var currentText));

            ws.OpenAdditionalDocument(docInfo.Id);

            doc = ws.CurrentSolution.GetAdditionalDocument(docInfo.Id);
            Assert.True(doc.TryGetText(out currentText));
            Assert.True(doc.TryGetTextVersion(out var currentVersion));
            Assert.Same(text, currentText);
            Assert.Equal(version, currentVersion);

            ws.CloseAdditionalDocument(docInfo.Id);

            doc = ws.CurrentSolution.GetAdditionalDocument(docInfo.Id);
            Assert.False(doc.TryGetText(out currentText));
        }
        public async Task MappedLocationFileNameProperlyRootedInMiscellaneousWorkspace()
        {
            var folderPath     = Directory.GetCurrentDirectory();
            var relativeFile   = ".\\Index.cshtml.cs";
            var mappedFilePath = Path.GetFullPath(Path.Combine(folderPath, relativeFile));

            var testFiles = new[]
            {
                new TestFile("Constants.cs", @"
                    public static class Constants
                    {
                        public const string My$$Text = ""Hello World"";
                    }"),
                new TestFile("Index.cshtml_virtual.cs", $@"
                    #line 1 ""{relativeFile}""
                    Constants.MyText
                    #line default
                    #line hidden")
            };

            var miscFile = new TestFile(mappedFilePath, "// Constants.MyText;");

            SharedOmniSharpTestHost.AddFilesToWorkspace(folderPath, testFiles);
            SharedOmniSharpTestHost.Workspace.TryAddMiscellaneousDocument(
                miscFile.FileName,
                TextLoader.From(TextAndVersion.Create(miscFile.Content.Text, VersionStamp.Create())),
                LanguageNames.CSharp);

            var testFile = testFiles.Single(tf => tf.Content.HasPosition);
            var usages   = await FindUsagesAsync(testFile, onlyThisFile : false);

            Assert.DoesNotContain(usages.QuickFixes, location => location.FileName.EndsWith("Index.cshtml_virtual.cs"));
            Assert.DoesNotContain(usages.QuickFixes, location => location.FileName.Equals(relativeFile));

            var quickFix = Assert.Single(usages.QuickFixes, location => location.FileName.Equals(mappedFilePath));

            Assert.Empty(quickFix.Projects);
        }
示例#16
0
        public DocumentStateTest()
        {
            TagHelperResolver = new TestTagHelperResolver();

            HostServices = TestServices.Create(
                new IWorkspaceService[]
            {
                new TestProjectSnapshotProjectEngineFactory(),
            },
                new ILanguageService[]
            {
                TagHelperResolver,
            });

            HostProject = new HostProject("c:\\MyProject\\Test.csproj", FallbackRazorConfiguration.MVC_2_0);
            HostProjectWithConfigurationChange = new HostProject("c:\\MyProject\\Test.csproj", FallbackRazorConfiguration.MVC_1_0);

            Workspace = TestWorkspace.Create(HostServices);

            var projectId = ProjectId.CreateNewId("Test");
            var solution  = Workspace.CurrentSolution.AddProject(ProjectInfo.Create(
                                                                     projectId,
                                                                     VersionStamp.Default,
                                                                     "Test",
                                                                     "Test",
                                                                     LanguageNames.CSharp,
                                                                     "c:\\MyProject\\Test.csproj"));

            WorkspaceProject = solution.GetProject(projectId);

            SomeTagHelpers = new List <TagHelperDescriptor>();
            SomeTagHelpers.Add(TagHelperDescriptorBuilder.Create("Test1", "TestAssembly").Build());

            Document = new HostDocument("c:\\MyProject\\File.cshtml", "File.cshtml");

            Text       = SourceText.From("Hello, world!");
            TextLoader = () => Task.FromResult(TextAndVersion.Create(Text, VersionStamp.Create()));
        }
示例#17
0
        public void AddProjectToWorkspace(OmnisharpWorkspace workspace,
                                          string projectFilePath,
                                          IEnumerable <string> frameworks,
                                          IDictionary <string, string> sourceFiles)
        {
            _logger.LogInformation($"  AddProjectToWorkspace");

            var versionStamp = VersionStamp.Create();
            var references   = new[]
            {
                CreateFromType(typeof(object)),     // mscorlib
                CreateFromType(typeof(Enumerable))  // System.Core
            };

            foreach (var framework in frameworks)
            {
                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(),
                                                     versionStamp,
                                                     $"OmniSharp+{framework}",
                                                     "AssemblyName",
                                                     LanguageNames.CSharp,
                                                     projectFilePath,
                                                     metadataReferences: references);

                workspace.AddProject(projectInfo);
                foreach (var file in sourceFiles)
                {
                    var document = DocumentInfo.Create(DocumentId.CreateNewId(projectInfo.Id),
                                                       file.Key,
                                                       folders: null,
                                                       sourceCodeKind: SourceCodeKind.Regular,
                                                       loader: TextLoader.From(TextAndVersion.Create(SourceText.From(file.Value), versionStamp)),
                                                       filePath: file.Key);

                    workspace.AddDocument(document);
                }
            }
        }
示例#18
0
        public static OmnisharpWorkspace CreateCsxWorkspace(string source, string fileName = "dummy.csx")
        {
            var versionStamp = VersionStamp.Create();
            var mscorlib     = MetadataReference.CreateFromAssembly(AssemblyFromType(typeof(object)));
            var systemCore   = MetadataReference.CreateFromAssembly(AssemblyFromType(typeof(Enumerable)));
            var references   = new[] { mscorlib, systemCore };
            var workspace    = new OmnisharpWorkspace();

            var parseOptions = new CSharpParseOptions(LanguageVersion.CSharp6, DocumentationMode.Parse, SourceCodeKind.Script);

            var projectId = ProjectId.CreateNewId(Guid.NewGuid().ToString());
            var project   = ProjectInfo.Create(projectId, VersionStamp.Create(), fileName, $"{fileName}.dll", LanguageNames.CSharp, fileName,
                                               compilationOptions: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary), metadataReferences: references, parseOptions: parseOptions,
                                               isSubmission: true);

            workspace.AddProject(project);
            var document = DocumentInfo.Create(DocumentId.CreateNewId(project.Id), fileName, null, SourceCodeKind.Script, null, fileName)
                           .WithSourceCodeKind(SourceCodeKind.Script)
                           .WithTextLoader(TextLoader.From(TextAndVersion.Create(SourceText.From(source), VersionStamp.Create())));

            workspace.AddDocument(document);
            return(workspace);
        }
示例#19
0
        public ProjectStateTest()
        {
            HostProject = new HostProject(TestProjectData.SomeProject.FilePath, FallbackRazorConfiguration.MVC_2_0, TestProjectData.SomeProject.RootNamespace);
            HostProjectWithConfigurationChange = new HostProject(TestProjectData.SomeProject.FilePath, FallbackRazorConfiguration.MVC_1_0, TestProjectData.SomeProject.RootNamespace);
            ProjectWorkspaceState = new ProjectWorkspaceState(new[]
            {
                TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly").Build(),
            });

            SomeTagHelpers = new List <TagHelperDescriptor>();
            SomeTagHelpers.Add(TagHelperDescriptorBuilder.Create("Test1", "TestAssembly").Build());

            Documents = new HostDocument[]
            {
                TestProjectData.SomeProjectFile1,
                TestProjectData.SomeProjectFile2,

                // linked file
                TestProjectData.AnotherProjectNestedFile3,
            };

            Text       = SourceText.From("Hello, world!");
            TextLoader = () => Task.FromResult(TextAndVersion.Create(Text, VersionStamp.Create()));
        }
示例#20
0
        public void SetOutput_AcceptsInitialOutput()
        {
            // Arrange
            var services     = TestWorkspace.Create().Services;
            var hostProject  = new HostProject("C:/project.csproj", RazorConfiguration.Default, "project");
            var projectState = ProjectState.Create(services, hostProject);
            var project      = new DefaultProjectSnapshot(projectState);

            var text           = SourceText.From("...");
            var textAndVersion = TextAndVersion.Create(text, VersionStamp.Default);
            var hostDocument   = new HostDocument("C:/file.cshtml", "C:/file.cshtml");
            var documentState  = new DocumentState(services, hostDocument, text, VersionStamp.Default, () => Task.FromResult(textAndVersion));
            var document       = new DefaultDocumentSnapshot(project, documentState);
            var csharpDocument = RazorCSharpDocument.Create("...", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());

            var version   = VersionStamp.Create();
            var container = new GeneratedCodeContainer();

            // Act
            container.SetOutput(document, csharpDocument, version, version);

            // Assert
            Assert.NotNull(container.LatestDocument);
        }
        internal static Solution CreateFullSolution(HostServices hostServices = null)
        {
            var solution  = new AdhocWorkspace(hostServices ?? Host.Mef.MefHostServices.DefaultHost).CurrentSolution;
            var csCode    = "class A { }";
            var project1  = solution.AddProject("Project", "Project.dll", LanguageNames.CSharp);
            var document1 = project1.AddDocument("Document1", SourceText.From(csCode));

            var vbCode    = "Class B\r\nEnd Class";
            var project2  = document1.Project.Solution.AddProject("Project2", "Project2.dll", LanguageNames.VisualBasic);
            var document2 = project2.AddDocument("Document2", SourceText.From(vbCode));

            project1 = document2.Project.Solution.GetProject(project1.Id).AddProjectReference(new ProjectReference(project2.Id, ImmutableArray.Create("test")));
            project1 = project1.AddMetadataReference(MetadataReference.CreateFromFile(typeof(object).Assembly.Location));
            project1 = project1.AddAnalyzerReference(new AnalyzerFileReference(typeof(object).Assembly.Location, new TestAnalyzerAssemblyLoader()));

            project1 = project1.AddAdditionalDocument("Additional", SourceText.From("hello"), ImmutableArray.Create("test"), @".\Add").Project;

            return(project1.Solution.AddAnalyzerConfigDocuments(
                       ImmutableArray.Create(
                           DocumentInfo.Create(
                               DocumentId.CreateNewId(project1.Id),
                               ".editorconfig",
                               loader: TextLoader.From(TextAndVersion.Create(SourceText.From("root = true"), VersionStamp.Create()))))));
        }
        public Task <TextLoader?> LoadSourceDocumentAsync(SourceDocument sourceDocument, Encoding?defaultEncoding, CancellationToken cancellationToken)
        {
            // First we try getting "local" files, either from embedded source or a local file on disk
            var stream = TryGetEmbeddedSourceStream(sourceDocument) ??
                         TryGetFileStream(sourceDocument);

            if (stream is not null)
            {
                using (stream)
                {
                    var encoding = defaultEncoding ?? Encoding.UTF8;
                    try
                    {
                        var sourceText = EncodedStringText.Create(stream, defaultEncoding: encoding, checksumAlgorithm: sourceDocument.HashAlgorithm);

                        var fileChecksum = sourceText.GetChecksum();
                        if (fileChecksum.SequenceEqual(sourceDocument.Checksum))
                        {
                            var textAndVersion = TextAndVersion.Create(sourceText, VersionStamp.Default, sourceDocument.FilePath);
                            var textLoader     = TextLoader.From(textAndVersion);
                            return(Task.FromResult <TextLoader?>(textLoader));
                        }
                    }
                    catch (IOException)
                    {
                        // TODO: Log message to inform the user what went wrong: https://github.com/dotnet/roslyn/issues/57352
                    }
                }
            }

            // TODO: Call the debugger to download the file
            // Maybe they'll download to a temp file, in which case this method could return a string
            // or maybe they'll return a stream, in which case we could create a new StreamTextLoader

            return(Task.FromResult <TextLoader?>(null));
        }
示例#23
0
        public ProjectStateGeneratedOutputTest()
        {
            HostProject = new HostProject(TestProjectData.SomeProject.FilePath, FallbackRazorConfiguration.MVC_2_0);
            HostProjectWithConfigurationChange = new HostProject(TestProjectData.SomeProject.FilePath, FallbackRazorConfiguration.MVC_1_0);

            var projectId = ProjectId.CreateNewId("Test");
            var solution  = Workspace.CurrentSolution.AddProject(ProjectInfo.Create(
                                                                     projectId,
                                                                     VersionStamp.Default,
                                                                     "Test",
                                                                     "Test",
                                                                     LanguageNames.CSharp,
                                                                     TestProjectData.SomeProject.FilePath));

            WorkspaceProject = solution.GetProject(projectId);

            SomeTagHelpers = new List <TagHelperDescriptor>();
            SomeTagHelpers.Add(TagHelperDescriptorBuilder.Create("Test1", "TestAssembly").Build());

            HostDocument = TestProjectData.SomeProjectFile1;

            Text       = SourceText.From("Hello, world!");
            TextLoader = () => Task.FromResult(TextAndVersion.Create(Text, VersionStamp.Create()));
        }
示例#24
0
        public void TrySetOutput_InvokesChangedEvent()
        {
            // Arrange
            using var workspace = TestWorkspace.Create();

            var services     = workspace.Services;
            var hostProject  = new HostProject("C:/project.csproj", RazorConfiguration.Default, "project");
            var projectState = ProjectState.Create(services, hostProject);
            var project      = new DefaultProjectSnapshot(projectState);

            var text           = SourceText.From("...");
            var textAndVersion = TextAndVersion.Create(text, VersionStamp.Default);
            var hostDocument   = new HostDocument("C:/file.cshtml", "C:/file.cshtml");
            var documentState  = new DocumentState(services, hostDocument, text, VersionStamp.Default, () => Task.FromResult(textAndVersion));
            var document       = new DefaultDocumentSnapshot(project, documentState);
            var csharpDocument = RazorCSharpDocument.Create("...", RazorCodeGenerationOptions.CreateDefault(), Enumerable.Empty <RazorDiagnostic>());
            var htmlDocument   = RazorHtmlDocument.Create("...", RazorCodeGenerationOptions.CreateDefault());
            var codeDocument   = CreateCodeDocument(csharpDocument, htmlDocument);

            var version       = VersionStamp.Create();
            var container     = new GeneratedDocumentContainer();
            var csharpChanged = false;
            var htmlChanged   = false;

            container.GeneratedCSharpChanged += (o, a) => csharpChanged = true;
            container.GeneratedHtmlChanged   += (o, a) => htmlChanged = true;

            // Act
            var result = container.TrySetOutput(document, codeDocument, version, version, version);

            // Assert
            Assert.NotNull(container.LatestDocument);
            Assert.True(csharpChanged);
            Assert.True(htmlChanged);
            Assert.True(result);
        }
示例#25
0
            public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
            {
                var physicalFilePath = _filePath;

                if (physicalFilePath[0] == '/')
                {
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        // VSLS path, not understood by File.OpenRead so we need to strip the leading separator.
                        physicalFilePath = physicalFilePath.Substring(1);
                    }
                    else
                    {
                        // Unix system, path starts with / which is allowed by File.OpenRead on non-windows.
                    }
                }
                var prevLastWriteTime = File.GetLastWriteTimeUtc(physicalFilePath);

                TextAndVersion textAndVersion;

                using (var stream = new FileStream(physicalFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                {
                    var version = VersionStamp.Create(prevLastWriteTime);
                    var text    = SourceText.From(stream);
                    textAndVersion = TextAndVersion.Create(text, version);
                }

                var newLastWriteTime = File.GetLastWriteTimeUtc(physicalFilePath);

                if (!newLastWriteTime.Equals(prevLastWriteTime))
                {
                    throw new IOException($"File was externally modified: {physicalFilePath}");
                }

                return(Task.FromResult(textAndVersion));
            }
示例#26
0
        private static ProjectInfo CreateMutationProject()
        {
            var projectId = ProjectId.CreateNewId();

            return(ProjectInfo.Create(
                       projectId,
                       VersionStamp.Create(),
                       "MutationProject",
                       "MutationProject",
                       LanguageNames.CSharp,
                       outputFilePath: Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Mutation", "MutationProject.dll"),
                       documents: new List <DocumentInfo>
            {
                DocumentInfo.Create(
                    DocumentId.CreateNewId(projectId),
                    "MyMutationDocument.cs",
                    loader: TextLoader.From(TextAndVersion.Create(SourceText.From(MyMutationDocument), VersionStamp.Default))),

                DocumentInfo.Create(
                    DocumentId.CreateNewId(projectId),
                    "MySecondMutationDocument.cs",
                    loader: TextLoader.From(TextAndVersion.Create(SourceText.From(MySecondMutationDocument), VersionStamp.Default))),
            }));
        }
示例#27
0
        public async Task TestAdditionalFile_OpenClose()
        {
            using (var workspace = CreateWorkspace())
            {
                var startText     = @"<setting value = ""goo""";
                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   = await doc.GetTextAsync(CancellationToken.None);

                var version = await doc.GetTextVersionAsync(CancellationToken.None);

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

                // Make sure that additional documents are included in GetOpenDocumentIds.
                var openDocumentIds = workspace.GetOpenDocumentIds();
                Assert.Single(openDocumentIds);
                Assert.Equal(additionalDoc.Id, openDocumentIds.Single());

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

                // Make sure that closed additional documents are not include in GetOpenDocumentIds.
                Assert.Empty(workspace.GetOpenDocumentIds());

                // 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());
            }
        }
示例#28
0
        public static IEnumerable <ProjectId> AddProjectToWorkspace(
            OmniSharpWorkspace workspace,
            string filePath,
            string[] frameworks,
            TestFile[] testFiles,
            TestFile[] analyzerConfigFiles = null,
            TestFile[] otherFiles          = null,
            ImmutableArray <AnalyzerReference> analyzerRefs = default)
        {
            analyzerConfigFiles ??= Array.Empty <TestFile>();
            otherFiles ??= Array.Empty <TestFile>();

            var versionStamp = VersionStamp.Create();
            var references   = GetReferences();

            frameworks = frameworks ?? new[] { string.Empty };
            var projectsIds       = new List <ProjectId>();
            var editorConfigPaths = EditorConfigFinder.GetEditorConfigPaths(filePath);

            foreach (var framework in frameworks)
            {
                var projectId = ProjectId.CreateNewId();
                var analyzerConfigDocuments = editorConfigPaths.Select(path =>
                                                                       DocumentInfo.Create(
                                                                           DocumentId.CreateNewId(projectId),
                                                                           name: ".editorconfig",
                                                                           loader: new FileTextLoader(path, Encoding.UTF8),
                                                                           filePath: path))
                                              .ToImmutableArray();

                var projectInfo = ProjectInfo.Create(
                    id: projectId,
                    version: versionStamp,
                    name: "OmniSharp+" + framework,
                    assemblyName: "AssemblyName",
                    language: LanguageNames.CSharp,
                    filePath: filePath,
                    metadataReferences: references,
                    analyzerReferences: analyzerRefs)
                                  .WithDefaultNamespace("OmniSharpTest")
                                  .WithAnalyzerConfigDocuments(analyzerConfigDocuments);

                workspace.AddProject(projectInfo);

                foreach (var testFile in testFiles)
                {
                    workspace.AddDocument(projectInfo.Id, testFile.FileName, TextLoader.From(TextAndVersion.Create(testFile.Content.Text, versionStamp)), SourceCodeKind.Regular);
                }

                foreach (var analyzerConfigFile in analyzerConfigFiles)
                {
                    workspace.AddAnalyzerConfigDocument(projectInfo.Id, analyzerConfigFile.FileName, TextLoader.From(TextAndVersion.Create(analyzerConfigFile.Content.Text, versionStamp)));
                }

                foreach (var otherFile in otherFiles)
                {
                    workspace.AddAdditionalDocument(projectInfo.Id, otherFile.FileName, TextLoader.From(TextAndVersion.Create(otherFile.Content.Text, versionStamp)));
                }

                projectsIds.Add(projectInfo.Id);
            }

            return(projectsIds);
        }
        public static TestProjectSnapshot Create(
            string filePath,
            string[] documentFilePaths,
            RazorConfiguration configuration,
            ProjectWorkspaceState projectWorkspaceState)
        {
            var workspaceServices = new List <IWorkspaceService>()
            {
                new TestProjectSnapshotProjectEngineFactory(),
            };
            var languageServices = new List <ILanguageService>();

            var hostServices = TestServices.Create(workspaceServices, languageServices);
            var workspace    = TestWorkspace.Create(hostServices);
            var hostProject  = new HostProject(filePath, configuration, "TestRootNamespace");
            var state        = ProjectState.Create(workspace.Services, hostProject);

            foreach (var documentFilePath in documentFilePaths)
            {
                var hostDocument = new HostDocument(documentFilePath, documentFilePath);
                state = state.WithAddedHostDocument(hostDocument, () => Task.FromResult(TextAndVersion.Create(SourceText.From(string.Empty), VersionStamp.Default)));
            }

            if (projectWorkspaceState != null)
            {
                state = state.WithProjectWorkspaceState(projectWorkspaceState);
            }

            var testProject = new TestProjectSnapshot(state);

            return(testProject);
        }
示例#30
0
        private async Task <Solution> GetSolutionAsync(IRemotableDataService service, PinnedRemotableDataScope syncScope)
        {
            var workspace = new AdhocWorkspace();

            var solutionObject = await service.GetValueAsync <SolutionStateChecksums>(syncScope.SolutionChecksum);

            var solutionInfo = await service.GetValueAsync <SolutionInfo.SolutionAttributes>(solutionObject.Info).ConfigureAwait(false);

            var projects = new List <ProjectInfo>();

            foreach (var projectObject in solutionObject.Projects.ToProjectObjects(service))
            {
                var projectInfo = await service.GetValueAsync <ProjectInfo.ProjectAttributes>(projectObject.Info).ConfigureAwait(false);

                if (!workspace.Services.IsSupported(projectInfo.Language))
                {
                    continue;
                }

                var documents = new List <DocumentInfo>();
                foreach (var documentObject in projectObject.Documents.ToDocumentObjects(service))
                {
                    var documentInfo = await service.GetValueAsync <DocumentInfo.DocumentAttributes>(documentObject.Info).ConfigureAwait(false);

                    var text = await service.GetValueAsync <SourceText>(documentObject.Text).ConfigureAwait(false);

                    // TODO: do we need version?
                    documents.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())),
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var p2p = new List <ProjectReference>();
                foreach (var checksum in projectObject.ProjectReferences)
                {
                    var reference = await service.GetValueAsync <ProjectReference>(checksum).ConfigureAwait(false);

                    p2p.Add(reference);
                }

                var metadata = new List <MetadataReference>();
                foreach (var checksum in projectObject.MetadataReferences)
                {
                    var reference = await service.GetValueAsync <MetadataReference>(checksum).ConfigureAwait(false);

                    metadata.Add(reference);
                }

                var analyzers = new List <AnalyzerReference>();
                foreach (var checksum in projectObject.AnalyzerReferences)
                {
                    var reference = await service.GetValueAsync <AnalyzerReference>(checksum).ConfigureAwait(false);

                    analyzers.Add(reference);
                }

                var additionals = new List <DocumentInfo>();
                foreach (var documentObject in projectObject.AdditionalDocuments.ToDocumentObjects(service))
                {
                    var documentInfo = await service.GetValueAsync <DocumentInfo.DocumentAttributes>(documentObject.Info).ConfigureAwait(false);

                    var text = await service.GetValueAsync <SourceText>(documentObject.Text).ConfigureAwait(false);

                    // TODO: do we need version?
                    additionals.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create())),
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var compilationOptions = await service.GetValueAsync <CompilationOptions>(projectObject.CompilationOptions).ConfigureAwait(false);

                var parseOptions = await service.GetValueAsync <ParseOptions>(projectObject.ParseOptions).ConfigureAwait(false);

                projects.Add(
                    ProjectInfo.Create(
                        projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName,
                        projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath,
                        compilationOptions, parseOptions,
                        documents, p2p, metadata, analyzers, additionals, projectInfo.IsSubmission));
            }

            return(workspace.AddSolution(SolutionInfo.Create(solutionInfo.Id, solutionInfo.Version, solutionInfo.FilePath, projects)));
        }