private void UpdateProjectReferences(ProjectState state, IEnumerable <ProjectDescription> projectReferencesLatest) { var projectReferences = new List <ProjectReference>(); var projectReferencesToRemove = state.ProjectReferences.Keys.ToHashSet(); foreach (var description in projectReferencesLatest) { var projectPath = Path.GetDirectoryName(description.Path); if (projectReferencesToRemove.Remove(projectPath)) { continue; } var referencedProjectState = _projectStates.Find(projectPath, description.Framework); projectReferences.Add(new ProjectReference(referencedProjectState.Id)); state.ProjectReferences[projectPath] = referencedProjectState.Id; _logger.LogDebug($" Add project reference {description.Path}"); } foreach (var reference in projectReferences) { _omnisharpWorkspace.AddProjectReference(state.Id, reference); } foreach (var reference in projectReferencesToRemove) { var toRemove = state.ProjectReferences[reference]; state.ProjectReferences.Remove(reference); _omnisharpWorkspace.RemoveProjectReference(state.Id, new ProjectReference(toRemove)); _logger.LogDebug($" Remove project reference {reference}"); } if (projectReferences.Count != 0 || projectReferencesToRemove.Count != 0) { _logger.LogInformation($" Added {projectReferences.Count} and removed {projectReferencesToRemove.Count} project references"); } }
public void Initalize() { var runtimePath = _aspNet5Paths.RuntimePath; _context.RuntimePath = runtimePath.Value; if (!ScanForProjects()) { // No ASP.NET 5 projects found so do nothing _logger.WriteInformation("No project.json based projects found"); return; } if (_context.RuntimePath == null) { // There is no default k found so do nothing _logger.WriteInformation("No default runtime found"); _emitter.Emit(EventTypes.Error, runtimePath.Error); return; } var wh = new ManualResetEventSlim(); _designTimeHostManager.Start(_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.DesignTimeHostPort = port; _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; this._emitter.Emit(EventTypes.ProjectChanged, new ProjectInformationResponse() { AspNet5Project = new AspNet5Project(project) }); 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, project.Path); _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; } int projectReferenceContextId; if (!_context.ProjectContextMapping.TryGetValue(projectReference.Path, out projectReferenceContextId)) { projectReferenceContextId = AddProject(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 == "Dependencies") { var val = m.Payload.ToObject <DependenciesMessage>(); var unresolvedDependencies = val.Dependencies.Values .Where(dep => dep.Type == "Unresolved"); if (unresolvedDependencies.Any()) { _logger.WriteInformation("Project {0} has these unresolved references: {1}", project.Path, string.Join(", ", unresolvedDependencies.Select(d => d.Name))); _emitter.Emit(EventTypes.UnresolvedDependencies, new UnresolvedDependenciesMessage() { FileName = project.Path, UnresolvedDependencies = unresolvedDependencies.Select(d => new PackageDependency() { Name = d.Name, Version = d.Version }) }); _packagesRestoreTool.Run(project); } } 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>(); project.SourceFiles = val.Files; 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; } else if (m.MessageType == "Error") { var val = m.Payload.ToObject <Microsoft.Framework.DesignTimeHost.Models.OutgoingMessages.ErrorMessage>(); _logger.WriteError(val.Message); } if (project.ProjectsByFramework.Values.All(p => p.Loaded)) { wh.Set(); } }; // Start the message channel _context.Connection.Start(); // Initialize the ASP.NET 5 projects Initialize(); }); wh.Wait(); }
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); 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.LogVerbose($"Adding reference '{referencePath}' to '{projectFileInfo.ProjectFilePath}'."); _workspace.AddMetadataReference(project.Id, metadataReference); } } foreach (var reference in unusedReferences) { _workspace.RemoveMetadataReference(project.Id, reference); } }
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 Initalize(IConfiguration configuration) { _logger.LogInformation($"Detecting CSX files in '{_env.Path}'."); var allCsxFiles = Directory.GetFiles(_env.Path, "*.csx", SearchOption.TopDirectoryOnly); if (allCsxFiles.Length == 0) { _logger.LogInformation("Could not find any CSX files"); return; } _scriptCsContext.Path = _env.Path; _logger.LogInformation($"Found {allCsxFiles.Length} CSX files."); //script name is added here as a fake one (dir path not even a real file); this is OK though -> it forces MEF initialization var scriptServicesBuilder = new ScriptServicesBuilder(new ScriptConsole(), LogManager.GetCurrentClassLogger()). LogLevel(LogLevel.Info).Cache(false).Repl(false).ScriptName(_env.Path).ScriptEngine <NullScriptEngine>(); _scriptServices = scriptServicesBuilder.Build(); var mscorlib = MetadataReference.CreateFromAssembly(typeof(object).GetTypeInfo().Assembly); var systemCore = MetadataReference.CreateFromAssembly(typeof(Enumerable).GetTypeInfo().Assembly); var scriptcsContracts = MetadataReference.CreateFromAssembly(typeof(IScriptHost).Assembly); var parseOptions = new CSharpParseOptions(LanguageVersion.CSharp6, DocumentationMode.Parse, SourceCodeKind.Script); var scriptPacks = _scriptServices.ScriptPackResolver.GetPacks().ToList(); var assemblyPaths = _scriptServices.AssemblyResolver.GetAssemblyPaths(_env.Path); foreach (var csxPath in allCsxFiles) { try { _scriptCsContext.CsxFiles.Add(csxPath); var processResult = _scriptServices.FilePreProcessor.ProcessFile(csxPath); var references = new List <MetadataReference> { mscorlib, systemCore, scriptcsContracts }; var usings = new List <string>(ScriptExecutor.DefaultNamespaces); //default references ImportReferences(references, ScriptExecutor.DefaultReferences); //file usings usings.AddRange(processResult.Namespaces); //#r references ImportReferences(references, processResult.References); //nuget references ImportReferences(references, assemblyPaths); //script packs if (scriptPacks != null && scriptPacks.Any()) { var scriptPackSession = new ScriptPackSession(scriptPacks, new string[0]); scriptPackSession.InitializePacks(); //script pack references ImportReferences(references, scriptPackSession.References); //script pack usings usings.AddRange(scriptPackSession.Namespaces); _scriptCsContext.ScriptPacks.UnionWith(scriptPackSession.Contexts.Select(pack => pack.GetType().ToString())); } _scriptCsContext.References.UnionWith(references.Select(x => x.Display)); _scriptCsContext.Usings.UnionWith(usings); var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, usings: usings.Distinct()); var fileName = Path.GetFileName(csxPath); var projectId = ProjectId.CreateNewId(Guid.NewGuid().ToString()); var project = ProjectInfo.Create(projectId, VersionStamp.Create(), fileName, $"{fileName}.dll", LanguageNames.CSharp, null, null, compilationOptions, parseOptions, null, null, references, null, null, true, typeof(IScriptHost)); _workspace.AddProject(project); AddFile(csxPath, projectId); foreach (var filePath in processResult.LoadedScripts.Distinct().Except(new[] { csxPath })) { _scriptCsContext.CsxFiles.Add(filePath); var loadedFileName = Path.GetFileName(filePath); var loadedFileProjectId = ProjectId.CreateNewId(Guid.NewGuid().ToString()); var loadedFileSubmissionProject = ProjectInfo.Create(loadedFileProjectId, VersionStamp.Create(), $"{loadedFileName}-LoadedFrom-{fileName}", $"{loadedFileName}-LoadedFrom-{fileName}.dll", LanguageNames.CSharp, null, null, compilationOptions, parseOptions, null, null, references, null, null, true, typeof(IScriptHost)); _workspace.AddProject(loadedFileSubmissionProject); AddFile(filePath, loadedFileProjectId); _workspace.AddProjectReference(projectId, new ProjectReference(loadedFileProjectId)); } } catch (Exception ex) { _logger.LogError($"{csxPath} will be ignored due to the following error:", ex); } } }
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); // } //}; }
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); } }