Ejemplo n.º 1
0
        public void TestAddProject_TryApplyChanges()
        {
            using (var ws = new AdhocWorkspace())
            {
                ProjectId pid = ProjectId.CreateNewId();

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

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

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

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

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

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

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

                var doc = proj.Documents.First();
                Assert.Equal("MyDoc.cs", doc.Name);
            }
        }
Ejemplo n.º 2
0
        RoslynCodeDocument CreateDocument(ProjectId projectId, IDecompiledDocument doc)
        {
            var options = new CodeEditorOptions();

            options.ContentTypeString = ContentType;
            options.Roles.Add(PredefinedDsTextViewRoles.RoslynCodeEditor);
            options.Roles.Add(TextViewRole);
            var codeEditor = codeEditorProvider.Create(options);

            codeEditor.TextView.Options.SetOptionValue(DefaultWpfViewOptions.AppearanceCategory, AppearanceCategory);
            codeEditor.TextView.Options.SetOptionValue(DefaultTextViewHostOptions.GlyphMarginId, true);

            var textBuffer = codeEditor.TextView.TextBuffer;

            textBuffer.Replace(new Span(0, textBuffer.CurrentSnapshot.Length), doc.Code);

            var documentInfo = DocumentInfo.Create(DocumentId.CreateNewId(projectId), doc.NameNoExtension + FileExtension, null, SourceCodeKind.Regular, TextLoader.From(codeEditor.TextBuffer.AsTextContainer(), VersionStamp.Create()));

            return(new RoslynCodeDocument(codeEditor, documentInfo, doc.NameNoExtension));
        }
Ejemplo n.º 3
0
 public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 => Task.FromResult(TextAndVersion.Create(SourceText.From(_text), VersionStamp.Create()));
Ejemplo n.º 4
0
 public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     return(Task.FromResult(TextAndVersion.Create(_hostDocument.LoadText(cancellationToken), VersionStamp.Create(), "test")));
 }
        public static async Task <List <CustomSuggestion> > GetCodeCompletion(SourceInfo sourceInfo)
        {
            var refs = CompileResources.PortableExecutableCompletionReferences;

            List <string> usings = new() { "System",
                                           "System.IO",
                                           "System.Collections.Generic",
                                           "System.Collections",
                                           "System.Console",
                                           "System.Diagnostics",
                                           "System.Dynamic",
                                           "System.Linq",
                                           "System.Linq.Expressions",
                                           "System.Net.Http",
                                           "System.Text",
                                           "System.Net",
                                           "System.Threading.Tasks",
                                           "System.Numerics" };
            var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && File.Exists(a.Location) && !a.FullName.Contains("JSInterop.WebAssembly")).ToList();

            var partTypes = MefHostServices.DefaultAssemblies.Concat(assemblies)
                            .Distinct()?
                            .SelectMany(x => x?.GetTypes())?
                            .ToArray();

            var compositionContext = new ContainerConfiguration()
                                     .WithParts(partTypes)
                                     .CreateContainer();
            var host = MefHostServices.Create(compositionContext);

            var workspace = new AdhocWorkspace(host);

            string scriptCode         = sourceInfo.SourceCode;
            var    _                  = typeof(Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions);
            var    compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, usings: usings);

            if (refs == null || refs.Count == 0)
            {
                return(null);
            }

            var scriptProjectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Script", "Script", LanguageNames.CSharp, isSubmission: true)
                                    .WithMetadataReferences(refs)
                                    .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
            int position          = sourceInfo.LineNumberOffsetFromTemplate;
            var completionService = CompletionService.GetService(scriptDocument);
            var results           = await completionService.GetCompletionsAsync(scriptDocument, position);

            if (results == null && sourceInfo.LineNumberOffsetFromTemplate < sourceInfo.SourceCode.Length)
            {
                sourceInfo.LineNumberOffsetFromTemplate++;
                await GetCodeCompletion(sourceInfo);
            }

            if (sourceInfo.SourceCode[sourceInfo.LineNumberOffsetFromTemplate - 1].ToString() == "(")
            {
                sourceInfo.LineNumberOffsetFromTemplate--;
                results = completionService.GetCompletionsAsync(scriptDocument, sourceInfo.LineNumberOffsetFromTemplate).Result;
            }

            //Method parameters
            var overloads      = GetMethodOverloads(scriptCode, position);
            var suggestionList = new List <CustomSuggestion>();

            if (results != null)
            {
                try
                {
                    suggestionList.AddRange(results.Items.Select(completion => new CustomSuggestion()
                    {
                        Label         = completion.Properties.ContainsKey("SymbolName") ? completion.Properties["SymbolName"] : completion.DisplayText,
                        InsertText    = completion.Properties.ContainsKey("SymbolName") ? completion.Properties["SymbolName"] : completion.DisplayText,
                        Kind          = completion.Properties.ContainsKey("SymbolKind") ? completion.Properties["SymbolKind"] : "8",
                        Detail        = completion.Tags != null && completion.Tags.Length > 0 ? completion.Tags[0] : "None",
                        Documentation = completion.Tags != null && completion.Tags.Length > 1 ? completion.Tags[1] : "None"
                    }));
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error from: \r\n{JsonConvert.SerializeObject(results)}\r\n{ex.Message}\r\n{ex.StackTrace}");
                    throw;
                }
            }

            if (overloads.Count == 0)
            {
                return(suggestionList);
            }
            suggestionList = new List <CustomSuggestion>();
            var builder = ImmutableArray.CreateBuilder <CompletionItem>();

            foreach ((string description, string documentation) in overloads)
            {
                suggestionList.Add(new CustomSuggestion()
                {
                    Label         = description.Split('(', ')')[1],
                    InsertText    = description.Split('(', ')')[1],
                    Kind          = "8",
                    Detail        = documentation,
                    Documentation = documentation
                });
            }
            return(suggestionList);
        }
Ejemplo n.º 6
0
        public DocumentId AddProjectWithDocument(string documentFileName, string text)
        {
            var fileName = Path.GetFileName(documentFileName);
            var name     = Path.GetFileNameWithoutExtension(documentFileName);
            var language = Path.GetExtension(documentFileName) == ".vb" ? LanguageNames.VisualBasic : LanguageNames.CSharp;

            var projectId = ProjectId.CreateNewId();

            var references = defaultReferences.Distinct().Select(CreateReference).ToList();

            references.Add(CreateReference(Assembly.Load("System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")));
            references.Add(CreateReference(Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51")));
            if (language == LanguageNames.VisualBasic)
            {
                references.Add(CreateReference(typeof(VBMath).Assembly));
            }
            else if (language == LanguageNames.CSharp)
            {
                references.Add(CreateReference(typeof(RuntimeBinderException).Assembly));
            }

            var projectInfo = ProjectInfo.Create(projectId, VersionStamp.Default, name, name + ".dll", language, metadataReferences: references,
                                                 parseOptions: language == LanguageNames.CSharp
                    ? (ParseOptions) new CSharpParseOptions(Microsoft.CodeAnalysis.CSharp.LanguageVersion.CSharp9, preprocessorSymbols: preprocessorSymbols)
                    : new VisualBasicParseOptions(Microsoft.CodeAnalysis.VisualBasic.LanguageVersion.VisualBasic16));

            OnProjectAdded(projectInfo);

            if (language == LanguageNames.CSharp)
            {
                AddFile(projectId, "NullableAttributes.cs");
                AddFile(projectId, "IsExternalInit.cs");
                AddFile(projectId, "Range.cs");
            }

            var documentId   = DocumentId.CreateNewId(projectId);
            var documentInfo = DocumentInfo.Create(documentId, fileName, loader: TextLoader.From(TextAndVersion.Create(SourceText.From(text, Encoding.UTF8), VersionStamp.Create())));

            OnDocumentAdded(documentInfo);
            return(documentId);

            void AddFile(ProjectId id, string sourceFile)
            {
                using var stream = typeof(ScriptingWorkspace).Assembly.GetManifestResourceStream("Waf.DotNetPad.Applications.CompilerServices." + sourceFile);
                var newDocumentId   = DocumentId.CreateNewId(id);
                var newDocumentInfo = DocumentInfo.Create(newDocumentId, sourceFile, loader: TextLoader.From(TextAndVersion.Create(SourceText.From(stream, Encoding.UTF8), VersionStamp.Create())));

                OnDocumentAdded(newDocumentInfo);
            }
        }
Ejemplo n.º 7
0
        public async Task TestAnalyzerConfigDocument()
        {
            var code = @"class Test { void Method() { } }";

            using (var workspace = TestWorkspace.CreateCSharp(code))
            {
                var projectId = workspace.CurrentSolution.ProjectIds.First();
                var analyzerConfigDocumentId   = DocumentId.CreateNewId(projectId);
                var analyzerConfigDocumentInfo = DocumentInfo.Create(
                    analyzerConfigDocumentId, ".editorconfig",
                    loader: TextLoader.From(TextAndVersion.Create(SourceText.From("root = true"), VersionStamp.Create())));

                await VerifySolutionUpdate(workspace, s =>
                {
                    return(s.AddAnalyzerConfigDocuments(ImmutableArray.Create(analyzerConfigDocumentInfo)));
                });

                workspace.OnAnalyzerConfigDocumentAdded(analyzerConfigDocumentInfo);

                await VerifySolutionUpdate(workspace, s =>
                {
                    return(s.WithAnalyzerConfigDocumentText(analyzerConfigDocumentId, SourceText.From("root = false")));
                });

                await VerifySolutionUpdate(workspace, s =>
                {
                    return(s.RemoveAnalyzerConfigDocument(analyzerConfigDocumentId));
                });
            }
        }
Ejemplo n.º 8
0
        private void SetupCodeEditor()
        {
            // Already created?
            if (workspace != null)
            {
                // Anything changed?
                if (workspace == Workspace && projectId == ProjectId)
                {
                    return;
                }

                CleanupCodeEditor();
            }

            // Check we have everything we need
            if (Workspace == null || codeEditor == null || ProjectId == null)
            {
                return;
            }

            this.workspace = Workspace;

            // Start with initial text
            var textDocument = new TextDocument(Text);

            sourceTextContainer              = new AvalonEditTextContainer(textDocument);
            sourceTextContainer.TextChanged += SourceTextContainer_TextChanged;

            var documentId = workspace.AddDocument(ProjectId, $"script-{Guid.NewGuid()}.cs", SourceCodeKind.Script, TextLoader.From(sourceTextContainer, VersionStamp.Create()));

            DocumentId = documentId;
            workspace.OpenDocument(sourceTextContainer, documentId, a => Dispatcher.Invoke(() => codeEditor.ProcessDiagnostics(a)));

            // Bind SourceTextContainer to UI
            codeEditor.BindSourceTextContainer(workspace, sourceTextContainer, documentId);
        }
Ejemplo n.º 9
0
                protected override Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken)
                {
                    var solution = _oldDocument.Project.Solution;

                    // Add a document - This will result in IWpfTextView previews.
                    solution = solution.AddDocument(DocumentId.CreateNewId(_oldDocument.Project.Id, AddedDocumentName), AddedDocumentName, AddedDocumentText);

                    // Remove a reference - This will result in a string preview.
                    var removedReference = _oldDocument.Project.MetadataReferences[_oldDocument.Project.MetadataReferences.Count - 1];

                    s_removedMetadataReferenceDisplayName = removedReference.Display;
                    solution = solution.RemoveMetadataReference(_oldDocument.Project.Id, removedReference);

                    // Add a project - This will result in a string preview.
                    solution = solution.AddProject(ProjectInfo.Create(s_addedProjectId, VersionStamp.Create(), AddedProjectName, AddedProjectName, LanguageNames.CSharp));

                    // Change a document - This will result in IWpfTextView previews.
                    solution = solution.WithDocumentSyntaxRoot(_oldDocument.Id, CSharpSyntaxTree.ParseText(ChangedDocumentText, cancellationToken: cancellationToken).GetRoot(cancellationToken));

                    return(Task.FromResult(solution));
                }
Ejemplo n.º 10
0
        private ProjectId AddProject(ProjectContext project)
        {
            // Create the framework specific project and add it to the workspace
            var projectInfo = ProjectInfo.Create(
                ProjectId.CreateNewId(),
                VersionStamp.Create(),
                project.ProjectFile.Name + "+" + project.TargetFramework,
                project.ProjectFile.Name,
                LanguageNames.CSharp,
                project.ProjectFile.ProjectFilePath);

            OnProjectAdded(projectInfo);

            // TODO: ctor argument?
            var configuration = "Debug";

            var compilationOptions = project.GetLanguageSpecificCompilerOptions(project.TargetFramework, configuration);

            var compilationSettings = ToCompilationSettings(compilationOptions, project.TargetFramework, project.ProjectFile.ProjectDirectory);

            OnParseOptionsChanged(projectInfo.Id, new CSharpParseOptions(compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines));

            OnCompilationOptionsChanged(projectInfo.Id, compilationSettings.CompilationOptions);

            foreach (var file in project.ProjectFile.Files.SourceFiles)
            {
                using (var stream = File.OpenRead(file))
                {
                    AddSourceFile(projectInfo, file, stream);
                }
            }

            var exporter = project.CreateExporter(configuration);

            foreach (var dependency in exporter.GetDependencies())
            {
                var projectDependency = dependency.Library as ProjectDescription;
                if (projectDependency != null)
                {
                    var projectDependencyContext = ProjectContext.Create(projectDependency.Project.ProjectFilePath, projectDependency.Framework);

                    var id = AddProject(projectDependencyContext);

                    OnProjectReferenceAdded(projectInfo.Id, new ProjectReference(id));
                }
                else
                {
                    foreach (var asset in dependency.CompilationAssemblies)
                    {
                        OnMetadataReferenceAdded(projectInfo.Id, GetMetadataReference(asset.ResolvedPath));
                    }
                }

                foreach (var file in dependency.SourceReferences)
                {
                    using (var stream = file.GetTransformedStream())
                    {
                        AddSourceFile(projectInfo, file.ResolvedPath, stream);
                    }
                }
            }

            return(projectInfo.Id);
        }
Ejemplo n.º 11
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);
        }
Ejemplo n.º 12
0
        private async Task <ProjectId> LoadProjectAsync(string projectFilePath, IProjectFileLoader loader, bool preferMetadata, List <ProjectInfo> loadedProjects, CancellationToken cancellationToken)
        {
            System.Diagnostics.Debug.Assert(projectFilePath != null);
            System.Diagnostics.Debug.Assert(loader != null);

            var projectId = this.GetOrCreateProjectId(projectFilePath);

            var name = Path.GetFileNameWithoutExtension(projectFilePath);

            var projectFile = await loader.LoadProjectFileAsync(projectFilePath, _properties, cancellationToken).ConfigureAwait(false);

            var projectFileInfo = await projectFile.GetProjectFileInfoAsync(cancellationToken).ConfigureAwait(false);

            VersionStamp version;

            if (!string.IsNullOrEmpty(projectFilePath) && File.Exists(projectFilePath))
            {
                version = VersionStamp.Create(File.GetLastWriteTimeUtc(projectFilePath));
            }
            else
            {
                version = VersionStamp.Create();
            }

            // Documents
            var docFileInfos = projectFileInfo.Documents.ToImmutableArrayOrEmpty();

            CheckDocuments(docFileInfos, projectFilePath, projectId);

            Encoding defaultEncoding = GetDefaultEncoding(projectFileInfo.CodePage);

            var docs = new List <DocumentInfo>();

            foreach (var docFileInfo in docFileInfos)
            {
                docs.Add(DocumentInfo.Create(
                             DocumentId.CreateNewId(projectId, debugName: docFileInfo.FilePath),
                             Path.GetFileName(docFileInfo.LogicalPath),
                             GetDocumentFolders(docFileInfo.LogicalPath),
                             projectFile.GetSourceCodeKind(docFileInfo.FilePath),
                             new FileTextLoader(docFileInfo.FilePath, defaultEncoding),
                             docFileInfo.FilePath,
                             docFileInfo.IsGenerated));
            }

            var additonalDocs = new List <DocumentInfo>();

            foreach (var docFileInfo in projectFileInfo.AdditionalDocuments)
            {
                additonalDocs.Add(DocumentInfo.Create(
                                      DocumentId.CreateNewId(projectId, debugName: docFileInfo.FilePath),
                                      Path.GetFileName(docFileInfo.LogicalPath),
                                      GetDocumentFolders(docFileInfo.LogicalPath),
                                      SourceCodeKind.Regular,
                                      new FileTextLoader(docFileInfo.FilePath, defaultEncoding),
                                      docFileInfo.FilePath,
                                      docFileInfo.IsGenerated));
            }

            // project references
            var resolvedReferences = await this.ResolveProjectReferencesAsync(
                projectFilePath, projectFileInfo.ProjectReferences, preferMetadata, loadedProjects, cancellationToken).ConfigureAwait(false);

            var metadataReferences = projectFileInfo.MetadataReferences
                                     .Concat(resolvedReferences.MetadataReferences);

            var outputFilePath = projectFileInfo.OutputFilePath;
            var assemblyName   = projectFileInfo.AssemblyName;

            // if the project file loader couldn't figure out an assembly name, make one using the project's file path.
            if (string.IsNullOrWhiteSpace(assemblyName))
            {
                assemblyName = Path.GetFileNameWithoutExtension(projectFilePath);

                // if this is still unreasonable, use a fixed name.
                if (string.IsNullOrWhiteSpace(assemblyName))
                {
                    assemblyName = "assembly";
                }
            }

            loadedProjects.Add(
                ProjectInfo.Create(
                    projectId,
                    version,
                    name,
                    assemblyName,
                    loader.Language,
                    projectFilePath,
                    outputFilePath,
                    projectFileInfo.CompilationOptions,
                    projectFileInfo.ParseOptions,
                    docs,
                    resolvedReferences.ProjectReferences,
                    metadataReferences,
                    analyzerReferences: projectFileInfo.AnalyzerReferences,
                    additionalDocuments: additonalDocs,
                    isSubmission: false,
                    hostObjectType: null));

            return(projectId);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Open a solution file and all referenced projects.
        /// </summary>
        public async Task <Solution> OpenSolutionAsync(string solutionFilePath, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (solutionFilePath == null)
            {
                throw new ArgumentNullException(nameof(solutionFilePath));
            }

            this.ClearSolution();

            var absoluteSolutionPath = this.GetAbsoluteSolutionPath(solutionFilePath, Environment.CurrentDirectory);

            using (_dataGuard.DisposableWait(cancellationToken))
            {
                this.SetSolutionProperties(absoluteSolutionPath);
            }

            VersionStamp version = default(VersionStamp);

#if !MSBUILD12
            Microsoft.Build.Construction.SolutionFile solutionFile = Microsoft.Build.Construction.SolutionFile.Parse(absoluteSolutionPath);
            var reportMode      = this.SkipUnrecognizedProjects ? ReportMode.Log : ReportMode.Throw;
            var invalidProjects = new List <ProjectInSolution>();

            // seed loaders from known project types
            using (_dataGuard.DisposableWait(cancellationToken))
            {
                foreach (var project in solutionFile.ProjectsInOrder)
                {
                    if (project.ProjectType == SolutionProjectType.SolutionFolder)
                    {
                        continue;
                    }

                    var projectAbsolutePath = TryGetAbsolutePath(project.AbsolutePath, reportMode);
                    if (projectAbsolutePath != null)
                    {
                        var extension = Path.GetExtension(projectAbsolutePath);
                        if (extension.Length > 0 && extension[0] == '.')
                        {
                            extension = extension.Substring(1);
                        }

                        var loader = ProjectFileLoader.GetLoaderForProjectFileExtension(this, extension);
                        if (loader != null)
                        {
                            _projectPathToLoaderMap[projectAbsolutePath] = loader;
                        }
                    }
                    else
                    {
                        invalidProjects.Add(project);
                    }
                }
            }

            // a list to accumulate all the loaded projects
            var loadedProjects = new List <ProjectInfo>();

            // load all the projects
            foreach (var project in solutionFile.ProjectsInOrder)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (project.ProjectType != SolutionProjectType.SolutionFolder && !invalidProjects.Contains(project))
                {
                    var projectAbsolutePath = TryGetAbsolutePath(project.AbsolutePath, reportMode);
                    if (projectAbsolutePath != null)
                    {
                        IProjectFileLoader loader;
                        if (TryGetLoaderFromProjectPath(projectAbsolutePath, reportMode, out loader))
                        {
                            // projects get added to 'loadedProjects' as side-effect
                            // never perfer metadata when loading solution, all projects get loaded if they can.
                            var tmp = await GetOrLoadProjectAsync(projectAbsolutePath, loader, preferMetadata : false, loadedProjects : loadedProjects, cancellationToken : cancellationToken).ConfigureAwait(false);
                        }
                    }
                }
            }
#else
            SolutionFile solutionFile = null;

            using (var reader = new StreamReader(absoluteSolutionPath))
            {
                version = VersionStamp.Create(File.GetLastWriteTimeUtc(absoluteSolutionPath));
                var text = await reader.ReadToEndAsync().ConfigureAwait(false);

                solutionFile = SolutionFile.Parse(new StringReader(text));
            }

            var solutionFolder = Path.GetDirectoryName(absoluteSolutionPath);

            // seed loaders from known project types
            using (_dataGuard.DisposableWait())
            {
                foreach (var projectBlock in solutionFile.ProjectBlocks)
                {
                    string absoluteProjectPath;
                    if (TryGetAbsoluteProjectPath(projectBlock.ProjectPath, solutionFolder, ReportMode.Ignore, out absoluteProjectPath))
                    {
                        var loader = ProjectFileLoader.GetLoaderForProjectTypeGuid(this, projectBlock.ProjectTypeGuid);
                        if (loader != null)
                        {
                            _projectPathToLoaderMap[absoluteProjectPath] = loader;
                        }
                    }
                }
            }

            // a list to accumulate all the loaded projects
            var loadedProjects = new List <ProjectInfo>();

            var reportMode = this.SkipUnrecognizedProjects ? ReportMode.Log : ReportMode.Throw;

            // load all the projects
            foreach (var projectBlock in solutionFile.ProjectBlocks)
            {
                cancellationToken.ThrowIfCancellationRequested();

                string absoluteProjectPath;
                if (TryGetAbsoluteProjectPath(projectBlock.ProjectPath, solutionFolder, reportMode, out absoluteProjectPath))
                {
                    IProjectFileLoader loader;
                    if (TryGetLoaderFromProjectPath(absoluteProjectPath, reportMode, out loader))
                    {
                        // projects get added to 'loadedProjects' as side-effect
                        // never perfer metadata when loading solution, all projects get loaded if they can.
                        var tmp = await GetOrLoadProjectAsync(absoluteProjectPath, loader, preferMetadata : false, loadedProjects : loadedProjects, cancellationToken : cancellationToken).ConfigureAwait(false);
                    }
                }
            }
#endif

            // construct workspace from loaded project infos
            this.OnSolutionAdded(SolutionInfo.Create(SolutionId.CreateNewId(debugName: absoluteSolutionPath), version, absoluteSolutionPath, loadedProjects));

            this.UpdateReferencesAfterAdd();

            return(this.CurrentSolution);
        }
        public VsSolutionUpdatesProjectSnapshotChangeTriggerTest()
        {
            SomeProject      = new HostProject(TestProjectData.SomeProject.FilePath, FallbackRazorConfiguration.MVC_1_0, TestProjectData.SomeProject.RootNamespace);
            SomeOtherProject = new HostProject(TestProjectData.AnotherProject.FilePath, FallbackRazorConfiguration.MVC_2_0, TestProjectData.AnotherProject.RootNamespace);

            Workspace = TestWorkspace.Create(w => SomeWorkspaceProject = w.AddProject(ProjectInfo.Create(
                                                                                          ProjectId.CreateNewId(),
                                                                                          VersionStamp.Create(),
                                                                                          "SomeProject",
                                                                                          "SomeProject",
                                                                                          LanguageNames.CSharp,
                                                                                          filePath: SomeProject.FilePath)));
        }
        public async Task SerializationTest_Document()
        {
            using var workspace = new TestWorkspace(EditorServicesUtil.ExportProvider, workspaceKind: "DiagnosticDataSerializerTest");
            var document = workspace.CurrentSolution.AddProject("TestProject", "TestProject", LanguageNames.CSharp).AddDocument("TestDocument", "");

            var diagnostics = new[]
            {
                new DiagnosticData(
                    id: "test1",
                    category: "Test",
                    message: "test1 message",
                    enuMessageForBingSearch: "test1 message format",
                    severity: DiagnosticSeverity.Info,
                    defaultSeverity: DiagnosticSeverity.Info,
                    isEnabledByDefault: false,
                    warningLevel: 1,
                    customTags: ImmutableArray <string> .Empty,
                    properties: ImmutableDictionary <string, string> .Empty,
                    document.Project.Id,
                    new DiagnosticDataLocation(document.Id, new TextSpan(10, 20), "originalFile1", 30, 30, 40, 40, "mappedFile1", 10, 10, 20, 20),
                    language: LanguageNames.CSharp),

                new DiagnosticData(
                    id: "test2",
                    category: "Test",
                    message: "test2 message",
                    enuMessageForBingSearch: "test2 message format",
                    severity: DiagnosticSeverity.Warning,
                    defaultSeverity: DiagnosticSeverity.Warning,
                    isEnabledByDefault: true,
                    warningLevel: 0,
                    customTags: ImmutableArray.Create("Test2"),
                    properties: ImmutableDictionary <string, string> .Empty.Add("propertyKey", "propertyValue"),
                    document.Project.Id,
                    new DiagnosticDataLocation(document.Id, new TextSpan(30, 40), "originalFile2", 70, 70, 80, 80, "mappedFile2", 50, 50, 60, 60),
                    language: "VB",
                    title: "test2 title",
                    description: "test2 description",
                    helpLink: "http://test2link"),

                new DiagnosticData(
                    id: "test3",
                    category: "Test",
                    message: "test3 message",
                    enuMessageForBingSearch: "test3 message format",
                    severity: DiagnosticSeverity.Error,
                    defaultSeverity: DiagnosticSeverity.Warning,
                    isEnabledByDefault: true,
                    warningLevel: 2,
                    customTags: ImmutableArray.Create("Test3", "Test3_2"),
                    properties: ImmutableDictionary <string, string> .Empty.Add("p1Key", "p1Value").Add("p2Key", "p2Value"),
                    document.Project.Id,
                    new DiagnosticDataLocation(document.Id, new TextSpan(50, 60), "originalFile3", 110, 110, 120, 120, "mappedFile3", 90, 90, 100, 100),
                    title: "test3 title",
                    description: "test3 description",
                    helpLink: "http://test3link"),
            }.ToImmutableArray();

            var utcTime         = DateTime.UtcNow;
            var analyzerVersion = VersionStamp.Create(utcTime);
            var version         = VersionStamp.Create(utcTime.AddDays(1));

            var key = "document";

            var persistentService = workspace.Services.GetRequiredService <IPersistentStorageService>();
            var serializer        = new CodeAnalysis.Workspaces.Diagnostics.DiagnosticDataSerializer(analyzerVersion, version);

            Assert.True(await serializer.SerializeAsync(persistentService, document.Project, document, key, diagnostics, CancellationToken.None).ConfigureAwait(false));

            var recovered = await serializer.DeserializeAsync(persistentService, document.Project, document, key, CancellationToken.None);

            AssertDiagnostics(diagnostics, recovered);
        }
        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);
                }
                if (projectFileInfo.GenerateXmlDocumentation)
                {
                    parseOptions = parseOptions.WithDocumentationMode(DocumentationMode.Diagnose);
                }
                _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 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);
            }
        }
        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().Result);


            if (expectedDiagnosics.Count != diagnostics.Count)
            {
                Console.WriteLine("Diagnostics: " + diagnostics.Count);
                foreach (var diag in diagnostics)
                {
                    Console.WriteLine(diag.Id + "/" + diag.GetMessage());
                }
                Assert.Fail("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.Fail("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().Result.ToString();

            txt    = CodeFixTestBase.HomogenizeEol(txt);
            output = CodeFixTestBase.HomogenizeEol(output);
            if (output != txt)
            {
                Console.WriteLine("expected:");
                Console.WriteLine(output);
                Console.WriteLine("got:");
                Console.WriteLine(txt);
                Assert.Fail();
            }
        }
        public void Initalize(IConfiguration configuration)
        {
            _options = new MSBuildOptions();
            ConfigurationBinder.Bind(configuration, _options);

            if (_options.WaitForDebugger)
            {
                Console.WriteLine($"Attach to process {System.Diagnostics.Process.GetCurrentProcess().Id}");
                while (!System.Diagnostics.Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
            }

            var solutionFilePath = _env.SolutionFilePath;

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

                if (result.Message != null)
                {
                    _logger.LogInformation(result.Message);
                }

                if (result.Solution == null)
                {
                    return;
                }

                solutionFilePath = result.Solution;
            }

            SolutionFile solutionFile = null;

            _context.SolutionPath = solutionFilePath;

            using (var stream = File.OpenRead(solutionFilePath))
            {
                using (var reader = new StreamReader(stream))
                {
                    solutionFile = SolutionFile.Parse(reader);
                }
            }
            _logger.LogInformation($"Detecting projects in '{solutionFilePath}'.");

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

                if (_context.ProjectGuidToWorkspaceMapping.ContainsKey(block.ProjectGuid))
                {
                    continue;
                }

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

                _logger.LogInformation($"Loading project from '{projectFilePath}'.");

                var projectFileInfo = CreateProject(projectFilePath);

                if (projectFileInfo == null)
                {
                    continue;
                }

                var compilationOptions = new CSharpCompilationOptions(projectFileInfo.OutputKind);
                compilationOptions = compilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

                if (projectFileInfo.AllowUnsafe)
                {
                    compilationOptions = compilationOptions.WithAllowUnsafe(true);
                }

                if (projectFileInfo.SignAssembly && !string.IsNullOrEmpty(projectFileInfo.AssemblyOriginatorKeyFile))
                {
                    var keyFile = Path.Combine(projectFileInfo.ProjectDirectory, projectFileInfo.AssemblyOriginatorKeyFile);
                    compilationOptions = compilationOptions.WithStrongNameProvider(new DesktopStrongNameProvider())
                                         .WithCryptoKeyFile(keyFile);
                }

                if (projectFileInfo.GenerateXmlDocumentation)
                {
                    compilationOptions = compilationOptions.WithXmlReferenceResolver(XmlFileResolver.Default);
                }

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

                _workspace.AddProject(projectInfo);

                projectFileInfo.WorkspaceId = projectInfo.Id;

                _context.Projects[projectFileInfo.ProjectFilePath]        = projectFileInfo;
                _context.ProjectGuidToWorkspaceMapping[block.ProjectGuid] = projectInfo.Id;

                _watcher.Watch(projectFilePath, OnProjectChanged);
            }

            foreach (var projectFileInfo in _context.Projects.Values)
            {
                UpdateProject(projectFileInfo);
            }
        }
        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();

            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);
        }
Ejemplo n.º 20
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);
        }
Ejemplo n.º 21
0
        public async Task TestDocument()
        {
            var code = @"class Test { void Method() { } }";

            using (var workspace = TestWorkspace.CreateCSharp(code))
            {
                var projectId    = workspace.CurrentSolution.ProjectIds.First();
                var documentId   = DocumentId.CreateNewId(projectId);
                var documentInfo = DocumentInfo.Create(
                    documentId, "sourceFile",
                    loader: TextLoader.From(TextAndVersion.Create(SourceText.From("class A { }"), VersionStamp.Create())));

                await VerifySolutionUpdate(workspace, s =>
                {
                    return(s.AddDocument(documentInfo));
                });

                workspace.OnDocumentAdded(documentInfo);

                await VerifySolutionUpdate(workspace, s =>
                {
                    return(s.WithDocumentText(documentId, SourceText.From("class Changed { }")));
                });

                await VerifySolutionUpdate(workspace, s =>
                {
                    return(s.RemoveDocument(documentId));
                });
            }
        }
Ejemplo n.º 22
0
            public Project AddProject(string name, string language)
            {
                var info = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), name, name, language);

                return(this.AddProject(info));
            }
Ejemplo n.º 23
0
        private static OmniSharpWorkspace CreateSimpleWorkspace(string fileName, string contents)
        {
            var workspace = new OmniSharpWorkspace(
                new HostServicesAggregator(
                    Enumerable.Empty <IHostServicesProvider>(), new LoggerFactory()),
                new LoggerFactory(), null);

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

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

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

            return(workspace);
        }
Ejemplo n.º 24
0
        private Solution CreateOrOpenSolution()
        {
            string solutionFile = Path.Combine(_persistentFolder, "Solution1.sln");
            bool   newSolution;

            if (newSolution = !File.Exists(solutionFile))
            {
                File.WriteAllText(solutionFile, "");
            }

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

            var workspace = new AdhocWorkspace();

            workspace.AddSolution(info);

            var solution = workspace.CurrentSolution;

            if (newSolution)
            {
                string projectFile = Path.Combine(Path.GetDirectoryName(solutionFile), "Project1.csproj");
                File.WriteAllText(projectFile, "");
                solution = solution.AddProject(ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Project1", "Project1", LanguageNames.CSharp, projectFile));
                var project = solution.Projects.Single();

                string documentFile = Path.Combine(Path.GetDirectoryName(projectFile), "Document1.cs");
                File.WriteAllText(documentFile, "");
                solution = solution.AddDocument(DocumentInfo.Create(DocumentId.CreateNewId(project.Id), "Document1", filePath: documentFile));
            }

            return(solution);
        }
Ejemplo n.º 25
0
        public ContainedDocument(
            AbstractContainedLanguage containedLanguage,
            SourceCodeKind sourceCodeKind,
            Workspace workspace,
            IVsHierarchy hierarchy,
            uint itemId,
            IComponentModel componentModel,
            IFormattingRule vbHelperFormattingRule)
        {
            Contract.ThrowIfNull(containedLanguage);

            _containedLanguage = containedLanguage;
            _sourceCodeKind    = sourceCodeKind;
            _componentModel    = componentModel;
            _workspace         = workspace;
            _optionService     = _workspace.Services.GetService <IOptionService>();
            _hostType          = GetHostType();

            var rdt = (IVsRunningDocumentTable)componentModel.GetService <SVsServiceProvider>().GetService(typeof(SVsRunningDocumentTable));

            IVsHierarchy sharedHierarchy;
            uint         itemIdInSharedHierarchy;
            var          isSharedHierarchy = LinkedFileUtilities.TryGetSharedHierarchyAndItemId(hierarchy, itemId, out sharedHierarchy, out itemIdInSharedHierarchy);

            var filePath = isSharedHierarchy
                ? rdt.GetMonikerForHierarchyAndItemId(sharedHierarchy, itemIdInSharedHierarchy)
                : rdt.GetMonikerForHierarchyAndItemId(hierarchy, itemId);

            // we couldn't look up the document moniker in RDT for a hierarchy/item pair
            // Since we only use this moniker as a key, we could fall back to something else, like the document name.
            if (filePath == null)
            {
                Debug.Assert(false, "Could not get the document moniker for an item in its hierarchy.");
                filePath = hierarchy.GetDocumentNameForHierarchyAndItemId(itemId);
            }

            if (Project.Hierarchy != null)
            {
                string moniker;
                Project.Hierarchy.GetCanonicalName(itemId, out moniker);
                _itemMoniker = moniker;
            }

            this.Key     = new DocumentKey(Project, filePath);
            this.Id      = DocumentId.CreateNewId(Project.Id, filePath);
            this.Folders = containedLanguage.Project.GetFolderNames(itemId);
            this.Loader  = TextLoader.From(containedLanguage.SubjectBuffer.AsTextContainer(), VersionStamp.Create(), filePath);
            _differenceSelectorService = componentModel.GetService <ITextDifferencingSelectorService>();
            _snapshotTracker           = new ReiteratedVersionSnapshotTracker(_containedLanguage.SubjectBuffer);
            _vbHelperFormattingRule    = vbHelperFormattingRule;
        }
Ejemplo n.º 26
0
            private Task <ProjectInfo> CreateProjectInfoAsync(
                ProjectFileInfo projectFileInfo,
                ProjectId projectId,
                bool addDiscriminator,
                CancellationToken cancellationToken
                )
            {
                var language    = projectFileInfo.Language;
                var projectPath = projectFileInfo.FilePath;
                var projectName = Path.GetFileNameWithoutExtension(projectPath) ?? string.Empty;

                if (
                    addDiscriminator &&
                    !RoslynString.IsNullOrWhiteSpace(projectFileInfo.TargetFramework)
                    )
                {
                    projectName += "(" + projectFileInfo.TargetFramework + ")";
                }

                var version = projectPath is null
                    ? VersionStamp.Default
                    : VersionStamp.Create(FileUtilities.GetFileTimeStamp(projectPath));

                if (projectFileInfo.IsEmpty)
                {
                    var assemblyName = GetAssemblyNameFromProjectPath(projectPath);

                    var parseOptions = GetLanguageService <ISyntaxTreeFactoryService>(language)
                                       ?.GetDefaultParseOptions();
                    var compilationOptions = GetLanguageService <ICompilationFactoryService>(
                        language
                        )
                                             ?.GetDefaultCompilationOptions();

                    return(Task.FromResult(
                               ProjectInfo.Create(
                                   projectId,
                                   version,
                                   projectName,
                                   assemblyName: assemblyName,
                                   language: language,
                                   filePath: projectPath,
                                   outputFilePath: string.Empty,
                                   outputRefFilePath: string.Empty,
                                   compilationOptions: compilationOptions,
                                   parseOptions: parseOptions,
                                   documents: SpecializedCollections.EmptyEnumerable <DocumentInfo>(),
                                   projectReferences: SpecializedCollections.EmptyEnumerable <ProjectReference>(),
                                   metadataReferences: SpecializedCollections.EmptyEnumerable <MetadataReference>(),
                                   analyzerReferences: SpecializedCollections.EmptyEnumerable <AnalyzerReference>(),
                                   additionalDocuments: SpecializedCollections.EmptyEnumerable <DocumentInfo>(),
                                   isSubmission: false,
                                   hostObjectType: null
                                   )
                               ));
                }

                return(DoOperationAndReportProgressAsync(
                           ProjectLoadOperation.Resolve,
                           projectPath,
                           projectFileInfo.TargetFramework,
                           async() =>
                {
                    var projectDirectory = Path.GetDirectoryName(projectPath);

                    // parse command line arguments
                    var commandLineParser = GetLanguageService <ICommandLineParserService>(
                        projectFileInfo.Language
                        );

                    if (commandLineParser is null)
                    {
                        var message = string.Format(
                            WorkspaceMSBuildResources.Unable_to_find_a_0_for_1,
                            nameof(ICommandLineParserService),
                            projectFileInfo.Language
                            );
                        throw new Exception(message);
                    }

                    var commandLineArgs = commandLineParser.Parse(
                        arguments: projectFileInfo.CommandLineArgs,
                        baseDirectory: projectDirectory,
                        isInteractive: false,
                        sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory()
                        );

                    var assemblyName = commandLineArgs.CompilationName;
                    if (RoslynString.IsNullOrWhiteSpace(assemblyName))
                    {
                        // if there isn't an assembly name, make one from the file path.
                        // Note: This may not be necessary any longer if the command line args
                        // always produce a valid compilation name.
                        assemblyName = GetAssemblyNameFromProjectPath(projectPath);
                    }

                    // Ensure sure that doc-comments are parsed
                    var parseOptions = commandLineArgs.ParseOptions;
                    if (parseOptions.DocumentationMode == DocumentationMode.None)
                    {
                        parseOptions = parseOptions.WithDocumentationMode(
                            DocumentationMode.Parse
                            );
                    }

                    // add all the extra options that are really behavior overrides
                    var metadataService = GetWorkspaceService <IMetadataService>();
                    var compilationOptions = commandLineArgs.CompilationOptions
                                             .WithXmlReferenceResolver(new XmlFileResolver(projectDirectory))
                                             .WithSourceReferenceResolver(
                        new SourceFileResolver(
                            ImmutableArray <string> .Empty,
                            projectDirectory
                            )
                        )
                                             // TODO: https://github.com/dotnet/roslyn/issues/4967
                                             .WithMetadataReferenceResolver(
                        new WorkspaceMetadataFileReferenceResolver(
                            metadataService,
                            new RelativePathResolver(
                                ImmutableArray <string> .Empty,
                                projectDirectory
                                )
                            )
                        )
                                             .WithStrongNameProvider(
                        new DesktopStrongNameProvider(commandLineArgs.KeyFileSearchPaths)
                        )
                                             .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

                    var documents = CreateDocumentInfos(
                        projectFileInfo.Documents,
                        projectId,
                        commandLineArgs.Encoding
                        );
                    var additionalDocuments = CreateDocumentInfos(
                        projectFileInfo.AdditionalDocuments,
                        projectId,
                        commandLineArgs.Encoding
                        );
                    var analyzerConfigDocuments = CreateDocumentInfos(
                        projectFileInfo.AnalyzerConfigDocuments,
                        projectId,
                        commandLineArgs.Encoding
                        );
                    CheckForDuplicateDocuments(
                        documents.Concat(additionalDocuments).Concat(analyzerConfigDocuments),
                        projectPath,
                        projectId
                        );

                    var analyzerReferences = ResolveAnalyzerReferences(commandLineArgs);

                    var resolvedReferences = await ResolveReferencesAsync(
                        projectId,
                        projectFileInfo,
                        commandLineArgs,
                        cancellationToken
                        )
                                             .ConfigureAwait(false);

                    return ProjectInfo
                    .Create(
                        projectId,
                        version,
                        projectName,
                        assemblyName,
                        language,
                        projectPath,
                        outputFilePath: projectFileInfo.OutputFilePath,
                        outputRefFilePath: projectFileInfo.OutputRefFilePath,
                        compilationOptions: compilationOptions,
                        parseOptions: parseOptions,
                        documents: documents,
                        projectReferences: resolvedReferences.ProjectReferences,
                        metadataReferences: resolvedReferences.MetadataReferences,
                        analyzerReferences: analyzerReferences,
                        additionalDocuments: additionalDocuments,
                        isSubmission: false,
                        hostObjectType: null
                        )
                    .WithDefaultNamespace(projectFileInfo.DefaultNamespace)
                    .WithAnalyzerConfigDocuments(analyzerConfigDocuments)
                    .WithCompilationOutputInfo(
                        new CompilationOutputInfo(projectFileInfo.OutputFilePath)
                        );
                }
        public static ProjectInfo CreateProjectInfo(ProjectFileInfo projectFileInfo)
        {
            var projectDirectory = Path.GetDirectoryName(projectFileInfo.FilePath);

            var projectId   = ProjectId.CreateNewId(debugName: projectFileInfo.FilePath);
            var version     = VersionStamp.Create(FileUtilities.GetFileTimeStamp(projectFileInfo.FilePath));
            var projectName = Path.GetFileNameWithoutExtension(projectFileInfo.FilePath);

            // parse command line arguments
            var commandLineParser = CSharpCommandLineParser.Default;

            var commandLineArgs = commandLineParser.Parse(
                args: projectFileInfo.CommandLineArgs,
                baseDirectory: projectDirectory,
                sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory());

            var assemblyName = commandLineArgs.CompilationName;

            if (string.IsNullOrWhiteSpace(assemblyName))
            {
                // if there isn't an assembly name, make one from the file path.
                // Note: This may not be necessary any longer if the commmand line args
                // always produce a valid compilation name.
                assemblyName = GetAssemblyNameFromProjectPath(projectFileInfo.FilePath);
            }

            // Ensure sure that doc-comments are parsed
            var parseOptions = commandLineArgs.ParseOptions;

            if (parseOptions.DocumentationMode == DocumentationMode.None)
            {
                parseOptions = parseOptions.WithDocumentationMode(DocumentationMode.Parse);
            }

            // add all the extra options that are really behavior overrides
            var metadataService    = _metadataService;
            var compilationOptions = commandLineArgs.CompilationOptions
                                     .WithXmlReferenceResolver(new XmlFileResolver(projectDirectory))
                                     .WithSourceReferenceResolver(new SourceFileResolver(ImmutableArray <string> .Empty, projectDirectory))
                                     // TODO: https://github.com/dotnet/roslyn/issues/4967
                                     .WithMetadataReferenceResolver(new WorkspaceMetadataFileReferenceResolver(metadataService, new RelativePathResolver(ImmutableArray <string> .Empty, projectDirectory)))
                                     .WithStrongNameProvider(new DesktopStrongNameProvider(commandLineArgs.KeyFileSearchPaths))
                                     .WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default);

            var documents           = CreateDocumentInfos(projectFileInfo.Documents, projectId, commandLineArgs.Encoding);
            var additionalDocuments = CreateDocumentInfos(projectFileInfo.AdditionalDocuments, projectId, commandLineArgs.Encoding);
            // CheckForDuplicateDocuments(documents, additionalDocuments, projectPath, projectId);

            var resolvedReferences = ResolveReferencesAsync(projectId, projectFileInfo, commandLineArgs);

            return(ProjectInfo.Create(
                       projectId,
                       version,
                       projectName,
                       assemblyName,
                       LanguageNames.CSharp,
                       projectFileInfo.FilePath,
                       outputFilePath: projectFileInfo.OutputFilePath,
                       compilationOptions: compilationOptions,
                       parseOptions: parseOptions,
                       documents: documents,
                       projectReferences: resolvedReferences.ProjectReferences.Distinct(),
                       metadataReferences: resolvedReferences.MetadataReferences.Distinct(),
                       analyzerReferences: Enumerable.Empty <AnalyzerReference>(),
                       additionalDocuments: additionalDocuments,
                       isSubmission: false,
                       hostObjectType: null));
        }
Ejemplo n.º 28
0
        private static ProjectInfo ParseInfo(FileInfo csproj, ProjectId projectId, out XDocument content)
        {
            var name = Path.GetFileNameWithoutExtension(csproj.FullName);
            var xml  = File.ReadAllText(csproj.FullName);
            var xdoc = content = XDocument.Parse(xml);

            return(ProjectInfo.Create(
                       projectId,
                       VersionStamp.Create(csproj.LastWriteTimeUtc),
                       name,
                       name,
                       LanguageNames.CSharp,
                       csproj.FullName,
                       documents: GetDocuments(),
                       metadataReferences: GetMetadataReferences()));

            bool IsSdk() => Regex.IsMatch(xml, @"<TargetFrameworks?\b");

            IEnumerable <DocumentInfo> GetDocuments()
            {
                if (IsSdk())
                {
                    foreach (var csFile in csproj.Directory.EnumerateFiles("*.cs", SearchOption.TopDirectoryOnly))
                    {
                        yield return(CreateDocumentInfo(csFile));
                    }

                    foreach (var dir in csproj.Directory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
                             .Where(dir => !string.Equals(dir.Name, "bin", StringComparison.OrdinalIgnoreCase))
                             .Where(dir => !string.Equals(dir.Name, "obj", StringComparison.OrdinalIgnoreCase)))
                    {
                        foreach (var nestedFile in dir.EnumerateFiles("*.cs", SearchOption.AllDirectories))
                        {
                            yield return(CreateDocumentInfo(nestedFile));
                        }
                    }
                }
                else
                {
                    var compiles = xdoc.Descendants(XName.Get("Compile", "http://schemas.microsoft.com/developer/msbuild/2003"))
                                   .ToArray();
                    if (compiles.Length == 0)
                    {
                        throw new InvalidOperationException("Parsing failed, no <Compile ... /> found.");
                    }

                    foreach (var compile in compiles)
                    {
                        var include = compile.Attribute("Include")?.Value;
                        if (include is null)
                        {
                            throw new InvalidOperationException("Parsing failed, no Include found.");
                        }

                        var csFile = Path.Combine(csproj.Directory.FullName, include);
                        yield return(CreateDocumentInfo(new FileInfo(csFile)));
                    }
                }
            }

            DocumentInfo CreateDocumentInfo(FileInfo file)
            {
                return(DocumentInfo.Create(
                           DocumentId.CreateNewId(projectId, file.Name),
                           file.Name,
                           sourceCodeKind: SourceCodeKind.Regular,
                           filePath: file.FullName,
                           isGenerated: file.Name.EndsWith(".g.cs"),
                           loader: TextLoader.From(
                               TextAndVersion.Create(
                                   text: Microsoft.CodeAnalysis.Text.SourceText.From(File.ReadAllText(file.FullName)),
                                   version: VersionStamp.Create(),
                                   filePath: file.FullName))));
            }

            IEnumerable <MetadataReference> GetMetadataReferences()
            {
                if (IsSdk())
                {
                }
                else
                {
                    var compiles = xdoc.Descendants(XName.Get("Reference", "http://schemas.microsoft.com/developer/msbuild/2003"))
                                   .ToArray();
                    if (compiles.Length == 0)
                    {
                        throw new InvalidOperationException("Parsing failed, no <Compile ... /> found.");
                    }

                    foreach (var compile in compiles)
                    {
                        var include = compile.Attribute("Include")?.Value;
                        if (include is null)
                        {
                            throw new InvalidOperationException("Parsing failed, no Include found.");
                        }

                        if (include.Contains("\\") &&
                            Path.Combine(csproj.Directory.FullName, include) is { } fileName&&
                            File.Exists(fileName))
                        {
                            yield return(MetadataReferences.CreateFromFile(fileName));
                        }
Ejemplo n.º 29
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)));
        }
Ejemplo n.º 30
0
        public TypeSystem()
        {
            //Create Workspace
            Workspace = new OmniSharpWorkspace(new HostServicesAggregator(/*null*/));

            //虚拟项目
            ModelProjectId             = ProjectId.CreateNewId();
            WorkflowModelProjectId     = ProjectId.CreateNewId();
            ServiceBaseProjectId       = ProjectId.CreateNewId();
            AsyncServiceProxyProjectId = ProjectId.CreateNewId();
            //ExpressionProjectId = ProjectId.CreateNewId();

            //各基本虚拟代码
            BaseDummyCodeDocumentId        = DocumentId.CreateNewId(ModelProjectId);
            ServiceBaseDummyCodeDocumentId = DocumentId.CreateNewId(ServiceBaseProjectId);
            BaseWFDummyCodeDocumentId      = DocumentId.CreateNewId(WorkflowModelProjectId);

            var dllCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

            var modelProjectInfo = ProjectInfo.Create(ModelProjectId, VersionStamp.Create(),
                                                      "ModelProject", "ModelProject", LanguageNames.CSharp, null, null,
                                                      dllCompilationOptions);
            var workflowProjectInfo = ProjectInfo.Create(WorkflowModelProjectId, VersionStamp.Create(),
                                                         "WorkflowProject", "WorkflowProject", LanguageNames.CSharp, null, null,
                                                         dllCompilationOptions);
            var serviceBaseProjectInfo = ProjectInfo.Create(ServiceBaseProjectId, VersionStamp.Create(),
                                                            "ServiceBaseProject", "ServiceBaseProject", LanguageNames.CSharp, null, null,
                                                            dllCompilationOptions);
            var asyncServiceProjectInfo = ProjectInfo.Create(AsyncServiceProxyProjectId, VersionStamp.Create(),
                                                             "AsyncServiceProxyProject", "AsyncServiceProxyProject", LanguageNames.CSharp, null, null,
                                                             dllCompilationOptions);
            //var expressionProjectInfo = ProjectInfo.Create(ExpressionProjectId, VersionStamp.Create(),
            //                                          "ExpressionProject", "ExpressionProject", LanguageNames.CSharp, null, null,
            //                                          dllCompilationOptions);

            var newSolution = Workspace.CurrentSolution
                              .AddProject(modelProjectInfo)
                              .AddMetadataReference(ModelProjectId, MetadataReferences.CoreLib)
                              .AddMetadataReference(ModelProjectId, MetadataReferences.NetstandardLib)
                              .AddDocument(BaseDummyCodeDocumentId, "BaseDummyCode.cs", CodeGenService.GenBaseDummyCode())

                              .AddProject(asyncServiceProjectInfo)
                              .AddMetadataReference(AsyncServiceProxyProjectId, MetadataReferences.CoreLib)
                              .AddMetadataReference(AsyncServiceProxyProjectId, MetadataReferences.NetstandardLib)
                              .AddProjectReference(AsyncServiceProxyProjectId, new ProjectReference(ModelProjectId))

                              .AddProject(serviceBaseProjectInfo)
                              .AddMetadataReference(ServiceBaseProjectId, MetadataReferences.CoreLib)
                              .AddMetadataReference(ServiceBaseProjectId, MetadataReferences.NetstandardLib)
                              .AddMetadataReference(ServiceBaseProjectId, MetadataReferences.SystemRuntimLib)
                              .AddMetadataReference(ServiceBaseProjectId, MetadataReferences.TasksLib)
                              .AddMetadataReference(ServiceBaseProjectId, MetadataReferences.TasksExtLib)
                              .AddMetadataReference(ServiceBaseProjectId, MetadataReferences.DataCommonLib)
                              .AddProjectReference(ServiceBaseProjectId, new ProjectReference(ModelProjectId))
                              .AddDocument(ServiceBaseDummyCodeDocumentId, "ServiceBaseDummyCode.cs", CodeGenService.GenServiceBaseDummyCode())

                              .AddProject(workflowProjectInfo)
                              .AddMetadataReference(WorkflowModelProjectId, MetadataReferences.CoreLib)
                              .AddMetadataReference(WorkflowModelProjectId, MetadataReferences.NetstandardLib)
                              .AddProjectReference(WorkflowModelProjectId, new ProjectReference(ModelProjectId))
                              .AddDocument(BaseWFDummyCodeDocumentId, "BaseWFDummyCode.cs", CodeGenService.GenBaseWFDummyCode())
            ;

            //.AddProject(expressionProjectInfo)
            //.AddMetadataReference(ExpressionProjectId, MetadataReferences.CoreLib)
            //.AddMetadataReference(ExpressionProjectId, MetadataReferences.NetstandardLib)
            ////.AddMetadataReference(ExpressionProjectId, GetMetadataReference("System.dll"))
            //.AddProjectReference(ExpressionProjectId, new ProjectReference(ModelProjectId))
            //.AddProjectReference(ExpressionProjectId, new ProjectReference(SyncServiceProxyProjectId));

            if (!Workspace.TryApplyChanges(newSolution))
            {
                Log.Warn("Cannot create default workspace.");
            }
        }