Beispiel #1
0
        public async Task TestChangeDocumentSourceCodeKind_TryApplyChanges()
        {
            using (var ws = new AdhocWorkspace())
            {
                var projectId = ws.AddProject("TestProject", LanguageNames.CSharp).Id;

                var originalDoc = ws.AddDocument(projectId, "TestDocument", SourceText.From(""));
                Assert.Equal(SourceCodeKind.Regular, originalDoc.SourceCodeKind);

                var changedDoc = originalDoc.WithSourceCodeKind(SourceCodeKind.Script);
                Assert.Equal(SourceCodeKind.Script, changedDoc.SourceCodeKind);

                var tcs = new TaskCompletionSource <bool>();
                ws.WorkspaceChanged += (s, args) =>
                {
                    if (args.Kind == WorkspaceChangeKind.DocumentInfoChanged &&
                        args.DocumentId == originalDoc.Id)
                    {
                        tcs.SetResult(true);
                    }
                };

                Assert.True(ws.TryApplyChanges(changedDoc.Project.Solution));

                var appliedDoc = ws.CurrentSolution.GetDocument(originalDoc.Id);
                Assert.Equal(SourceCodeKind.Script, appliedDoc.SourceCodeKind);

                await Task.WhenAny(tcs.Task, Task.Delay(1000));

                Assert.True(tcs.Task.IsCompleted && tcs.Task.Result);
            }
        }
        protected Solution CreateOrOpenSolution(bool nullPaths = false)
        {
            var solutionFile = Path.Combine(_persistentFolder, "Solution1.sln");

            File.WriteAllText(solutionFile, "");

            var info = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create(), solutionFile);

            var workspace = new AdhocWorkspace();

            workspace.AddSolution(info);

            var solution = workspace.CurrentSolution;

            var projectFile = Path.Combine(Path.GetDirectoryName(solutionFile), "Project1.csproj");

            File.WriteAllText(projectFile, "");
            solution = solution.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Project1", "Project1", LanguageNames.CSharp,
                                                              filePath: nullPaths ? null : projectFile));
            var project = solution.Projects.Single();

            var documentFile = Path.Combine(Path.GetDirectoryName(projectFile), "Document1.cs");

            File.WriteAllText(documentFile, "");
            solution = solution.AddDocument(DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "Document1",
                                                                filePath: nullPaths ? null : documentFile));

            // Apply this to the workspace so our Solution is the primary branch ID, which matches our usual behavior
            workspace.TryApplyChanges(solution);

            return(workspace.CurrentSolution);
        }
Beispiel #3
0
        public void TestRemoveProject_TryApplyChanges()
        {
            var pid  = ProjectId.CreateNewId();
            var info = ProjectInfo.Create(
                pid,
                version: VersionStamp.Default,
                name: "TestProject",
                assemblyName: "TestProject.dll",
                language: LanguageNames.CSharp);

            using (var ws = new AdhocWorkspace())
            {
                ws.AddProject(info);

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

                var newSolution = ws.CurrentSolution.RemoveProject(pid);
                Assert.Equal(0, newSolution.Projects.Count());

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

                Assert.Equal(0, ws.CurrentSolution.Projects.Count());
            }
        }
        public void TestChangeDocumentInfo_TryApplyChanges()
        {
            using var ws = new AdhocWorkspace();
            var projectId = ws.AddProject("TestProject", LanguageNames.CSharp).Id;

            var originalDoc = ws.AddDocument(projectId, "TestDocument", SourceText.From(""));

            Assert.Equal("TestDocument", originalDoc.Name);
            Assert.Equal(0, originalDoc.Folders.Count);
            Assert.Null(originalDoc.FilePath);

            var newName    = "ChangedName";
            var newPath    = @"\A\B\ChangedName.cs";
            var changedDoc = originalDoc.WithName(newName).WithFolders(new[] { "A", "B" }).WithFilePath(newPath);

            Assert.Equal(newName, changedDoc.Name);
            Assert.Equal(2, changedDoc.Folders.Count);
            Assert.Equal("A", changedDoc.Folders[0]);
            Assert.Equal("B", changedDoc.Folders[1]);
            Assert.Equal(newPath, changedDoc.FilePath);

            Assert.True(ws.TryApplyChanges(changedDoc.Project.Solution));

            var appliedDoc = ws.CurrentSolution.GetDocument(originalDoc.Id);

            Assert.Equal(newName, appliedDoc.Name);
            Assert.Equal(2, appliedDoc.Folders.Count);
            Assert.Equal("A", appliedDoc.Folders[0]);
            Assert.Equal("B", appliedDoc.Folders[1]);
            Assert.Equal(newPath, appliedDoc.FilePath);
        }
Beispiel #5
0
        private LiveIssue SetupAndCreate(Diagnostic diagnostic, string diagnosticProjectFilePath)
        {
            // Arrange
            var vsSolutionMock = SetupSolutionMocks(
                new KeyValuePair <string, string>(ProjectInSolutionFilePath, "{31D0DAAC-8606-40FE-8DF0-01784706EA3E}"));

            var projectId = ProjectId.CreateNewId();
            var workspace = new AdhocWorkspace();
            var solution  = workspace.CurrentSolution
                            .AddProject(ProjectInfo.Create(projectId, VersionStamp.Default, "Project1", "Assembly1", LanguageNames.CSharp,
                                                           diagnosticProjectFilePath))
                            .AddDocument(DocumentInfo.Create(DocumentId.CreateNewId(projectId), "name is unimportant.cs",
                                                             loader: TextLoader.From(TextAndVersion.Create(SourceText.From(@"namespace {
    class Foo
    {
    }
}"), VersionStamp.Default))));

            workspace.TryApplyChanges(solution);

            var liveIssueFactory = new RoslynLiveIssueFactory(workspace, vsSolutionMock.Object);

            var syntaxTree = workspace.CurrentSolution.Projects.First().GetCompilationAsync().Result.SyntaxTrees.First();

            // Act
            using (new AssertIgnoreScope())
            {
                return(liveIssueFactory.Create(syntaxTree, diagnostic));
            }
        }
Beispiel #6
0
        protected Solution CreateOrOpenSolution(bool nullPaths = false)
        {
            var solutionFile = _persistentFolder.CreateOrOpenFile("Solution1.sln").WriteAllText("");

            var info = SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create(), solutionFile.Path);

            var workspace = new AdhocWorkspace(VisualStudioTestCompositions.LanguageServices.GetHostServices());

            workspace.AddSolution(info);

            var solution = workspace.CurrentSolution;

            var projectFile = _persistentFolder.CreateOrOpenFile("Project1.csproj").WriteAllText("");

            solution = solution.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Project1", "Project1", LanguageNames.CSharp,
                                                              filePath: nullPaths ? null : projectFile.Path));
            var project = solution.Projects.Single();

            var documentFile = _persistentFolder.CreateOrOpenFile("Document1.cs").WriteAllText("");

            solution = solution.AddDocument(DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "Document1",
                                                                filePath: nullPaths ? null : documentFile.Path));

            // Apply this to the workspace so our Solution is the primary branch ID, which matches our usual behavior
            workspace.TryApplyChanges(solution);

            return(workspace.CurrentSolution);
        }
Beispiel #7
0
        public void UpdateDocument(ref Document document, string code)
        {
            var newSolution = workspace.CurrentSolution.WithDocumentText(
                document.Id, SourceText.From(code), PreservationMode.PreserveIdentity);

            workspace.TryApplyChanges(newSolution);
            document = workspace.CurrentSolution.GetDocument(document.Id);
        }
Beispiel #8
0
        private AdhocWorkspace CreateWorkspaceWithRecoverableTrees(HostServices hostServices)
        {
            var ws = new AdhocWorkspace(hostServices, workspaceKind: "NotKeptAlive");

            ws.TryApplyChanges(ws.CurrentSolution.WithOptions(ws.CurrentSolution.Options
                                                              .WithChangedOption(Host.CacheOptions.RecoverableTreeLengthThreshold, 0)));
            return(ws);
        }
        private static Solution CreateEmptySolutionUsingRecoverableSyntaxTrees()
        {
            var workspace = new AdhocWorkspace(MefHostServices.Create(TestHost.Assemblies), workspaceKind: "NotKeptAlive");

            workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options
                                                                            .WithChangedOption(Host.CacheOptions.RecoverableTreeLengthThreshold, 0)));
            return(workspace.CurrentSolution);
        }
Beispiel #10
0
        /// <summary>
        /// Adds a project to an existing Roslyn workspace.
        /// </summary>
        /// <param name="analyzer">The Buildalyzer project analyzer.</param>
        /// <param name="workspace">A Roslyn workspace.</param>
        /// <param name="addProjectReferences">
        /// <c>true</c> to add projects to the workspace for project references that exist in the same
        /// <see cref="AnalyzerManager" />.
        /// </param>
        /// <returns>The newly added Roslyn project.</returns>
        public static Project AddToWorkspace(this ProjectAnalyzer analyzer, AdhocWorkspace workspace, bool addProjectReferences = false)
        {
            if (analyzer == null)
            {
                throw new ArgumentNullException(nameof(analyzer));
            }

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

            // Get or create an ID for this project
            var projectGuid = analyzer.CompiledProject?.GetPropertyValue("ProjectGuid");
            var projectId   = !string.IsNullOrEmpty(projectGuid) &&
                              Guid.TryParse(analyzer.CompiledProject?.GetPropertyValue("ProjectGuid"), out var projectIdGuid)
                                        ? ProjectId.CreateFromSerialized(projectIdGuid)
                                        : ProjectId.CreateNewId();

            // Create and add the project
            var projectInfo = GetProjectInfo(analyzer, workspace, projectId);
            var solution    = workspace.CurrentSolution.AddProject(projectInfo);

            // Check if this project is referenced by any other projects in the workspace
            foreach (var existingProject in solution.Projects.ToArray())
            {
                if (!existingProject.Id.Equals(projectId) &&
                    analyzer.Manager.Projects.TryGetValue(existingProject.FilePath, out var existingAnalyzer) &&
                    (existingAnalyzer.GetProjectReferences()?.Contains(analyzer.ProjectFilePath) ?? false))
                {
                    // Add the reference to the existing project
                    var projectReference = new ProjectReference(projectId);
                    solution = solution.AddProjectReference(existingProject.Id, projectReference);
                }
            }

            // Apply solution changes
            if (!workspace.TryApplyChanges(solution))
            {
                throw new InvalidOperationException("Could not apply workspace solution changes");
            }

            // Add any project references not already added
            if (addProjectReferences)
            {
                foreach (var referencedAnalyzer in GetReferencedAnalyzerProjects(analyzer))
                {
                    // Check if the workspace contains the project inside the loop since adding one might also add this one due to transitive references
                    if (!workspace.CurrentSolution.Projects.Any(x => x.FilePath == referencedAnalyzer.ProjectFilePath))
                    {
                        AddToWorkspace(referencedAnalyzer, workspace, addProjectReferences);
                    }
                }
            }

            // Find and return this project
            return(workspace.CurrentSolution.GetProject(projectId));
        }
Beispiel #11
0
        protected override async Task Refactor(AdhocWorkspace workspace, Document document, SyntaxNode root)
        {
            var updatedDoc = await UnionTypeCodeProvider.EnumToClass(
                document,
                root.DescendantNodes().OfType <EnumDeclarationSyntax>().Last(), CancellationToken.None)
                             .ConfigureAwait(false);

            workspace.TryApplyChanges(updatedDoc.Project.Solution);
        }
        /// <summary>
        /// Creates a new instance of the factory.
        /// </summary>
        /// <returns>The created document factory.</returns>
        public static DocumentFactory Create()
        {
            var workspace = new AdhocWorkspace();
            var project   = workspace.AddProject("Unit Test", "C#")
                            .AddMetadataReferences(new[] { CorlibReference, SystemReference, SystemCoreReference /*, CSharpSymbolsReference, CodeAnalysisReference*/ });

            workspace.TryApplyChanges(project.Solution);
            return(new DocumentFactory(project));
        }
Beispiel #13
0
        public void AddDocumentToWorkspace(AdhocWorkspace workspace, ProjectId projectId, string name, SyntaxNode formattedResult)
        {
            var doc = workspace.AddDocument(projectId, name, formattedResult.SyntaxTree.GetText());

            if (!workspace.TryApplyChanges(doc.Project.Solution))
            {
                Console.WriteLine("failed to add to project");
            }
        }
    protected override async Task Refactor(AdhocWorkspace workspace, Document document, SyntaxNode root)
    {
        var updatedDocument = await ImmutableHelpersCodeProvider.GenerateWithExtension(
            document,
            root.DescendantNodes().OfType <ClassDeclarationSyntax>().Last(), CancellationToken.None)
                              .ConfigureAwait(false);

        workspace.TryApplyChanges(updatedDocument.Project.Solution);
    }
Beispiel #15
0
        public async Task TestHasSuccessfullyLoadedBeingFalseWithCompilerAnalyzerFSAOn()
        {
            var workspace = new AdhocWorkspace();

            workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options
                                                                            .WithChangedOption(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp, BackgroundAnalysisScope.FullSolution)));
            var document = GetDocumentFromIncompleteProject(workspace);

            await TestAnalyzerAsync(workspace, document, new CSharpCompilerDiagnosticAnalyzer(), CompilerAnalyzerResultSetter, expectedSyntax : true, expectedSemantic : false);
        }
Beispiel #16
0
        public bool AddMetadataReferences(CompilerMetadataReference[] metadataReferences)
        {
            Debug.Assert(workspace != null);
            if (workspace == null)
            {
                throw new InvalidOperationException();
            }
            var newProj = workspace.CurrentSolution.Projects.First().AddMetadataReferences(metadataReferences.Select(a => a.CreateMetadataReference(docFactory)));

            return(workspace.TryApplyChanges(newProj.Solution));
        }
        private (SyntaxNode node, Document document) Rename(SyntaxNode nodeToRename, Document document, string newName)
        {
            var symbolInfo = _semanticModel.GetSymbolInfo(nodeToRename).Symbol ??
                             _semanticModel.GetDeclaredSymbol(nodeToRename);
            var solution = Renamer.RenameSymbolAsync(document.Project.Solution, symbolInfo, newName,
                                                     _workspace.Options).Result;

            _workspace.TryApplyChanges(solution);
            document       = _workspace.CurrentSolution.GetDocument(document.Id);
            _semanticModel = document.GetSemanticModelAsync().Result;
            return(_semanticModel.SyntaxTree.GetRoot(), document);
        }
        public async Task UpdaterService()
        {
            var hostServices = s_composition.GetHostServices();

            using var workspace = new AdhocWorkspace(hostServices);

            var options = workspace.CurrentSolution.Options.WithChangedOption(
                RemoteHostOptions.SolutionChecksumMonitorBackOffTimeSpanInMS,
                1
                );

            workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(options));

            var listenerProvider = (
                (IMefHostExportProvider)hostServices
                ).GetExportedValue <AsynchronousOperationListenerProvider>();

            var checksumUpdater = new SolutionChecksumUpdater(
                workspace,
                listenerProvider,
                CancellationToken.None
                );
            var service = workspace.Services.GetRequiredService <IRemoteHostClientProvider>();

            // make sure client is ready
            using var client = await service.TryGetRemoteHostClientAsync(CancellationToken.None);

            // add solution, change document
            workspace.AddSolution(
                SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default)
                );
            var project  = workspace.AddProject("proj", LanguageNames.CSharp);
            var document = workspace.AddDocument(project.Id, "doc.cs", SourceText.From("code"));

            workspace.ApplyTextChanges(
                document.Id,
                new[] { new TextChange(new TextSpan(0, 1), "abc") },
                CancellationToken.None
                );

            // wait for listener
            var workspaceListener = listenerProvider.GetWaiter(FeatureAttribute.Workspace);
            await workspaceListener.ExpeditedWaitAsync();

            var listener = listenerProvider.GetWaiter(FeatureAttribute.SolutionChecksumUpdater);
            await listener.ExpeditedWaitAsync();

            // checksum should already exist
            Assert.True(workspace.CurrentSolution.State.TryGetStateChecksums(out _));

            checksumUpdater.Shutdown();
        }
Beispiel #19
0
        private static Workspace GetWorkspace(string?projectFilePath = null)
        {
            var projectId = ProjectId.CreateNewId();
            var workspace = new AdhocWorkspace(VisualStudioTestCompositions.LanguageServices.GetHostServices(), WorkspaceKind.Host);

            Assert.True(workspace.TryApplyChanges(workspace.CurrentSolution
                                                  .AddProject(ProjectInfo.Create(projectId, VersionStamp.Create(), "proj1", "proj1.dll", LanguageNames.CSharp, filePath: projectFilePath))
                                                  .AddDocument(DocumentId.CreateNewId(projectId), "goo.cs", "public class Goo { }")
                                                  .AddAdditionalDocument(DocumentId.CreateNewId(projectId), "add.txt", "text")
                                                  .AddAnalyzerReference(projectId, new MockAnalyzerReference())
                                                  .AddAnalyzerConfigDocument(DocumentId.CreateNewId(projectId), "editorcfg", SourceText.From("config"), filePath: "/a/b")));
            return(workspace);
        }
        private ReplSubmission UpdateSubmission(ReplSubmission replSubmission, string code)
        {
            var edit    = workspace.CurrentSolution.WithDocumentText(replSubmission.Document.Id, SourceText.From(code));
            var success = workspace.TryApplyChanges(edit);

            // document has changed, requery to get the new one
            var document = workspace.CurrentSolution.GetDocument(replSubmission.Document.Id);

            return(new ReplSubmission
            {
                Code = code,
                Document = document
            });
        }
Beispiel #21
0
        private static Workspace CreateWorkspaceWithProjectAndDocuments()
        {
            var projectId = ProjectId.CreateNewId();

            var workspace = new AdhocWorkspace(EditorTestCompositions.EditorFeatures.GetHostServices(), WorkspaceKind.Host);

            Assert.True(workspace.TryApplyChanges(workspace.CurrentSolution
                                                  .AddProject(projectId, "proj1", "proj1.dll", LanguageNames.CSharp)
                                                  .AddDocument(DocumentId.CreateNewId(projectId), "goo.cs", "public class Goo { }")
                                                  .AddAdditionalDocument(DocumentId.CreateNewId(projectId), "add.txt", "text")
                                                  .AddAnalyzerConfigDocument(DocumentId.CreateNewId(projectId), "editorcfg", SourceText.From(""), filePath: EditorconfigPath)));

            return(workspace);
        }
Beispiel #22
0
        public async Task TestGetInteriorSymbolsDoesNotCrashOnSpeculativeSemanticModel()
        {
            var    markup = @"
class C
{
    void foo()
    {
        System.Func<int> lambda = () => 
        {
        int x;
        $$
        }
    }
}";
            int    position;
            string text;

            MarkupTestFile.GetPosition(markup, out text, out position);

            var sourceText = SourceText.From(text);
            var workspace  = new AdhocWorkspace();
            var project    = workspace.AddProject("Test", LanguageNames.CSharp);
            var document   = workspace.AddDocument(project.Id, "testdocument", sourceText);

            var firstModel = await document.GetSemanticModelAsync();

            var tree1 = await document.GetSyntaxTreeAsync();

            var basemethod1 = tree1.FindTokenOnLeftOfPosition(position, CancellationToken.None).GetAncestor <CSharp.Syntax.BaseMethodDeclarationSyntax>();

            // Modify the document so we can use the old semantic model as a base.
            var updated = sourceText.WithChanges(new TextChange(new TextSpan(position, 0), "insertion"));

            workspace.TryApplyChanges(document.WithText(updated).Project.Solution);

            document = workspace.CurrentSolution.GetDocument(document.Id);
            var tree2 = await document.GetSyntaxTreeAsync();

            var basemethod2 = tree2.FindTokenOnLeftOfPosition(position, CancellationToken.None).GetAncestor <CSharp.Syntax.BaseMethodDeclarationSyntax>();

            var           service = new CSharp.CSharpSemanticFactsService();
            SemanticModel testModel;
            var           m = service.TryGetSpeculativeSemanticModel(firstModel, basemethod1, basemethod2, out testModel);

            var xSymbol = testModel.LookupSymbols(position).First(s => s.Name == "x");

            // This should not throw an exception.
            Assert.NotNull(SymbolKey.Create(xSymbol));
        }
        public async Task TestHasSuccessfullyLoadedBeingFalseWhenFileOpened()
        {
            var workspace = new AdhocWorkspace();

            var analyzerReference = new AnalyzerImageReference(ImmutableArray.Create <DiagnosticAnalyzer>(new Analyzer()));

            workspace.TryApplyChanges(workspace.CurrentSolution.WithAnalyzerReferences(new[] { analyzerReference }));

            var document = GetDocumentFromIncompleteProject(workspace);

            // open document
            workspace.OpenDocument(document.Id);

            await TestAnalyzerAsync(workspace, document, AnalyzerResultSetter, expectedSyntax : true, expectedSemantic : true);
        }
Beispiel #24
0
 private void UpdateDocument(string code)
 {
     if (document == null)
     {
         document = project.AddDocument("Script", SourceText.From(code));
     }
     else
     {
         document = document.WithText(SourceText.From(code));
         if (!workspace.TryApplyChanges(workspace.CurrentSolution))
         {
             throw new Exception("Unable to update document for code completion service");
         }
     }
 }
Beispiel #25
0
        private void UpdateDocument(string code)
        {
            if (doc == null)
            {
                doc        = workspace.AddDocument(project.Id, "ManagerScript.cs", SourceText.From(code));
                completion = CompletionService.GetService(doc);
            }

            Document document = doc.WithText(SourceText.From(code));

            if (!workspace.TryApplyChanges(document.Project.Solution))
            {
                throw new Exception("Unable to apply changes to solution");
            }
            doc = workspace.CurrentSolution.GetDocument(doc.Id);
        }
        private static Document GetCSharpDocument(RazorCodeDocument codeDocument, FormattingOptions options)
        {
            var adhocWorkspace = new AdhocWorkspace();
            var csharpOptions  = adhocWorkspace.Options
                                 .WithChangedOption(CodeAnalysis.Formatting.FormattingOptions.TabSize, LanguageNames.CSharp, (int)options.TabSize)
                                 .WithChangedOption(CodeAnalysis.Formatting.FormattingOptions.IndentationSize, LanguageNames.CSharp, (int)options.TabSize)
                                 .WithChangedOption(CodeAnalysis.Formatting.FormattingOptions.UseTabs, LanguageNames.CSharp, !options.InsertSpaces);

            adhocWorkspace.TryApplyChanges(adhocWorkspace.CurrentSolution.WithOptions(csharpOptions));

            var project          = adhocWorkspace.AddProject("TestProject", LanguageNames.CSharp);
            var csharpSourceText = codeDocument.GetCSharpSourceText();
            var csharpDocument   = adhocWorkspace.AddDocument(project.Id, "TestDocument", csharpSourceText);

            return(csharpDocument);
        }
        public async Task TestHasSuccessfullyLoadedBeingFalseFSAOn()
        {
            var workspace = new AdhocWorkspace();

            var analyzerReference = new AnalyzerImageReference(ImmutableArray.Create <DiagnosticAnalyzer>(new Analyzer()));

            var options = workspace.CurrentSolution.Options
                          .WithChangedOption(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp, BackgroundAnalysisScope.FullSolution);

            workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(options).WithAnalyzerReferences(new[] { analyzerReference }));
            var document = GetDocumentFromIncompleteProject(workspace);

            // open document
            workspace.OpenDocument(document.Id);

            await TestAnalyzerAsync(workspace, document, AnalyzerResultSetter, expectedSyntax : true, expectedSemantic : true);
        }
Beispiel #28
0
        private static void BuildWorkspace()
        {
            // Firstly, we create our workspace.
            Workspace = new AdhocWorkspace();

            // Next, we create the solution and project that houses our source code.
            // A solution and project map to the
            Solution = Workspace.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default));
            Project  = Solution.AddProject("MyCodeBase", "MyCodeBase", LanguageNames.CSharp);

            // To load the assemblies for our stand-alone Roslyn based app,
            // we are doing a little trick to find the essential assemblies.
            // Here I'm scanning the app domain for mscorlib, System and System.Core
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();

            var mscorlib   = assemblies.FirstOrDefault(a => a.GetName().Name == "mscorlib");
            var system     = assemblies.FirstOrDefault(a => a.GetName().Name == "System");
            var systemCore = assemblies.FirstOrDefault(a => a.GetName().Name == "System.Core");

            // As Roslyns solution and project model is immutable, each time we mutate the Project we
            // need to then use the result for future operations.
            Project = Project.AddMetadataReference(MetadataReference.CreateFromFile(mscorlib.Location));
            Project = Project.AddMetadataReference(MetadataReference.CreateFromFile(system.Location));
            Project = Project.AddMetadataReference(MetadataReference.CreateFromFile(systemCore.Location));

            // Lastly, let's set the apps solution to the newly mutated solution that contains the project
            // which references our core assemblies.
            Solution = Project.Solution;

            const string ResourceId = "IntroductionToRoslyn.Resources.MyCustomAttribute.cs";
            string       code       = ReadResourceContent(Assembly.GetExecutingAssembly(), ResourceId);

            // Adding code to a compilation is as simple as using AddDocument
            // This:
            //  - Creates a new document in the project.
            //  - Readies it for parsing into a SyntaxTree.
            //  - Consumes it and loads its symbols into the semantic model.
            Document = Project.AddDocument("MyCustomAttribute.cs", code);

            // Because of Roslyns immutable project model, we need to store our changes back up
            Project  = Document.Project;
            Solution = Project.Solution;

            // Finally, we commit our mutated solution back to the workspace.
            Workspace.TryApplyChanges(Project.Solution);
        }
Beispiel #29
0
        public async Task PublicToIntenalFix_ShouldMakeClassInternal()
        {
            var services = new ServiceCollection();

            services
            .AddLogging()
            .AddSingleton <PublicToInternalFix>();
            var provider = services.BuildServiceProvider();

            var fixer = provider.GetRequiredService <PublicToInternalFix>();

            var workspace  = new AdhocWorkspace();
            var solution   = workspace.AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Default));
            var libProject = workspace.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Default, "Lib", "Lib", LanguageNames.CSharp));

            var sourceText = SourceText.From(@"
                using System;
                namespace Lib 
                {
                    public class Foo 
                    {
                        public int Prop { get; set; }
                    }

                    public class Bar 
                    {
                       public int Prop { get; set; }
                    }
                }
            ");
            var doc        = workspace.AddDocument(libProject.Id, "Lib.cs", sourceText);

            var compilation = await workspace.CurrentSolution.GetProject(libProject.Id).GetCompilationAsync();

            var symbols = compilation.GetSymbolsWithName(_ => true);

            var newSolution = await fixer.MakePublicTypesInternal(workspace.CurrentSolution, symbols.OfType <INamedTypeSymbol>());

            Assert.IsTrue(workspace.TryApplyChanges(newSolution));

            var text = await workspace.CurrentSolution.GetDocument(doc.Id).GetTextAsync();

            Assert.IsTrue(text.ToString().Contains("internal class Foo"));
            Assert.IsTrue(text.ToString().Contains("internal class Bar"));
        }
        private CSharpCompilationCaptureResult Build(string projectFileOrSolution, Dictionary <string, string> properties)
        {
            // Create a bin log
            var tempBinLog = BuildBinLog(projectFileOrSolution, properties);

            // Read compiler invocations from the log
            var invocations = Microsoft.Build.Logging.StructuredLogger.CompilerInvocationsReader.ReadInvocations(tempBinLog);

            File.Delete(tempBinLog);

            // Create the workspace for all the projects
            var workspace     = new AdhocWorkspace();
            var projectToArgs = new Dictionary <ProjectId, CSharpCommandLineArguments>();

            foreach (var compilerInvocation in invocations)
            {
                // We support only CSharp projects
                if (compilerInvocation.Language != Microsoft.Build.Logging.StructuredLogger.CompilerInvocation.CSharp)
                {
                    continue;
                }

                // Rebuild command line arguments
                // Try to discard the exec name by going straight to the first csc parameter (assuming that we are using / instead of -)
                // TODO: very brittle, issue opened on StructuredLogger https://github.com/KirillOsenkov/MSBuildStructuredLog/issues/413
                var commandLineArgs    = compilerInvocation.CommandLineArguments;
                var indexOfFirstOption = commandLineArgs.IndexOf(" /", StringComparison.Ordinal);
                if (indexOfFirstOption >= 0)
                {
                    commandLineArgs = commandLineArgs.Substring(indexOfFirstOption + 1);
                }
                var args = ParseArguments(commandLineArgs);

                var projectName = Path.GetFileNameWithoutExtension(compilerInvocation.ProjectFilePath);
                var project     = workspace.AddProject(projectName, LanguageNames.CSharp);

                project = GetCompilationOptionsAndFiles(project, compilerInvocation, args, out var csharpArguments);

                projectToArgs[project.Id] = csharpArguments;

                workspace.TryApplyChanges(project.Solution);
            }

            return(new CSharpCompilationCaptureResult(workspace, projectToArgs));
        }
        public void TestRemoveProject_TryApplyChanges()
        {
            var pid = ProjectId.CreateNewId();
            var info = ProjectInfo.Create(
                pid,
                version: VersionStamp.Default,
                name: "TestProject",
                assemblyName: "TestProject.dll",
                language: LanguageNames.CSharp);

            using (var ws = new AdhocWorkspace())
            {
                ws.AddProject(info);

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

                var newSolution = ws.CurrentSolution.RemoveProject(pid);
                Assert.Equal(0, newSolution.Projects.Count());

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

                Assert.Equal(0, ws.CurrentSolution.Projects.Count());
            }
        }
        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);
            }
        }