示例#1
0
        static List <CodeAction> GetActions(CodeRefactoringProvider action, string input, out CSharpDiagnosticTestBase.TestWorkspace workspace, out Document doc, CSharpParseOptions parseOptions = null)
        {
            TextSpan selectedSpan;
            TextSpan markedSpan;
            string   text = ParseText(input, out selectedSpan, out markedSpan);

            workspace = new CSharpDiagnosticTestBase.TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            if (parseOptions == null)
            {
                parseOptions = new CSharpParseOptions(
                    LanguageVersion.CSharp6,
                    DocumentationMode.Diagnose | DocumentationMode.Parse,
                    SourceCodeKind.Regular,
                    ImmutableArray.Create("DEBUG", "TEST")
                    );
            }
            workspace.Options.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, false);
            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "TestProject",
                               "TestProject",
                               LanguageNames.CSharp,
                               null,
                               null,
                               new CSharpCompilationOptions(
                                   OutputKind.DynamicallyLinkedLibrary,
                                   "",
                                   "",
                                   "Script",
                                   null,
                                   OptimizationLevel.Debug,
                                   false,
                                   true
                                   ),
                               parseOptions,
                               new[] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text), VersionStamp.Create()))
                    )
            },
                               null,
                               DiagnosticTestBase.DefaultMetadataReferences
                               )
                           );
            doc = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId);
            var actions = new List <CodeAction>();
            var context = new CodeRefactoringContext(doc, selectedSpan, actions.Add, default(CancellationToken));

            action.ComputeRefactoringsAsync(context).Wait();
            if (markedSpan.Start > 0)
            {
                //foreach (var nra in actions.OfType<NRefactoryCodeAction>())
                //{
                //    Assert.AreEqual(markedSpan, nra.TextSpan, "Activation span does not match.");
                //}
            }
            return(actions);
        }
示例#2
0
        private async Task <Solution> GetSolutionAsync(ISolutionSynchronizationService 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)));
        }
示例#3
0
 public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 => Task.FromResult(TextAndVersion.Create(SourceText.From(_text), VersionStamp.Create(), _hostDocument.FilePath));
示例#4
0
        protected static void AnalyzeWithRule <T>(Func <string, SyntaxTree> parseTextFunc, Func <SyntaxTree[], Compilation> createCompilationFunc, string language, string input, string ruleId, string output = null, int issueToFix = -1, int actionToRun = 0, Action <int, Diagnostic> diagnosticCheck = null) where T : DiagnosticAnalyzer, new()
        {
            var text = new StringBuilder();

            var expectedDiagnosics = new List <TextSpan>();
            int start = -1;

            for (int i = 0; i < input.Length; i++)
            {
                char ch = input[i];
                if (ch == '$')
                {
                    if (start < 0)
                    {
                        start = text.Length;
                        continue;
                    }
                    expectedDiagnosics.Add(TextSpan.FromBounds(start, text.Length));
                    start = -1;
                }
                else
                {
                    text.Append(ch);
                }
            }

            var syntaxTree = parseTextFunc(text.ToString());

            Compilation compilation = createCompilationFunc(new[] { syntaxTree });

            var diagnostics = new List <Diagnostic>();
            var compilationWithAnalyzers = compilation.WithAnalyzers(System.Collections.Immutable.ImmutableArray <DiagnosticAnalyzer> .Empty.Add(new T()));

            diagnostics.AddRange(compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().GetAwaiter().GetResult());


            if (expectedDiagnosics.Count != diagnostics.Count)
            {
                Console.WriteLine("Diagnostics: " + diagnostics.Count);
                foreach (var diag in diagnostics)
                {
                    Console.WriteLine(diag.Id + "/" + diag.GetMessage());
                }
                Assert.True(false, "Diagnostic count mismatch expected: " + expectedDiagnosics.Count + " but was:" + diagnostics.Count);
            }

            for (int i = 0; i < expectedDiagnosics.Count; i++)
            {
                var d         = diagnostics[i];
                var wholeSpan = GetWholeSpan(d);
                if (wholeSpan != expectedDiagnosics[i])
                {
                    Assert.True(false, "Diagnostic " + i + " span mismatch expected: " + expectedDiagnosics[i] + " but was " + wholeSpan);
                }
                if (diagnosticCheck != null)
                {
                    diagnosticCheck(i, d);
                }
            }

            if (output == null)
            {
                return;
            }

            var workspace  = new TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "", "", language, null, null, null, null,
                               new[] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text.ToString()), VersionStamp.Create())))
            }
                               ));
            if (issueToFix < 0)
            {
                diagnostics.Reverse();
                foreach (var v in diagnostics)
                {
                    RunFix(workspace, projectId, documentId, v);
                }
            }
            else
            {
                RunFix(workspace, projectId, documentId, diagnostics.ElementAt(issueToFix), actionToRun);
            }

            var txt = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId).GetTextAsync().GetAwaiter().GetResult().ToString();

            txt    = Utils.HomogenizeEol(txt);
            output = Utils.HomogenizeEol(output);
            if (output != txt)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("expected:");
                sb.AppendLine(output);
                sb.AppendLine("got:");
                sb.AppendLine(txt);
                Assert.True(false, sb.ToString());
            }
        }
示例#5
0
            public override async Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
            {
                var text = await RoslynServices.AssetService.GetAssetAsync <SourceText>(_checksum, cancellationToken).ConfigureAwait(false);

                return(TextAndVersion.Create(text, VersionStamp.Create()));
            }
示例#6
0
        private void UpdateProject(ProjectFileInfo projectFileInfo)
        {
            var project = _workspace.CurrentSolution.GetProject(projectFileInfo.WorkspaceId);

            var unusedDocuments = project.Documents.ToDictionary(d => d.FilePath, d => d.Id);

            foreach (var file in projectFileInfo.SourceFiles)
            {
                if (unusedDocuments.Remove(file))
                {
                    continue;
                }

                using (var stream = File.OpenRead(file))
                {
                    var sourceText = SourceText.From(stream, encoding: Encoding.UTF8);
                    var id         = DocumentId.CreateNewId(projectFileInfo.WorkspaceId);
                    var version    = VersionStamp.Create();

                    var loader = TextLoader.From(TextAndVersion.Create(sourceText, version));

                    _workspace.AddDocument(DocumentInfo.Create(id, file, filePath: file, loader: loader));
                }
            }

            foreach (var unused in unusedDocuments)
            {
                _workspace.RemoveDocument(unused.Value);
            }

            var unusedProjectReferences = new HashSet <ProjectReference>(project.ProjectReferences);

            foreach (var projectReferencePath in projectFileInfo.ProjectReferences)
            {
                ProjectFileInfo projectReferenceInfo;
                if (_context.Projects.TryGetValue(projectReferencePath, out projectReferenceInfo))
                {
                    var reference = new ProjectReference(projectReferenceInfo.WorkspaceId);

                    if (unusedProjectReferences.Remove(reference))
                    {
                        // This reference already exists
                        continue;
                    }

                    _workspace.AddProjectReference(project.Id, reference);
                }
                else
                {
                    _logger.WriteWarning(string.Format("Unable to resolve project reference '{0}' for '{1}'.", projectReferencePath, projectFileInfo.ProjectFilePath));
                }
            }

            foreach (var unused in unusedProjectReferences)
            {
                _workspace.RemoveProjectReference(project.Id, unused);
            }

            var unusedAnalyzers = new Dictionary <string, AnalyzerReference>(project.AnalyzerReferences.ToDictionary(a => a.FullPath));

            foreach (var analyzerPath in projectFileInfo.Analyzers)
            {
                if (!File.Exists(analyzerPath))
                {
                    _logger.WriteWarning(string.Format("Unable to resolve assembly '{0}'", analyzerPath));
                }
                else
                {
                    if (unusedAnalyzers.Remove(analyzerPath))
                    {
                        continue;
                    }
#if ASPNET50
                    var analyzerReference = new AnalyzerFileReference(analyzerPath);
                    project.AddAnalyzerReference(analyzerReference);
#endif
                }
            }

            foreach (var analyzerReference in unusedAnalyzers.Values)
            {
                project.RemoveAnalyzerReference(analyzerReference);
            }

            var unusedReferences = new HashSet <MetadataReference>(project.MetadataReferences);

            foreach (var referencePath in projectFileInfo.References)
            {
                if (!File.Exists(referencePath))
                {
                    _logger.WriteWarning(string.Format("Unable to resolve assembly '{0}'", referencePath));
                }
                else
                {
                    var metadataReference = _metadataReferenceCache.GetMetadataReference(referencePath);

                    if (unusedReferences.Remove(metadataReference))
                    {
                        continue;
                    }

                    _logger.WriteVerbose(string.Format("Adding reference '{0}' to '{1}'.", referencePath, projectFileInfo.ProjectFilePath));
                    _workspace.AddMetadataReference(project.Id, metadataReference);
                }
            }

            foreach (var reference in unusedReferences)
            {
                _workspace.RemoveMetadataReference(project.Id, reference);
            }
        }
        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.Equal(false, doc.TryGetText(out var currentText));

                ws.OpenAdditionalDocument(docInfo.Id);

                doc = ws.CurrentSolution.GetAdditionalDocument(docInfo.Id);
                Assert.Equal(true, doc.TryGetText(out currentText));
                Assert.Equal(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.Equal(false, doc.TryGetText(out currentText));
            }
        }
        static List <CodeAction> GetActions(CodeFixProvider action, string input, out DiagnosticTestBase.TestWorkspace workspace, out Document doc, CSharpParseOptions parseOptions = null)
        {
            TextSpan selectedSpan;
            string   text = ParseText(input, out selectedSpan);

            workspace = new DiagnosticTestBase.TestWorkspace();
            var projectId  = ProjectId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            if (parseOptions == null)
            {
                parseOptions = new CSharpParseOptions(
                    LanguageVersion.CSharp6,
                    DocumentationMode.Diagnose | DocumentationMode.Parse,
                    SourceCodeKind.Regular,
                    ImmutableArray.Create("DEBUG", "TEST")
                    );
            }
            workspace.Options.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, false);
            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "TestProject",
                               "TestProject",
                               LanguageNames.CSharp,
                               null,
                               null,
                               new CSharpCompilationOptions(
                                   OutputKind.DynamicallyLinkedLibrary,
                                   false,
                                   "",
                                   "",
                                   "Script",
                                   null,
                                   OptimizationLevel.Debug,
                                   false,
                                   true
                                   ),
                               parseOptions,
                               new[] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(text), VersionStamp.Create()))
                    )
            },
                               null,
                               CSharpDiagnosticTestBase.DefaultMetadataReferences
                               )
                           );
            doc = workspace.CurrentSolution.GetProject(projectId).GetDocument(documentId);
            var actions     = new List <Tuple <CodeAction, ImmutableArray <Diagnostic> > >();
            var model       = doc.GetSemanticModelAsync().GetAwaiter().GetResult();
            var diagnostics = model.GetDiagnostics();

            if (diagnostics.Length == 0)
            {
                return(new List <CodeAction>());
            }

            foreach (var d in diagnostics)
            {
                if (action.FixableDiagnosticIds.Contains(d.Id))
                {
                    if (selectedSpan.Start > 0)
                    {
                        Assert.True(selectedSpan == d.Location.SourceSpan, "Activation span does not match.");
                    }

                    var context = new CodeFixContext(doc, d.Location.SourceSpan, diagnostics.Where(d2 => d2.Location.SourceSpan == d.Location.SourceSpan).ToImmutableArray(), (arg1, arg2) => actions.Add(Tuple.Create(arg1, arg2)), default(CancellationToken));
                    action.RegisterCodeFixesAsync(context);
                }
            }


            return(actions.Select(a => a.Item1).ToList());
        }
示例#9
0
 /// <summary>
 /// Closes the document.
 /// </summary>
 /// <param name="documentId">The document identifier.</param>
 public override void CloseDocument(DocumentId documentId)
 {
     base.CloseDocument(documentId);
     OnDocumentClosed(documentId, TextLoader.From(TextAndVersion.Create(CurrentSolution.GetDocument(documentId).GetTextAsync().Result, VersionStamp.Create())));
 }
 public void AddOrAccess(TextAndVersion instance, IWeakAction <TextAndVersion> evictor)
 {
     evictor.Invoke(instance);
 }
示例#11
0
            protected override async Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken)
            {
                var currentSolution = solution;
                var fixerTasks      = new List <Task>();
                var addedDocs       = new ConcurrentBag <Document>();
                var updatedDocs     = new ConcurrentBag <Document>();

                foreach (var pair in diagnosticsToFix)
                {
                    var project = solution.GetProject(pair.Key.Id);
                    Debug.Assert(project != null, "Failed to get project from solution.");
                    var diagnostics = pair.Value;

                    var group = diagnostics.GroupBy(d => d.Properties["TargetFullName"]);
                    foreach (var diag in group)
                    {
                        var diagnostic = diag.First();
                        var document   = diagnostic.Location.IsInSource ?
                                         project.Documents.FirstOrDefault(doc => doc.FilePath == diagnostic.Location.SourceTree.FilePath) :
                                         project.GetDocument(diagnostic.Location.SourceTree);

                        Debug.Assert(document != null, "Failed to locate document from diagnostic.");

                        fixerTasks.Add(new CodeFixer(document, diagnostic, addedDocs, updatedDocs, codeActionFactory)
                                       .RunAsync(cancellationToken));
                    }
                }

                await Task.WhenAll(fixerTasks).ConfigureAwait(false);

                foreach (var addedDoc in addedDocs)
                {
                    var addedText = await addedDoc.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    var addedVersion = await addedDoc.GetTextVersionAsync(cancellationToken).ConfigureAwait(false);

                    currentSolution = currentSolution.AddDocument(DocumentInfo.Create(
                                                                      addedDoc.Id, addedDoc.Name, addedDoc.Folders,
                                                                      addedDoc.SourceCodeKind,
                                                                      TextLoader.From(TextAndVersion.Create(addedText, addedVersion, addedDoc.FilePath)),
                                                                      addedDoc.FilePath));
                }

                foreach (var updatedDoc in updatedDocs)
                {
                    var updatedText = await updatedDoc.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    currentSolution = currentSolution.WithDocumentText(updatedDoc.Id, updatedText);
                }

                return(currentSolution);
            }
        private AspNet5.Project CreateProjectWithSourceFile(string projectPath, string documentPath)
        {
            AspNet5.Project project;
            _context.TryAddProject(projectPath, out project);
            var projectId    = ProjectId.CreateNewId();
            var versionStamp = VersionStamp.Create();
            var projectInfo  = ProjectInfo.Create(projectId, versionStamp,
                                                  "ProjectName", "AssemblyName",
                                                  LanguageNames.CSharp, projectPath);

            var document = DocumentInfo.Create(DocumentId.CreateNewId(projectInfo.Id), documentPath, loader: TextLoader.From(TextAndVersion.Create(SourceText.From(""), versionStamp)), filePath: documentPath);

            _workspace.AddProject(projectInfo);
            _workspace.AddDocument(document);
            return(project);
        }
        public override async Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
        {
            var output = await _document.GetGeneratedOutputAsync().ConfigureAwait(false);

            return(TextAndVersion.Create(SourceText.From(output.GetCSharpDocument().GeneratedCode), _version, _filePath));
        }
示例#14
0
        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);

            using 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);
        }
        private async Task CheckUpdatedDocumentTextIsObservablyConstantAsync(AdhocWorkspace ws)
        {
            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,
                documents: new[] { docInfo });

            ws.AddProject(projInfo);
            var doc = ws.CurrentSolution.GetDocument(docInfo.Id);

            // change document
            var root = await doc.GetSyntaxRootAsync();

            var newRoot = root.WithAdditionalAnnotations(new SyntaxAnnotation());

            Assert.NotSame(root, newRoot);
            var newDoc = doc.Project.Solution.WithDocumentSyntaxRoot(doc.Id, newRoot).GetDocument(doc.Id);

            Assert.NotSame(doc, newDoc);

            var newDocText = await newDoc.GetTextAsync();

            var sameText = await newDoc.GetTextAsync();

            Assert.Same(newDocText, sameText);

            var newDocTree = await newDoc.GetSyntaxTreeAsync();

            var treeText = newDocTree.GetText();

            Assert.Same(newDocText, treeText);
        }
		internal CompletionList CreateProvider (string input, SourceCodeKind? sourceCodeKind = null, bool usePreviousCharAsTrigger = false)
		{
			int cursorPosition = input.IndexOf ("$$", StringComparison.Ordinal);
			var parsedText = input.Substring (0, cursorPosition) + input.Substring (cursorPosition + 2);

			var workspace = new InspectionActionTestBase.TestWorkspace ();

			var projectId = ProjectId.CreateNewId ();
			//var solutionId = SolutionId.CreateNewId();
			var documentId = DocumentId.CreateNewId (projectId);

			workspace.Open (ProjectInfo.Create (
						projectId,
						VersionStamp.Create (),
						"TestProject",
						"TestProject",
						LanguageNames.CSharp,
						null,
						null,
						new CSharpCompilationOptions (
							OutputKind.DynamicallyLinkedLibrary,
							false,
							"",
							"",
							"Script",
							null,
							OptimizationLevel.Debug,
							false,
							false
						),
						new CSharpParseOptions (
							LanguageVersion.CSharp6,
							DocumentationMode.None,
							SourceCodeKind.Regular,
							ImmutableArray.Create ("DEBUG", "TEST")
						),
						new [] {
							DocumentInfo.Create(
								documentId,
								"a.cs",
								null,
								SourceCodeKind.Regular,
								TextLoader.From(TextAndVersion.Create(SourceText.From(parsedText), VersionStamp.Create()))
							)
						},
						null,
						InspectionActionTestBase.DefaultMetadataReferences
					)
			);
			var engine = new MonoDevelop.CSharp.Completion.RoslynParameterHintingEngine ();

			var compilation = workspace.CurrentSolution.GetProject (projectId).GetCompilationAsync ().Result;

			var document = workspace.CurrentSolution.GetDocument (documentId);
			var semanticModel = document.GetSemanticModelAsync ().Result;

			char triggerChar = cursorPosition > 0 ? document.GetTextAsync ().Result [cursorPosition - 1] : '\0';

			var cs = (CSharpCompletionService)workspace.Services.GetLanguageServices (LanguageNames.CSharp).GetService<CompletionService> ();
			cs.SetTestProviders (CreateCompletionProvider ());

			var trigger = CompletionTrigger.Invoke;
			if (usePreviousCharAsTrigger)
				trigger = new CompletionTrigger (CompletionTriggerKind.Insertion, triggerChar);
			return cs.GetCompletionsAsync (document, cursorPosition, trigger, null, null, default (CancellationToken)).Result;
		}
示例#17
0
        private void UpdateProject(ProjectFileInfo projectFileInfo)
        {
            var project = _workspace.CurrentSolution.GetProject(projectFileInfo.WorkspaceId);

            var unusedDocuments = project.Documents.ToDictionary(d => d.FilePath, d => d.Id);

            foreach (var file in projectFileInfo.SourceFiles)
            {
                if (unusedDocuments.Remove(file))
                {
                    continue;
                }

                using (var stream = File.OpenRead(file))
                {
                    var sourceText = SourceText.From(stream, encoding: Encoding.UTF8);
                    var id         = DocumentId.CreateNewId(projectFileInfo.WorkspaceId);
                    var version    = VersionStamp.Create();

                    var loader = TextLoader.From(TextAndVersion.Create(sourceText, version));

                    _workspace.AddDocument(DocumentInfo.Create(id, file, filePath: file, loader: loader));
                }
            }

            if (projectFileInfo.SpecifiedLanguageVersion.HasValue || projectFileInfo.DefineConstants != null)
            {
                var parseOptions = projectFileInfo.SpecifiedLanguageVersion.HasValue
                    ? new CSharpParseOptions(projectFileInfo.SpecifiedLanguageVersion.Value)
                    : new CSharpParseOptions();
                if (projectFileInfo.DefineConstants != null && projectFileInfo.DefineConstants.Any())
                {
                    parseOptions = parseOptions.WithPreprocessorSymbols(projectFileInfo.DefineConstants);
                }
                _workspace.SetParseOptions(project.Id, parseOptions);
            }

            foreach (var unused in unusedDocuments)
            {
                _workspace.RemoveDocument(unused.Value);
            }

            var unusedProjectReferences = new HashSet <ProjectReference>(project.ProjectReferences);

            foreach (var projectReferencePath in projectFileInfo.ProjectReferences)
            {
                ProjectFileInfo projectReferenceInfo;
                if (_context.Projects.TryGetValue(projectReferencePath, out projectReferenceInfo))
                {
                    var reference = new ProjectReference(projectReferenceInfo.WorkspaceId);

                    if (unusedProjectReferences.Remove(reference))
                    {
                        // This reference already exists
                        continue;
                    }

                    _workspace.AddProjectReference(project.Id, reference);
                }
                else
                {
                    _logger.LogWarning($"Unable to resolve project reference '{projectReferencePath}' for '{projectFileInfo}'.");
                }
            }

            foreach (var unused in unusedProjectReferences)
            {
                _workspace.RemoveProjectReference(project.Id, unused);
            }

            var unusedAnalyzers = new Dictionary <string, AnalyzerReference>(project.AnalyzerReferences.ToDictionary(a => a.FullPath));

            foreach (var analyzerPath in projectFileInfo.Analyzers)
            {
                if (!File.Exists(analyzerPath))
                {
                    _logger.LogWarning($"Unable to resolve assembly '{analyzerPath}'");
                }
                else
                {
                    if (unusedAnalyzers.Remove(analyzerPath))
                    {
                        continue;
                    }
#if DNX451
                    var analyzerReference = new AnalyzerFileReference(analyzerPath, new SimpleAnalyzerAssemblyLoader());
                    project.AddAnalyzerReference(analyzerReference);
#endif
                }
            }

            foreach (var analyzerReference in unusedAnalyzers.Values)
            {
                project.RemoveAnalyzerReference(analyzerReference);
            }

            var unusedReferences = new HashSet <MetadataReference>(project.MetadataReferences);

            foreach (var referencePath in projectFileInfo.References)
            {
                if (!File.Exists(referencePath))
                {
                    _logger.LogWarning($"Unable to resolve assembly '{referencePath}'");
                }
                else
                {
                    var metadataReference = _metadataReferenceCache.GetMetadataReference(referencePath);

                    if (unusedReferences.Remove(metadataReference))
                    {
                        continue;
                    }

                    _logger.LogDebug($"Adding reference '{referencePath}' to '{projectFileInfo.ProjectFilePath}'.");
                    _workspace.AddMetadataReference(project.Id, metadataReference);
                }
            }

            foreach (var reference in unusedReferences)
            {
                _workspace.RemoveMetadataReference(project.Id, reference);
            }
        }
示例#18
0
 public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     return(Task.FromResult(TextAndVersion.Create(emptySourceText, VersionStamp.Default)));
 }
 private static TextDocumentState CreateTextState(Solution solution, SourceText text)
 {
     // we just need a fake state to call GetTextAsync that return given sourcetext
     return(TextDocumentState.Create(
                DocumentInfo.Create(
                    DocumentId.CreateNewId(ProjectId.CreateNewId()), "unused", loader: TextLoader.From(TextAndVersion.Create(text, VersionStamp.Default))),
                solution.Services));
 }
示例#20
0
        /// <summary>
        /// Called when a "." is pressed - the previous word is found,
        /// and if matched in the treeview, the members listbox is
        /// populated with items from the tree, which are first sorted.
        /// </summary>
        /// <returns>Whether an items are found for the word</returns>
        ///
        private bool populateListBox()
        {
            this.listBoxAutoComplete.Items.Clear();



            // generate list of suggestions
            var host      = MefHostServices.Create(MefHostServices.DefaultAssemblies);
            var workspace = new AdhocWorkspace(host);

            var scriptCode = prexistingVarDecs + richTextBox1.Text;

            // Need to pass in an array of all usings statements
            var compilationOptions = new CSharpCompilationOptions(
                OutputKind.DynamicallyLinkedLibrary,
                usings: new[] { "System" });


            var scriptProjectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Script", "Script", LanguageNames.CSharp, isSubmission: true)
                                    .WithMetadataReferences(new[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
            })
                                    .WithCompilationOptions(compilationOptions);

            var scriptProject      = workspace.AddProject(scriptProjectInfo);
            var scriptDocumentInfo = DocumentInfo.Create(
                DocumentId.CreateNewId(scriptProject.Id), "Script",
                sourceCodeKind: SourceCodeKind.Script,
                loader: TextLoader.From(TextAndVersion.Create(SourceText.From(scriptCode), VersionStamp.Create())));
            var scriptDocument = workspace.AddDocument(scriptDocumentInfo);

            // cursor position is at the end
            var position = scriptCode.Length;

            var completionService = CompletionService.GetService(scriptDocument);
            var results           = completionService.GetCompletionsAsync(scriptDocument, position).GetAwaiter().GetResult();
            //var suggestions = new AutoCompleteStringCollection();
            var suggestions        = new List <string>();
            int currentSuggestions = 0;

            if (results == null)
            {
                return(false);
            }
            foreach (var i in results.Items)
            {
                //suggestions.Add(scriptCode.Substring(dec.Length, i.Span.Start) + i.DisplayText);
                if (scriptCode[scriptCode.Length - 1] != '.')
                {
                    string recString = richTextBox1.Text.Substring(i.Span.Start - prexistingVarDecs.Length, i.Span.Length);
                    if (recString != "" && i.DisplayText.Length >= recString.Length && i.DisplayText.Substring(0, recString.Length).ToLower().Equals(recString.ToLower()))
                    {
                        suggestions.Add(richTextBox1.Text.Substring(0, i.Span.Start - prexistingVarDecs.Length) + i.DisplayText);
                        this.listBoxAutoComplete.Items.Add(new GListBoxItem(i.DisplayText));
                        currentSuggestions++;
                    }
                }
                else
                {
                    suggestions.Add(richTextBox1.Text.Substring(0, i.Span.Start - prexistingVarDecs.Length) + i.DisplayText);
                    this.listBoxAutoComplete.Items.Add(new GListBoxItem(i.DisplayText));

                    currentSuggestions++;
                }
                //if (currentSuggestions > 5)
                //break;
            }
            currentCompletionList = results;
            //codeInput.AutoCompleteCustomSource = suggestions;
            return(true);
        }
示例#21
0
        public async Task TestUpdatedDocumentHasTextVersionAsync()
        {
            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,
                documents: new[] { docInfo }
                );

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

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

            // cause text to load and show that TryGet now works for text and version
            currentText = await doc.GetTextAsync();

            Assert.True(doc.TryGetText(out currentText));
            Assert.True(doc.TryGetTextVersion(out currentVersion));
            Assert.Equal(version, currentVersion);

            // change document
            var root = await doc.GetSyntaxRootAsync();

            var newRoot = root.WithAdditionalAnnotations(new SyntaxAnnotation());

            Assert.NotSame(root, newRoot);
            var newDoc = doc.WithSyntaxRoot(newRoot);

            Assert.NotSame(doc, newDoc);

            // text is now unavailable since it must be constructed from tree
            Assert.False(newDoc.TryGetText(out currentText));

            // version is available because it is cached
            Assert.True(newDoc.TryGetTextVersion(out currentVersion));

            // access it the hard way
            var actualVersion = await newDoc.GetTextVersionAsync();

            // version is the same
            Assert.Equal(currentVersion, actualVersion);

            // accessing text version did not cause text to be constructed.
            Assert.False(newDoc.TryGetText(out currentText));

            // now access text directly (force it to be constructed)
            var actualText = await newDoc.GetTextAsync();

            actualVersion = await newDoc.GetTextVersionAsync();

            // prove constructing text did not introduce a new version
            Assert.Equal(currentVersion, actualVersion);
        }
        public void Initalize()
        {
            var context = new AspNet5Context();

            context.RuntimePath = GetRuntimePath();

            if (!ScanForProjects(context))
            {
                // No ASP.NET 5 projects found so do nothing
                _logger.WriteInformation("No ASP.NET 5 projects found");
                return;
            }

            var wh = new ManualResetEventSlim();

            _designTimeHostManager.Start(context.RuntimePath, context.HostId, port =>
            {
                var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(new IPEndPoint(IPAddress.Loopback, port));

                var networkStream = new NetworkStream(socket);

                _logger.WriteInformation("Connected");

                context.Connection = new ProcessingQueue(networkStream, _logger);

                context.Connection.OnReceive += m =>
                {
                    var project = context.Projects[m.ContextId];

                    if (m.MessageType == "ProjectInformation")
                    {
                        var val = m.Payload.ToObject <ProjectMessage>();

                        project.Name               = val.Name;
                        project.GlobalJsonPath     = val.GlobalJsonPath;
                        project.Configurations     = val.Configurations;
                        project.Commands           = val.Commands;
                        project.ProjectSearchPaths = val.ProjectSearchPaths;

                        var unprocessed = project.ProjectsByFramework.Keys.ToList();

                        foreach (var frameworkData in val.Frameworks)
                        {
                            unprocessed.Remove(frameworkData.FrameworkName);

                            var frameworkProject = project.ProjectsByFramework.GetOrAdd(frameworkData.FrameworkName, framework =>
                            {
                                return(new FrameworkProject(project, framework));
                            });

                            var id = frameworkProject.ProjectId;

                            if (_workspace.CurrentSolution.ContainsProject(id))
                            {
                                continue;
                            }
                            else
                            {
                                var projectInfo = ProjectInfo.Create(
                                    id,
                                    VersionStamp.Create(),
                                    val.Name + "+" + frameworkData.ShortName,
                                    val.Name,
                                    LanguageNames.CSharp);

                                _workspace.AddProject(projectInfo);
                                context.WorkspaceMapping[id] = frameworkProject;
                            }

                            lock (frameworkProject.PendingProjectReferences)
                            {
                                var reference = new Microsoft.CodeAnalysis.ProjectReference(id);

                                foreach (var referenceId in frameworkProject.PendingProjectReferences)
                                {
                                    _workspace.AddProjectReference(referenceId, reference);
                                }

                                frameworkProject.PendingProjectReferences.Clear();
                            }
                        }

                        // Remove old projects
                        foreach (var frameworkName in unprocessed)
                        {
                            FrameworkProject frameworkProject;
                            project.ProjectsByFramework.TryRemove(frameworkName, out frameworkProject);
                            _workspace.RemoveProject(frameworkProject.ProjectId);
                        }
                    }
                    // This is where we can handle messages and update the
                    // language service
                    else if (m.MessageType == "References")
                    {
                        // References as well as the dependency graph information
                        var val = m.Payload.ToObject <ReferencesMessage>();

                        var frameworkProject = project.ProjectsByFramework[val.Framework.FrameworkName];
                        var projectId        = frameworkProject.ProjectId;

                        var metadataReferences = new List <MetadataReference>();
                        var projectReferences  = new List <Microsoft.CodeAnalysis.ProjectReference>();

                        var removedFileReferences    = frameworkProject.FileReferences.ToDictionary(p => p.Key, p => p.Value);
                        var removedRawReferences     = frameworkProject.RawReferences.ToDictionary(p => p.Key, p => p.Value);
                        var removedProjectReferences = frameworkProject.ProjectReferences.ToDictionary(p => p.Key, p => p.Value);

                        foreach (var file in val.FileReferences)
                        {
                            if (removedFileReferences.Remove(file))
                            {
                                continue;
                            }

                            var metadataReference = _metadataFileReferenceCache.GetMetadataReference(file);
                            frameworkProject.FileReferences[file] = metadataReference;
                            metadataReferences.Add(metadataReference);
                        }

                        foreach (var rawReference in val.RawReferences)
                        {
                            if (removedRawReferences.Remove(rawReference.Key))
                            {
                                continue;
                            }

                            var metadataReference = MetadataReference.CreateFromImage(rawReference.Value);
                            frameworkProject.RawReferences[rawReference.Key] = metadataReference;
                            metadataReferences.Add(metadataReference);
                        }

                        foreach (var projectReference in val.ProjectReferences)
                        {
                            if (removedProjectReferences.Remove(projectReference.Path))
                            {
                                continue;
                            }

                            var projectReferenceContextId = context.ProjectContextMapping[projectReference.Path];

                            var referencedProject = context.Projects[projectReferenceContextId];

                            var referencedFrameworkProject = referencedProject.ProjectsByFramework.GetOrAdd(projectReference.Framework.FrameworkName,
                                                                                                            framework =>
                            {
                                return(new FrameworkProject(referencedProject, framework));
                            });

                            var projectReferenceId = referencedFrameworkProject.ProjectId;

                            if (_workspace.CurrentSolution.ContainsProject(projectReferenceId))
                            {
                                projectReferences.Add(new Microsoft.CodeAnalysis.ProjectReference(projectReferenceId));
                            }
                            else
                            {
                                lock (referencedFrameworkProject.PendingProjectReferences)
                                {
                                    referencedFrameworkProject.PendingProjectReferences.Add(projectId);
                                }
                            }

                            referencedFrameworkProject.ProjectDependeees[project.Path] = projectId;

                            frameworkProject.ProjectReferences[projectReference.Path] = projectReferenceId;
                        }

                        foreach (var reference in metadataReferences)
                        {
                            _workspace.AddMetadataReference(projectId, reference);
                        }

                        foreach (var projectReference in projectReferences)
                        {
                            _workspace.AddProjectReference(projectId, projectReference);
                        }

                        foreach (var pair in removedProjectReferences)
                        {
                            _workspace.RemoveProjectReference(projectId, new Microsoft.CodeAnalysis.ProjectReference(pair.Value));
                            frameworkProject.ProjectReferences.Remove(pair.Key);

                            // TODO: Update the dependee's list
                        }

                        foreach (var pair in removedFileReferences)
                        {
                            _workspace.RemoveMetadataReference(projectId, pair.Value);
                            frameworkProject.FileReferences.Remove(pair.Key);
                        }

                        foreach (var pair in removedRawReferences)
                        {
                            _workspace.RemoveMetadataReference(projectId, pair.Value);
                            frameworkProject.RawReferences.Remove(pair.Key);
                        }
                    }
                    else if (m.MessageType == "CompilerOptions")
                    {
                        // Configuration and compiler options
                        var val = m.Payload.ToObject <CompilationOptionsMessage>();

                        var projectId = project.ProjectsByFramework[val.Framework.FrameworkName].ProjectId;

                        var options = val.CompilationOptions.CompilationOptions;

                        var specificDiagnosticOptions = options.SpecificDiagnosticOptions
                                                        .ToDictionary(p => p.Key, p => (ReportDiagnostic)p.Value);

                        var csharpOptions = new CSharpCompilationOptions(
                            outputKind: (OutputKind)options.OutputKind,
                            optimizationLevel: (OptimizationLevel)options.OptimizationLevel,
                            platform: (Platform)options.Platform,
                            generalDiagnosticOption: (ReportDiagnostic)options.GeneralDiagnosticOption,
                            warningLevel: options.WarningLevel,
                            allowUnsafe: options.AllowUnsafe,
                            concurrentBuild: options.ConcurrentBuild,
                            specificDiagnosticOptions: specificDiagnosticOptions
                            );

                        var parseOptions = new CSharpParseOptions(val.CompilationOptions.LanguageVersion,
                                                                  preprocessorSymbols: val.CompilationOptions.Defines);

                        _workspace.SetCompilationOptions(projectId, csharpOptions);
                        _workspace.SetParseOptions(projectId, parseOptions);
                    }
                    else if (m.MessageType == "Sources")
                    {
                        // The sources to feed to the language service
                        var val = m.Payload.ToObject <SourcesMessage>();

                        var frameworkProject = project.ProjectsByFramework[val.Framework.FrameworkName];
                        var projectId        = frameworkProject.ProjectId;

                        var unprocessed = new HashSet <string>(frameworkProject.Documents.Keys);

                        foreach (var file in val.Files)
                        {
                            if (unprocessed.Remove(file))
                            {
                                continue;
                            }

                            using (var stream = File.OpenRead(file))
                            {
                                var sourceText = SourceText.From(stream, encoding: Encoding.UTF8);
                                var id         = DocumentId.CreateNewId(projectId);
                                var version    = VersionStamp.Create();

                                frameworkProject.Documents[file] = id;

                                var loader = TextLoader.From(TextAndVersion.Create(sourceText, version));
                                _workspace.AddDocument(DocumentInfo.Create(id, file, filePath: file, loader: loader));
                            }
                        }

                        foreach (var file in unprocessed)
                        {
                            var docId = frameworkProject.Documents[file];
                            frameworkProject.Documents.Remove(file);
                            _workspace.RemoveDocument(docId);
                        }

                        frameworkProject.Loaded = true;
                    }

                    if (project.ProjectsByFramework.Values.All(p => p.Loaded))
                    {
                        wh.Set();
                    }
                };

                // Start the message channel
                context.Connection.Start();

                // Initialize the ASP.NET 5 projects
                Initialize(context);
            });

            wh.Wait();

            // TODO: Subscribe to _workspace changes and update DTH
            //Thread.Sleep(5000);

            //_workspace._workspaceChanged += (sender, e) =>
            //{
            //    var arg = e;
            //    var kind = e.Kind;

            //    if (e.Kind == _workspaceChangeKind.DocumentChanged ||
            //        e.Kind == _workspaceChangeKind.DocumentAdded ||
            //        e.Kind == _workspaceChangeKind.DocumentRemoved)
            //    {
            //        var frameworkProject = context._workspaceMapping[e.ProjectId];

            //        TriggerDependeees(context, frameworkProject.ProjectState.Path);
            //    }
            //};
        }
示例#23
0
        private async Task <Solution> CreateSolutionAsync(Checksum solutionChecksum, CancellationToken cancellationToken)
        {
            // synchronize whole solution first
            await _assetService.SynchronizeSolutionAssetsAsync(solutionChecksum, cancellationToken).ConfigureAwait(false);

            var solutionChecksumObject = await _assetService.GetAssetAsync <SolutionStateChecksums>(solutionChecksum, cancellationToken).ConfigureAwait(false);

            var workspace    = new AdhocWorkspace(RoslynServices.HostServices, workspaceKind: WorkspaceKind_RemoteWorkspace);
            var solutionInfo = await _assetService.GetAssetAsync <SerializedSolutionInfo>(solutionChecksumObject.Info, cancellationToken).ConfigureAwait(false);

            var projects = new List <ProjectInfo>();

            foreach (var projectChecksum in solutionChecksumObject.Projects)
            {
                var projectSnapshot = await _assetService.GetAssetAsync <ProjectStateChecksums>(projectChecksum, cancellationToken).ConfigureAwait(false);

                var projectInfo = await _assetService.GetAssetAsync <SerializedProjectInfo>(projectSnapshot.Info, cancellationToken).ConfigureAwait(false);

                if (!workspace.Services.IsSupported(projectInfo.Language))
                {
                    // only add project our workspace supports.
                    // workspace doesn't allow creating project with unknown languages
                    continue;
                }

                var documents = new List <DocumentInfo>();
                foreach (var documentChecksum in projectSnapshot.Documents)
                {
                    var documentSnapshot = await _assetService.GetAssetAsync <DocumentStateChecksums>(documentChecksum, cancellationToken).ConfigureAwait(false);

                    var documentInfo = await _assetService.GetAssetAsync <SerializedDocumentInfo>(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?
                    documents.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            textLoader,
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var p2p = new List <ProjectReference>();
                foreach (var checksum in projectSnapshot.ProjectReferences)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var reference = await _assetService.GetAssetAsync <ProjectReference>(checksum, cancellationToken).ConfigureAwait(false);

                    p2p.Add(reference);
                }

                var metadata = new List <MetadataReference>();
                foreach (var checksum in projectSnapshot.MetadataReferences)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var reference = await _assetService.GetAssetAsync <MetadataReference>(checksum, cancellationToken).ConfigureAwait(false);

                    metadata.Add(reference);
                }

                var analyzers = new List <AnalyzerReference>();
                foreach (var checksum in projectSnapshot.AnalyzerReferences)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var reference = await _assetService.GetAssetAsync <AnalyzerReference>(checksum, cancellationToken).ConfigureAwait(false);

                    analyzers.Add(reference);
                }

                var additionals = new List <DocumentInfo>();
                foreach (var documentChecksum in projectSnapshot.AdditionalDocuments)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var documentSnapshot = await _assetService.GetAssetAsync <DocumentStateChecksums>(documentChecksum, cancellationToken).ConfigureAwait(false);

                    var documentInfo = await _assetService.GetAssetAsync <SerializedDocumentInfo>(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?
                    additionals.Add(
                        DocumentInfo.Create(
                            documentInfo.Id,
                            documentInfo.Name,
                            documentInfo.Folders,
                            documentInfo.SourceCodeKind,
                            textLoader,
                            documentInfo.FilePath,
                            documentInfo.IsGenerated));
                }

                var compilationOptions = await _assetService.GetAssetAsync <CompilationOptions>(projectSnapshot.CompilationOptions, cancellationToken).ConfigureAwait(false);

                var parseOptions = await _assetService.GetAssetAsync <ParseOptions>(projectSnapshot.ParseOptions, cancellationToken).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)));
        }
示例#24
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());
            }
        }
示例#25
0
 protected virtual async Task <TextAndVersion> ReadCodeFileAsSTextAndVersionAsync(string embeddedResourceFileName) =>
 TextAndVersion.Create(
     SourceText.From(await ReadCodeFileAsStringAsync(embeddedResourceFileName)),
     VersionStamp.Default,
     embeddedResourceFileName);
        internal static ParameterHintingResult CreateProvider(string text)
        {
            string parsedText;
            string editorText;
            int    cursorPosition = text.IndexOf('$');
            int    endPos         = text.IndexOf('$', cursorPosition + 1);

            if (endPos == -1)
            {
                parsedText = editorText = text.Substring(0, cursorPosition) + text.Substring(cursorPosition + 1);
            }
            else
            {
                parsedText     = text.Substring(0, cursorPosition) + new string(' ', endPos - cursorPosition) + text.Substring(endPos + 1);
                editorText     = text.Substring(0, cursorPosition) + text.Substring(cursorPosition + 1, endPos - cursorPosition - 1) + text.Substring(endPos + 1);
                cursorPosition = endPos - 1;
            }

            var workspace = new InspectionActionTestBase.TestWorkspace();

            var projectId = ProjectId.CreateNewId();
            //var solutionId = SolutionId.CreateNewId();
            var documentId = DocumentId.CreateNewId(projectId);

            workspace.Open(ProjectInfo.Create(
                               projectId,
                               VersionStamp.Create(),
                               "TestProject",
                               "TestProject",
                               LanguageNames.CSharp,
                               null,
                               null,
                               new CSharpCompilationOptions(
                                   OutputKind.DynamicallyLinkedLibrary,
                                   false,
                                   "",
                                   "",
                                   "Script",
                                   null,
                                   OptimizationLevel.Debug,
                                   false,
                                   false
                                   ),
                               new CSharpParseOptions(
                                   LanguageVersion.CSharp6,
                                   DocumentationMode.None,
                                   SourceCodeKind.Regular,
                                   ImmutableArray.Create("DEBUG", "TEST")
                                   ),
                               new [] {
                DocumentInfo.Create(
                    documentId,
                    "a.cs",
                    null,
                    SourceCodeKind.Regular,
                    TextLoader.From(TextAndVersion.Create(SourceText.From(parsedText), VersionStamp.Create()))
                    )
            },
                               null,
                               InspectionActionTestBase.DefaultMetadataReferences
                               )
                           );

            var engine = new ParameterHintingEngine(workspace, new TestFactory());

            var compilation = workspace.CurrentSolution.GetProject(projectId).GetCompilationAsync().Result;

            if (!workspace.TryApplyChanges(workspace.CurrentSolution.WithDocumentText(documentId, SourceText.From(editorText))))
            {
                Assert.Fail();
            }
            var document      = workspace.CurrentSolution.GetDocument(documentId);
            var semanticModel = document.GetSemanticModelAsync().Result;

            return(engine.GetParameterDataProviderAsync(document, semanticModel, cursorPosition).Result);
        }
 internal override TextAndVersion LoadTextAndVersionSynchronously(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 => TextAndVersion.Create(_text, VersionStamp.Create());
示例#28
0
 public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     return(Task.FromResult(TextAndVersion.Create(_hostDocument.LoadText(cancellationToken), VersionStamp.Create(), "test")));
 }
示例#29
0
        public async Task <Dictionary <string, AssemblyInfo> > Execute([CallerFilePath] string sourceFile = null)
        {
            if (sourceFile == null)
            {
                throw new ArgumentNullException(nameof(sourceFile));
            }

            var builtAssemblies = new Dictionary <string, AssemblyInfo>();

            IEnumerable <AssemblyInfo> GetAssemblies()
            {
                var assemblyRegex    = new Regex(@"<\s*assembly(:\s*(?<Name>\w+))?\s*/?>");
                var endAssemblyRegex = new Regex(@"</\s*assembly\s*>");
                var typeRegex        = new Regex(@"<\s*type:\s*(?<Name>\w+)\s*/>");
                var referenceRegex   = new Regex(@"<\s*ref:\s*(?<Name>[\w_\.]+)\s*/>");
                var weaverRegex      = new Regex(@"<\s*weaver:\s*(?<Name>[\w_\.]+)\s*/>");

                using (var sr = new StreamReader(sourceFile))
                {
                    AssemblyInfo currentAssembly = null;
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        if (line == null)
                        {
                            continue;
                        }
                        string trimmed = line.Trim();
                        if (trimmed.StartsWith("//") || trimmed.StartsWith("/*"))
                        {
                            // ReSharper disable TooWideLocalVariableScope
                            Match assemblyStartMatch, typeMatch, referenceMatch, weaverMatch;
                            // ReSharper restore TooWideLocalVariableScope
                            if ((assemblyStartMatch = assemblyRegex.Match(trimmed)).Success)
                            {
                                if (currentAssembly != null)
                                {
                                    yield return(currentAssembly);
                                }
                                currentAssembly = new AssemblyInfo(assemblyStartMatch.Groups["Name"]?.Value);
                            }
                            else if (currentAssembly != null)
                            {
                                if (endAssemblyRegex.IsMatch(trimmed))
                                {
                                    yield return(currentAssembly);

                                    currentAssembly = null;
                                }
                                else if ((typeMatch = typeRegex.Match(trimmed)).Success)
                                {
                                    if (Enum.TryParse(typeMatch.Groups["Name"].Value, true, out OutputKind output))
                                    {
                                        currentAssembly.OutputKind = output;
                                    }
                                }
                                else if ((referenceMatch = referenceRegex.Match(trimmed)).Success)
                                {
                                    MetadataReference GetReference(string name)
                                    {
                                        if (builtAssemblies.TryGetValue(name, out AssemblyInfo builtAssembly))
                                        {
                                            return(MetadataReference.CreateFromFile(builtAssembly.Assembly.Location));
                                        }
                                        string filePath = $@".\{name}.dll";

                                        if (File.Exists(filePath))
                                        {
                                            return(MetadataReference.CreateFromFile(filePath));
                                        }
                                        //Assembly loadedAssembly = Assembly.Load(new AssemblyName(name));
                                        //if (loadedAssembly != null)
                                        //{
                                        //    return MetadataReference.CreateFromFile(loadedAssembly.Location);
                                        //}
                                        return(null);
                                    }

                                    MetadataReference reference = GetReference(referenceMatch.Groups["Name"].Value);
                                    if (reference != null)
                                    {
                                        currentAssembly.AddReference(reference);
                                    }
                                    //TODO: Else
                                }
                                else if ((weaverMatch = weaverRegex.Match(trimmed)).Success)
                                {
                                    Weaver weaver = Weaver.FindWeaver(weaverMatch.Groups["Name"].Value);
                                    if (weaver != null)
                                    {
                                        WeaverAdded?.Invoke(this, new WeaverAddedEventArgs(weaver));
                                        currentAssembly.AddWeaver(weaver);
                                    }
                                    //TODO: Else
                                }
                            }
                        }
                        currentAssembly?.AppendLine(line);
                    }
                    if (currentAssembly != null)
                    {
                        yield return(currentAssembly);
                    }
                }
            }

            var workspace = new AdhocWorkspace();

            foreach (AssemblyInfo assemblyInfo in GetAssemblies())
            {
                string assemblyName = $"AssemblyToTest{_instanceCount++}";

                var projectId = ProjectId.CreateNewId();

                var document = DocumentInfo.Create(DocumentId.CreateNewId(projectId), "Generated.cs",
                                                   loader: TextLoader.From(TextAndVersion.Create(SourceText.From(assemblyInfo.GetContents(), System.Text.Encoding.Unicode),
                                                                                                 VersionStamp.Create())));

                var project = workspace.AddProject(ProjectInfo.Create(projectId,
                                                                      VersionStamp.Create(), assemblyName, assemblyName, LanguageNames.CSharp,
                                                                      compilationOptions: new CSharpCompilationOptions(assemblyInfo.OutputKind),
                                                                      parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7_3),
                                                                      documents: new[] { document }, metadataReferences: assemblyInfo.References,
                                                                      filePath: Path.GetFullPath(
                                                                          $"{Path.GetFileNameWithoutExtension(Path.GetRandomFileName())}.csproj")));

                Compilation compile = await project.GetCompilationAsync();

                assemblyInfo.FilePath = Path.GetFullPath($"{assemblyName}.dll");
                string pdbPath = Path.ChangeExtension(assemblyInfo.FilePath, ".pdb");
                using (var file = File.Create(assemblyInfo.FilePath))
                    using (var pdbFile = File.Create(pdbPath))
                    {
                        var emitResult = compile.Emit(file, pdbFile);
                        if (emitResult.Success)
                        {
                            foreach (Weaver weaver in assemblyInfo.Weavers)
                            {
                                file.Position = 0;
                                weaver.ApplyToAssembly(file);
                            }
                        }
                        else
                        {
                            throw new CompileException(emitResult.Diagnostics);
                        }
                    }
                assemblyInfo.Assembly = Assembly.LoadFile(assemblyInfo.FilePath);
                builtAssemblies.Add(assemblyInfo.Name ?? assemblyName, assemblyInfo);
            }
            return(builtAssemblies);
        }
        public void Initalize()
        {
            var solutionFilePath = _env.SolutionFilePath;

            if (string.IsNullOrEmpty(solutionFilePath))
            {
                var solutions = Directory.GetFiles(_env.Path, "*.sln");

                switch (solutions.Length)
                {
                case 0:
                    _logger.WriteInformation(string.Format("No solution files found in '{0}'", _env.Path));
                    return;

                case 1:
                    solutionFilePath = solutions[0];
                    break;

                default:
                    _logger.WriteError("Could not determine solution file");
                    return;
                }
            }

            SolutionFile solutionFile = null;

            using (var stream = File.OpenRead(solutionFilePath))
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }

            _logger.WriteInformation(string.Format("Detecting projects in '{0}'.", solutionFilePath));

            var projectMap = new Dictionary <string, ProjectFileInfo>();

            foreach (var block in solutionFile.ProjectBlocks)
            {
                if (!_supportsProjectTypes.Contains(block.ProjectTypeGuid))
                {
                    _logger.WriteWarning("Skipped unsupported project type '{0}'", block.ProjectPath);
                    continue;
                }

                if (_projectMap.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

                var projectFilePath = Path.GetFullPath(Path.GetFullPath(Path.Combine(_env.Path, block.ProjectPath.Replace('\\', Path.DirectorySeparatorChar))));

                _logger.WriteInformation(string.Format("Loading project from '{0}'.", projectFilePath));

                ProjectFileInfo projectFileInfo = null;

                try
                {
                    projectFileInfo = ProjectFileInfo.Create(_logger, _env.Path, projectFilePath);

                    if (projectFileInfo == null)
                    {
                        _logger.WriteWarning(string.Format("Failed to process project file '{0}'.", projectFilePath));
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    _logger.WriteWarning(string.Format("Failed to process project file '{0}'.", projectFilePath), ex);
                    continue;
                }

                var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(projectFileInfo.Name),
                                                     VersionStamp.Create(),
                                                     projectFileInfo.Name,
                                                     projectFileInfo.AssemblyName,
                                                     LanguageNames.CSharp,
                                                     projectFileInfo.ProjectFilePath);

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;
                projectMap[projectFileInfo.ProjectFilePath] = projectFileInfo;

                _projectMap[block.ProjectGuid] = projectInfo.Id;
            }

            foreach (var projectFileInfo in projectMap.Values)
            {
                var project = _workspace.CurrentSolution.GetProject(projectFileInfo.WorkspaceId);

                var unusedDocuments = project.Documents.ToDictionary(d => d.FilePath, d => d.Id);

                foreach (var file in projectFileInfo.SourceFiles)
                {
                    if (unusedDocuments.Remove(file))
                    {
                        continue;
                    }

                    using (var stream = File.OpenRead(file))
                    {
                        var sourceText = SourceText.From(stream, encoding: Encoding.UTF8);
                        var id         = DocumentId.CreateNewId(projectFileInfo.WorkspaceId);
                        var version    = VersionStamp.Create();

                        var loader = TextLoader.From(TextAndVersion.Create(sourceText, version));

                        _workspace.AddDocument(DocumentInfo.Create(id, file, filePath: file, loader: loader));
                    }
                }

                foreach (var unused in unusedDocuments)
                {
                    _workspace.RemoveDocument(unused.Value);
                }

                var unusedProjectReferences = new HashSet <ProjectReference>(project.ProjectReferences);

                foreach (var projectReferencePath in projectFileInfo.ProjectReferences)
                {
                    ProjectFileInfo projectReferenceInfo;
                    if (projectMap.TryGetValue(projectReferencePath, out projectReferenceInfo))
                    {
                        var reference = new ProjectReference(projectReferenceInfo.WorkspaceId);

                        if (unusedProjectReferences.Remove(reference))
                        {
                            // This reference already exists
                            continue;
                        }

                        _workspace.AddProjectReference(project.Id, reference);
                    }
                    else
                    {
                        _logger.WriteWarning(string.Format("Unable to resolve project reference '{0}' for '{1}'.", projectReferencePath, projectFileInfo.ProjectFilePath));
                    }
                }

                foreach (var unused in unusedProjectReferences)
                {
                    _workspace.RemoveProjectReference(project.Id, unused);
                }

                var unusedReferences = new HashSet <MetadataReference>(project.MetadataReferences);

                foreach (var referencePath in projectFileInfo.References)
                {
                    if (!File.Exists(referencePath))
                    {
                        _logger.WriteWarning(string.Format("Unable to resolve assembly '{0}'", referencePath));
                    }
                    else
                    {
                        var metadataReference = _metadataReferenceCache.GetMetadataReference(referencePath);

                        if (unusedReferences.Remove(metadataReference))
                        {
                            continue;
                        }

                        _logger.WriteVerbose(string.Format("Adding reference '{0}' to '{1}'.", referencePath, projectFileInfo.ProjectFilePath));
                        _workspace.AddMetadataReference(project.Id, metadataReference);
                    }
                }

                foreach (var reference in unusedReferences)
                {
                    _workspace.RemoveMetadataReference(project.Id, reference);
                }
            }
        }
 public void AddOrAccess(TextAndVersion instance, IWeakAction<TextAndVersion> evictor)
 {
     evictor.Invoke(instance);
 }