diff --git a/src/Microsoft.DotNet.ProjectModel.Server/ConnectionContext.cs b/src/Microsoft.DotNet.ProjectModel.Server/ConnectionContext.cs index a6c73bc45..7ea4d2b40 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/ConnectionContext.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/ConnectionContext.cs @@ -12,17 +12,17 @@ namespace Microsoft.DotNet.ProjectModel.Server { private readonly string _hostName; private readonly ProcessingQueue _queue; - private readonly IDictionary _projectContextManagers; + private readonly IDictionary _projects; public ConnectionContext(Socket acceptedSocket, string hostName, ProtocolManager protocolManager, WorkspaceContext workspaceContext, - IDictionary projectContextManagers, + IDictionary projects, ILoggerFactory loggerFactory) { _hostName = hostName; - _projectContextManagers = projectContextManagers; + _projects = projects; _queue = new ProcessingQueue(new NetworkStream(acceptedSocket), loggerFactory); _queue.OnReceive += message => @@ -35,18 +35,18 @@ namespace Microsoft.DotNet.ProjectModel.Server else { message.Sender = this; - ProjectContextManager keeper; - if (!_projectContextManagers.TryGetValue(message.ContextId, out keeper)) + ProjectManager projectManager; + if (!_projects.TryGetValue(message.ContextId, out projectManager)) { - keeper = new ProjectContextManager(message.ContextId, + projectManager = new ProjectManager(message.ContextId, loggerFactory, workspaceContext, protocolManager); - _projectContextManagers[message.ContextId] = keeper; + _projects[message.ContextId] = projectManager; } - keeper.OnReceive(message); + projectManager.OnReceive(message); } }; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Helpers/NuGetFrameworkExtensions.cs b/src/Microsoft.DotNet.ProjectModel.Server/Helpers/NuGetFrameworkExtensions.cs index 27c2aba6f..279f7c970 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Helpers/NuGetFrameworkExtensions.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Helpers/NuGetFrameworkExtensions.cs @@ -8,15 +8,14 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models { public static class NuGetFrameworkExtensions { - public static FrameworkData ToPayload(this NuGetFramework framework, - FrameworkReferenceResolver resolver) + public static FrameworkData ToPayload(this NuGetFramework framework) { return new FrameworkData { ShortName = framework.GetShortFolderName(), FrameworkName = framework.DotNetFrameworkName, FriendlyName = framework.Framework, - RedistListPath = resolver.GetFrameworkRedistListPath(framework) + RedistListPath = FrameworkReferenceResolver.Default.GetFrameworkRedistListPath(framework) }; } } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/DependencyInfo.cs b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/DependencyInfo.cs deleted file mode 100644 index b0a21773f..000000000 --- a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/DependencyInfo.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using Microsoft.DotNet.ProjectModel.Server.Models; - -namespace Microsoft.DotNet.ProjectModel.Server.InternalModels -{ - internal class DependencyInfo - { - public Dictionary Dependencies { get; set; } - } -} diff --git a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectContextSnapshot.cs b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectContextSnapshot.cs new file mode 100644 index 000000000..1bb6fe760 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectContextSnapshot.cs @@ -0,0 +1,69 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.DotNet.ProjectModel.Server.Helpers; +using Microsoft.DotNet.ProjectModel.Server.Models; +using NuGet.Frameworks; + +namespace Microsoft.DotNet.ProjectModel.Server +{ + internal class ProjectContextSnapshot + { + public string RootDependency { get; set; } + public NuGetFramework TargetFramework { get; set; } + public IReadOnlyList SourceFiles { get; set; } + public CommonCompilerOptions CompilerOptions { get; set; } + public IReadOnlyList ProjectReferences { get; set; } + public IReadOnlyList FileReferences { get; set; } + public IReadOnlyList DependencyDiagnostics { get; set; } + public IDictionary Dependencies { get; set; } + + public static ProjectContextSnapshot Create(ProjectContext context, string configuration, IEnumerable currentSearchPaths) + { + var snapshot = new ProjectContextSnapshot(); + + var allDependencyDiagnostics = new List(); + allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); + allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(context, currentSearchPaths)); + + var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source); + + var allSourceFiles = new List(context.ProjectFile.Files.SourceFiles); + var allFileReferences = new List(); + var allProjectReferences = new List(); + var allDependencies = new Dictionary(); + + foreach (var export in context.CreateExporter(configuration).GetDependencies()) + { + allSourceFiles.AddRange(export.SourceReferences); + allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); + + var library = export.Library; + var diagnostics = diagnosticsLookup[library].ToList(); + var description = DependencyDescription.Create(library, diagnostics); + allDependencies[description.Name] = description; + + var projectDescription = library as ProjectDescription; + + if (projectDescription != null) + { + allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription)); + } + } + + snapshot.RootDependency = context.ProjectFile.Name; + snapshot.TargetFramework = context.TargetFramework; + snapshot.SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); + snapshot.CompilerOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); + snapshot.ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList(); + snapshot.FileReferences = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); + snapshot.DependencyDiagnostics = allDependencyDiagnostics; + snapshot.Dependencies = allDependencies; + + return snapshot; + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectInfo.cs b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectInfo.cs deleted file mode 100644 index 20af7171d..000000000 --- a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectInfo.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.DotNet.ProjectModel.Server.Helpers; -using Microsoft.DotNet.ProjectModel.Server.Models; -using NuGet.Frameworks; - -namespace Microsoft.DotNet.ProjectModel.Server.InternalModels -{ - internal class ProjectInfo - { - public ProjectInfo(ProjectContext context, - string configuration, - IEnumerable currentSearchPaths) - { - var allExports = context.CreateExporter(configuration).GetAllExports().ToList(); - var allDiagnostics = context.LibraryManager.GetAllDiagnostics(); - - Context = context; - Configuration = configuration; - - var allSourceFiles = new List(context.ProjectFile.Files.SourceFiles); - var allFileReferences = new List(); - - foreach (var export in allExports) - { - allSourceFiles.AddRange(export.SourceReferences); - allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); - } - - SourceFiles = allSourceFiles.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); - CompilationAssembiles = allFileReferences.Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(path => path).ToList(); - - var allProjectReferences = new List(); - - var allDependencyDiagnostics = new List(); - allDependencyDiagnostics.AddRange(context.LibraryManager.GetAllDiagnostics()); - allDependencyDiagnostics.AddRange(DependencyTypeChangeFinder.Diagnose(Context, currentSearchPaths)); - - var diagnosticsLookup = allDependencyDiagnostics.ToLookup(d => d.Source); - - Dependencies = new Dictionary(); - - foreach (var library in context.LibraryManager.GetLibraries()) - { - var diagnostics = diagnosticsLookup[library].ToList(); - var description = DependencyDescription.Create(library, diagnostics); - Dependencies[description.Name] = description; - - if (library is ProjectDescription && library.Identity.Name != context.ProjectFile.Name) - { - allProjectReferences.Add(ProjectReferenceDescription.Create((ProjectDescription)library)); - } - } - - DependencyDiagnostics = allDependencyDiagnostics; - ProjectReferences = allProjectReferences.OrderBy(reference => reference.Name).ToList(); - } - - public string Configuration { get; } - - public ProjectContext Context { get; } - - public string RootDependency => Context.ProjectFile.Name; - - public NuGetFramework Framework => Context.TargetFramework; - - public CommonCompilerOptions CompilerOptions => Context.ProjectFile.GetCompilerOptions(Framework, Configuration); - - public IReadOnlyList SourceFiles { get; } - - public IReadOnlyList CompilationAssembiles { get; } - - public IReadOnlyList ProjectReferences { get; } - - public IReadOnlyList DependencyDiagnostics { get; } - - public Dictionary Dependencies { get; } - } -} diff --git a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectSnapshot.cs b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectSnapshot.cs index 289cd76a5..caa0c7bf1 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectSnapshot.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectSnapshot.cs @@ -1,21 +1,47 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; +using System.Linq; +using Microsoft.DotNet.ProjectModel.Server.Helpers; using Microsoft.DotNet.ProjectModel.Server.Models; using NuGet.Frameworks; -namespace Microsoft.DotNet.ProjectModel.Server.InternalModels +namespace Microsoft.DotNet.ProjectModel.Server { internal class ProjectSnapshot { - public NuGetFramework TargetFramework { get; set; } - public IReadOnlyList SourceFiles { get; set; } - public CommonCompilerOptions CompilerOptions { get; set; } - public IReadOnlyList ProjectReferences { get; set; } - public IReadOnlyList FileReferences { get; set; } - public IReadOnlyList DependencyDiagnostics { get; set; } - public IDictionary Dependencies { get; set; } - public string RootDependency { get; set; } + public Project Project { get; set; } + public string GlobalJsonPath { get; set; } + public IReadOnlyList ProjectSearchPaths { get; set; } + public IReadOnlyList ProjectDiagnostics { get; set; } + public ErrorMessage GlobalErrorMessage { get; set; } + public Dictionary ProjectContexts { get; } = new Dictionary(); + + public static ProjectSnapshot Create(string projectDirectory, string configuration, WorkspaceContext workspaceContext, IReadOnlyList projectSearchPaths) + { + var projectContextsCollection = workspaceContext.GetProjectContextCollection(projectDirectory); + if (!projectContextsCollection.ProjectContexts.Any()) + { + throw new InvalidOperationException($"Unable to find project.json in '{projectDirectory}'"); + } + GlobalSettings globalSettings; + var currentSearchPaths = projectContextsCollection.Project.ResolveSearchPaths(out globalSettings); + + var snapshot = new ProjectSnapshot(); + snapshot.Project = projectContextsCollection.Project; + snapshot.ProjectDiagnostics = new List(projectContextsCollection.ProjectDiagnostics); + snapshot.ProjectSearchPaths = currentSearchPaths.ToList(); + snapshot.GlobalJsonPath = globalSettings?.FilePath; + + foreach (var projectContext in projectContextsCollection.ProjectContexts) + { + snapshot.ProjectContexts[projectContext.TargetFramework] = + ProjectContextSnapshot.Create(projectContext, configuration, currentSearchPaths); + } + + return snapshot; + } } } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectState.cs b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectState.cs deleted file mode 100644 index fc7efe0e1..000000000 --- a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/ProjectState.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Linq; -using System.Collections.Generic; -using System; - -namespace Microsoft.DotNet.ProjectModel.Server.InternalModels -{ - internal class ProjectState - { - public static ProjectState Create(string appPath, - string configuration, - WorkspaceContext workspaceContext, - IEnumerable currentSearchPaths) - { - var projectContextsCollection = workspaceContext.GetProjectContextCollection(appPath); - if (!projectContextsCollection.ProjectContexts.Any()) - { - throw new InvalidOperationException($"Unable to find project.json in '{appPath}'"); - } - - var project = projectContextsCollection.ProjectContexts.First().ProjectFile; - var projectDiagnostics = new List(projectContextsCollection.ProjectDiagnostics); - var projectInfos = new List(); - - foreach (var projectContext in projectContextsCollection.ProjectContexts) - { - projectInfos.Add(new ProjectInfo( - projectContext, - configuration, - currentSearchPaths)); - } - - return new ProjectState(project, projectDiagnostics, projectInfos); - } - - private ProjectState(Project project, List projectDiagnostics, List projectInfos) - { - Project = project; - Projects = projectInfos; - Diagnostics = projectDiagnostics; - } - - public Project Project { get; } - - public IReadOnlyList Projects { get; } - - public IReadOnlyList Diagnostics { get; } - } -} diff --git a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/Snapshot.cs b/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/Snapshot.cs deleted file mode 100644 index 9ef3f6124..000000000 --- a/src/Microsoft.DotNet.ProjectModel.Server/InternalModels/Snapshot.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using Microsoft.DotNet.ProjectModel.Server.Helpers; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; -using Microsoft.DotNet.ProjectModel.Server.Models; -using NuGet.Frameworks; - -namespace Microsoft.DotNet.ProjectModel.Server -{ - internal class Snapshot - { - public static Snapshot CreateFromProject(Project project) - { - GlobalSettings globalSettings; - var projectSearchPaths = project.ResolveSearchPaths(out globalSettings); - - return new Snapshot(project, globalSettings?.FilePath, projectSearchPaths); - } - - public Snapshot() - { - Projects = new Dictionary(); - } - - public Snapshot(Project project, string globalJsonPath, IEnumerable projectSearchPaths) - : this() - { - Project = project; - GlobalJsonPath = globalJsonPath; - ProjectSearchPaths = projectSearchPaths.ToList(); - } - - public Project Project { get; set; } - public string GlobalJsonPath { get; set; } - public IReadOnlyList ProjectSearchPaths { get; set; } - public IReadOnlyList ProjectDiagnostics { get; set; } - public ErrorMessage GlobalErrorMessage { get; set; } - public Dictionary Projects { get; } - } -} diff --git a/src/Microsoft.DotNet.ProjectModel.Server/MessageTypes.cs b/src/Microsoft.DotNet.ProjectModel.Server/MessageTypes.cs index 83aae8134..df9419502 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/MessageTypes.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/MessageTypes.cs @@ -6,7 +6,6 @@ namespace Microsoft.DotNet.ProjectModel.Server public class MessageTypes { // Incoming - public const string ProjectContexts = nameof(ProjectContexts); public const string Initialize = nameof(Initialize); public const string ChangeConfiguration = nameof(ChangeConfiguration); public const string RefreshDependencies = nameof(RefreshDependencies); @@ -24,6 +23,5 @@ namespace Microsoft.DotNet.ProjectModel.Server public const string CompilerOptions = nameof(CompilerOptions); public const string References = nameof(References); public const string Sources = nameof(Sources); - public const string AllDiagnostics = nameof(AllDiagnostics); } } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/CompilerOptionsMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/CompilerOptionsMessenger.cs index 1450dbc6d..429d9f690 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/CompilerOptionsMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/CompilerOptionsMessenger.cs @@ -2,38 +2,37 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class CompilerOptionsMessenger : Messenger + internal class CompilerOptionsMessenger : Messenger { public CompilerOptionsMessenger(Action transmit) : base(MessageTypes.CompilerOptions, transmit) { } - protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) + protected override bool CheckDifference(ProjectContextSnapshot local, ProjectContextSnapshot remote) { return remote.CompilerOptions != null && Equals(local.CompilerOptions, remote.CompilerOptions); } - protected override object CreatePayload(ProjectSnapshot local) + protected override object CreatePayload(ProjectContextSnapshot local) { - return new CompilationOptionsMessagePayload + return new CompilationOptionsMessage { - Framework = local.TargetFramework.ToPayload(_resolver), + Framework = local.TargetFramework.ToPayload(), Options = local.CompilerOptions }; } - protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) + protected override void SetValue(ProjectContextSnapshot local, ProjectContextSnapshot remote) { remote.CompilerOptions = local.CompilerOptions; } - private class CompilationOptionsMessagePayload + private class CompilationOptionsMessage { public FrameworkData Framework { get; set; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependenciesMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependenciesMessenger.cs index 728ba3eff..3f37b40c5 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependenciesMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependenciesMessenger.cs @@ -4,18 +4,17 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class DependenciesMessenger : Messenger + internal class DependenciesMessenger : Messenger { public DependenciesMessenger(Action transmit) : base(MessageTypes.Dependencies, transmit) { } - protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) + protected override bool CheckDifference(ProjectContextSnapshot local, ProjectContextSnapshot remote) { return remote.Dependencies != null && string.Equals(local.RootDependency, remote.RootDependency) && @@ -23,17 +22,17 @@ namespace Microsoft.DotNet.ProjectModel.Server.Messengers Enumerable.SequenceEqual(local.Dependencies, remote.Dependencies); } - protected override object CreatePayload(ProjectSnapshot local) + protected override object CreatePayload(ProjectContextSnapshot local) { return new DependenciesMessage { - Framework = local.TargetFramework.ToPayload(_resolver), + Framework = local.TargetFramework.ToPayload(), RootDependency = local.RootDependency, Dependencies = local.Dependencies }; } - protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) + protected override void SetValue(ProjectContextSnapshot local, ProjectContextSnapshot remote) { remote.Dependencies = local.Dependencies; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependencyDiagnosticsMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependencyDiagnosticsMessenger.cs index abe3a6bc7..a4122f3c2 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependencyDiagnosticsMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/DependencyDiagnosticsMessenger.cs @@ -3,31 +3,30 @@ using System; using System.Linq; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class DependencyDiagnosticsMessenger : Messenger + internal class DependencyDiagnosticsMessenger : Messenger { public DependencyDiagnosticsMessenger(Action transmit) : base(MessageTypes.DependencyDiagnostics, transmit) { } - protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) + protected override bool CheckDifference(ProjectContextSnapshot local, ProjectContextSnapshot remote) { return remote.DependencyDiagnostics != null && Enumerable.SequenceEqual(local.DependencyDiagnostics, remote.DependencyDiagnostics); } - protected override object CreatePayload(ProjectSnapshot local) + protected override object CreatePayload(ProjectContextSnapshot local) { return new DiagnosticsListMessage( local.DependencyDiagnostics, - local.TargetFramework?.ToPayload(_resolver)); + local.TargetFramework?.ToPayload()); } - protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) + protected override void SetValue(ProjectContextSnapshot local, ProjectContextSnapshot remote) { remote.DependencyDiagnostics = local.DependencyDiagnostics; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/GlobalErrorMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/GlobalErrorMessenger.cs index 23b77255b..7410678d0 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/GlobalErrorMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/GlobalErrorMessenger.cs @@ -5,23 +5,23 @@ using System; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class GlobalErrorMessenger : Messenger + internal class GlobalErrorMessenger : Messenger { public GlobalErrorMessenger(Action transmit) : base(MessageTypes.Error, transmit) { } - protected override bool CheckDifference(Snapshot local, Snapshot remote) + protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) { return remote != null && Equals(local.GlobalErrorMessage, remote.GlobalErrorMessage); } - protected override object CreatePayload(Snapshot local) + protected override object CreatePayload(ProjectSnapshot local) { return local.GlobalErrorMessage; } - protected override void SetValue(Snapshot local, Snapshot remote) + protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) { remote.GlobalErrorMessage = local.GlobalErrorMessage; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/Messenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/Messenger.cs index 7ec3d247b..fee5f9aa3 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/Messenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/Messenger.cs @@ -2,18 +2,15 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using Microsoft.DotNet.ProjectModel.Resolution; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { internal abstract class Messenger where T : class { - protected readonly FrameworkReferenceResolver _resolver; protected readonly Action _transmit; public Messenger(string messageType, Action transmit) { - _resolver = FrameworkReferenceResolver.Default; _transmit = transmit; MessageType = messageType; diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectDiagnosticsMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectDiagnosticsMessenger.cs index e93d74a87..5ebd89cb6 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectDiagnosticsMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectDiagnosticsMessenger.cs @@ -7,24 +7,24 @@ using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class ProjectDiagnosticsMessenger : Messenger + internal class ProjectDiagnosticsMessenger : Messenger { public ProjectDiagnosticsMessenger(Action transmit) : base(MessageTypes.Diagnostics, transmit) { } - protected override bool CheckDifference(Snapshot local, Snapshot remote) + protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) { return remote.ProjectDiagnostics != null && Enumerable.SequenceEqual(local.ProjectDiagnostics, remote.ProjectDiagnostics); } - protected override object CreatePayload(Snapshot local) + protected override object CreatePayload(ProjectSnapshot local) { return new DiagnosticsListMessage(local.ProjectDiagnostics); } - protected override void SetValue(Snapshot local, Snapshot remote) + protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) { remote.ProjectDiagnostics = local.ProjectDiagnostics; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectInformationMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectInformationMessenger.cs index 715498046..33b347497 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectInformationMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ProjectInformationMessenger.cs @@ -4,18 +4,17 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.DotNet.ProjectModel.Resolution; using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class ProjectInformationMessenger : Messenger + internal class ProjectInformationMessenger : Messenger { public ProjectInformationMessenger(Action transmit) : base(MessageTypes.ProjectInformation, transmit) { } - protected override bool CheckDifference(Snapshot local, Snapshot remote) + protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) { return remote.Project != null && string.Equals(local.Project.Name, remote.Project.Name) && @@ -27,30 +26,29 @@ namespace Microsoft.DotNet.ProjectModel.Server.Messengers Enumerable.SequenceEqual(local.ProjectSearchPaths, remote.ProjectSearchPaths); } - protected override object CreatePayload(Snapshot local) + protected override object CreatePayload(ProjectSnapshot local) { - return new ProjectInformation(local.Project, local.GlobalJsonPath, local.ProjectSearchPaths, _resolver); + return new ProjectInformationMessage(local.Project, local.GlobalJsonPath, local.ProjectSearchPaths); } - protected override void SetValue(Snapshot local, Snapshot remote) + protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) { remote.Project = local.Project; remote.GlobalJsonPath = local.GlobalJsonPath; remote.ProjectSearchPaths = local.ProjectSearchPaths; } - private class ProjectInformation + private class ProjectInformationMessage { - public ProjectInformation(Project project, - string gloablJsonPath, - IEnumerable projectSearchPath, - FrameworkReferenceResolver resolver) + public ProjectInformationMessage(Project project, + string gloablJsonPath, + IReadOnlyList projectSearchPaths) { Name = project.Name; - Frameworks = project.GetTargetFrameworks().Select(f => f.FrameworkName.ToPayload(resolver)).ToList(); + Frameworks = project.GetTargetFrameworks().Select(f => f.FrameworkName.ToPayload()).ToList(); Configurations = project.GetConfigurations().ToList(); Commands = project.Commands; - ProjectSearchPaths = new List(projectSearchPath); + ProjectSearchPaths = projectSearchPaths; GlobalJsonPath = gloablJsonPath; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ReferencesMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ReferencesMessenger.cs index 50127875c..2d8436816 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ReferencesMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/ReferencesMessenger.cs @@ -4,18 +4,17 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class ReferencesMessenger : Messenger + internal class ReferencesMessenger : Messenger { public ReferencesMessenger(Action transmit) : base(MessageTypes.References, transmit) { } - protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) + protected override bool CheckDifference(ProjectContextSnapshot local, ProjectContextSnapshot remote) { return remote.FileReferences != null && remote.ProjectReferences != null && @@ -23,17 +22,17 @@ namespace Microsoft.DotNet.ProjectModel.Server.Messengers Enumerable.SequenceEqual(local.ProjectReferences, remote.ProjectReferences); } - protected override object CreatePayload(ProjectSnapshot local) + protected override object CreatePayload(ProjectContextSnapshot local) { return new ReferencesMessage { - Framework = local.TargetFramework.ToPayload(_resolver), + Framework = local.TargetFramework.ToPayload(), ProjectReferences = local.ProjectReferences, FileReferences = local.FileReferences }; } - protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) + protected override void SetValue(ProjectContextSnapshot local, ProjectContextSnapshot remote) { remote.FileReferences = local.FileReferences; remote.ProjectReferences = local.ProjectReferences; diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/SourcesMessenger.cs b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/SourcesMessenger.cs index 77e0473bf..430ecc724 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Messengers/SourcesMessenger.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Messengers/SourcesMessenger.cs @@ -4,39 +4,38 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; using Microsoft.DotNet.ProjectModel.Server.Models; namespace Microsoft.DotNet.ProjectModel.Server.Messengers { - internal class SourcesMessenger : Messenger + internal class SourcesMessenger : Messenger { public SourcesMessenger(Action transmit) : base(MessageTypes.Sources, transmit) { } - protected override bool CheckDifference(ProjectSnapshot local, ProjectSnapshot remote) + protected override bool CheckDifference(ProjectContextSnapshot local, ProjectContextSnapshot remote) { return remote.SourceFiles != null && Enumerable.SequenceEqual(local.SourceFiles, remote.SourceFiles); } - protected override object CreatePayload(ProjectSnapshot local) + protected override object CreatePayload(ProjectContextSnapshot local) { - return new SourcesMessagePayload + return new SourcesMessage { - Framework = local.TargetFramework.ToPayload(_resolver), + Framework = local.TargetFramework.ToPayload(), Files = local.SourceFiles, GeneratedFiles = new Dictionary() }; } - protected override void SetValue(ProjectSnapshot local, ProjectSnapshot remote) + protected override void SetValue(ProjectContextSnapshot local, ProjectContextSnapshot remote) { remote.SourceFiles = local.SourceFiles; } - private class SourcesMessagePayload + private class SourcesMessage { public FrameworkData Framework { get; set; } public IReadOnlyList Files { get; set; } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Models/DependencyDescription.cs b/src/Microsoft.DotNet.ProjectModel.Server/Models/DependencyDescription.cs index 35948eca0..7ae2cfe65 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Models/DependencyDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Models/DependencyDescription.cs @@ -11,28 +11,6 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models { private DependencyDescription() { } - public static DependencyDescription Create(LibraryDescription library, IEnumerable diagnostics) - { - return new DependencyDescription - { - Name = library.Identity.Name, - DisplayName = GetLibraryDisplayName(library), - Version = library.Identity.Version?.ToString(), - Type = library.Identity.Type.Value, - Resolved = library.Resolved, - Path = library.Path, - Dependencies = library.Dependencies.Select(dependency => new DependencyItem - { - Name = dependency.Name, - Version = dependency.VersionRange?.ToString() // TODO: review - }), - Errors = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Error) - .Select(d => new DiagnosticMessageView(d)), - Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning) - .Select(d => new DiagnosticMessageView(d)) - }; - } - public string Name { get; private set; } public string DisplayName { get; private set; } @@ -73,6 +51,28 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models return base.GetHashCode(); } + public static DependencyDescription Create(LibraryDescription library, IEnumerable diagnostics) + { + return new DependencyDescription + { + Name = library.Identity.Name, + DisplayName = GetLibraryDisplayName(library), + Version = library.Identity.Version?.ToString(), + Type = library.Identity.Type.Value, + Resolved = library.Resolved, + Path = library.Path, + Dependencies = library.Dependencies.Select(dependency => new DependencyItem + { + Name = dependency.Name, + Version = dependency.VersionRange?.ToString() // TODO: review + }), + Errors = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Error) + .Select(d => new DiagnosticMessageView(d)), + Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning) + .Select(d => new DiagnosticMessageView(d)) + }; + } + private static string GetLibraryDisplayName(LibraryDescription library) { var name = library.Identity.Name; diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Models/DiagnosticsListMessage.cs b/src/Microsoft.DotNet.ProjectModel.Server/Models/DiagnosticsListMessage.cs index e8ae452dd..dc66cd12d 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Models/DiagnosticsListMessage.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Models/DiagnosticsListMessage.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace Microsoft.DotNet.ProjectModel.Server.Models { diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Models/ProjectReferenceDescription.cs b/src/Microsoft.DotNet.ProjectModel.Server/Models/ProjectReferenceDescription.cs index 019c2062a..cc4ac61b3 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Models/ProjectReferenceDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Models/ProjectReferenceDescription.cs @@ -7,6 +7,24 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models { private ProjectReferenceDescription() { } + public string Name { get; set; } + public string Path { get; set; } + public string WrappedProjectPath { get; set; } + + public override bool Equals(object obj) + { + var other = obj as ProjectReferenceDescription; + return other != null && + string.Equals(Name, other.Name) && + string.Equals(Path, other.Path) && + string.Equals(WrappedProjectPath, other.WrappedProjectPath); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + public static ProjectReferenceDescription Create(ProjectDescription description) { var targetFrameworkInformation = description.TargetFrameworkInfo; @@ -29,23 +47,5 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models WrappedProjectPath = wrappedProjectPath, }; } - - public string Name { get; set; } - public string Path { get; set; } - public string WrappedProjectPath { get; set; } - - public override bool Equals(object obj) - { - var other = obj as ProjectReferenceDescription; - return other != null && - string.Equals(Name, other.Name) && - string.Equals(Path, other.Path) && - string.Equals(WrappedProjectPath, other.WrappedProjectPath); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } } } diff --git a/src/Microsoft.DotNet.ProjectModel.Server/Program.cs b/src/Microsoft.DotNet.ProjectModel.Server/Program.cs index 293bae263..be9d23ca7 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/Program.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/Program.cs @@ -6,14 +6,13 @@ using System.Diagnostics; using System.Net; using System.Net.Sockets; using Microsoft.Dnx.Runtime.Common.CommandLine; -using Microsoft.DotNet.ProjectModel.Resolution; using Microsoft.Extensions.Logging; namespace Microsoft.DotNet.ProjectModel.Server { public class Program { - private readonly Dictionary _projectContextManagers; + private readonly Dictionary _projects; private readonly WorkspaceContext _workspaceContext; private readonly ProtocolManager _protocolManager; private readonly ILoggerFactory _loggerFactory; @@ -21,14 +20,14 @@ namespace Microsoft.DotNet.ProjectModel.Server private readonly int _port; private Socket _listenSocket; - public Program(int intPort, string hostName, ILoggerFactory loggerFactory) + public Program(int port, string hostName, ILoggerFactory loggerFactory) { - _port = intPort; + _port = port; _hostName = hostName; _loggerFactory = loggerFactory; _protocolManager = new ProtocolManager(maxVersion: 4, loggerFactory: _loggerFactory); _workspaceContext = WorkspaceContext.Create(); - _projectContextManagers = new Dictionary(); + _projects = new Dictionary(); } public static int Main(string[] args) @@ -41,8 +40,8 @@ namespace Microsoft.DotNet.ProjectModel.Server app.HelpOption("-?|-h|--help"); var verbose = app.Option("--verbose", "Verbose ouput", CommandOptionType.NoValue); - var hostpid = app.Option("--hostPid", "The process id of the host", CommandOptionType.SingleValue); - var hostname = app.Option("--hostName", "The name of the host", CommandOptionType.SingleValue); + var hostpid = app.Option("--host-pid", "The process id of the host", CommandOptionType.SingleValue); + var hostname = app.Option("--host-name", "The name of the host", CommandOptionType.SingleValue); var port = app.Option("--port", "The TCP port used for communication", CommandOptionType.SingleValue); app.OnExecute(() => @@ -82,7 +81,6 @@ namespace Microsoft.DotNet.ProjectModel.Server { var logger = _loggerFactory.CreateLogger($"OpenChannel"); - // This fixes the mono incompatibility but ties it to ipv4 connections _listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _listenSocket.Bind(new IPEndPoint(IPAddress.Loopback, _port)); _listenSocket.Listen(10); @@ -99,7 +97,7 @@ namespace Microsoft.DotNet.ProjectModel.Server _hostName, _protocolManager, _workspaceContext, - _projectContextManagers, + _projects, _loggerFactory); connection.QueueStart(); diff --git a/src/Microsoft.DotNet.ProjectModel.Server/ProjectContextManager.cs b/src/Microsoft.DotNet.ProjectModel.Server/ProjectManager.cs similarity index 63% rename from src/Microsoft.DotNet.ProjectModel.Server/ProjectContextManager.cs rename to src/Microsoft.DotNet.ProjectModel.Server/ProjectManager.cs index dc2fa9434..8e299d119 100644 --- a/src/Microsoft.DotNet.ProjectModel.Server/ProjectContextManager.cs +++ b/src/Microsoft.DotNet.ProjectModel.Server/ProjectManager.cs @@ -6,25 +6,21 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; -using Microsoft.DotNet.ProjectModel.Resolution; using Microsoft.DotNet.ProjectModel.Server.Helpers; -using Microsoft.DotNet.ProjectModel.Server.InternalModels; using Microsoft.DotNet.ProjectModel.Server.Messengers; using Microsoft.DotNet.ProjectModel.Server.Models; using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; using NuGet.Frameworks; namespace Microsoft.DotNet.ProjectModel.Server { - internal class ProjectContextManager + internal class ProjectManager { private readonly ILogger _log; private readonly object _processingLock = new object(); private readonly Queue _inbox = new Queue(); private readonly ProtocolManager _protocolManager; - private readonly List _waitingForDiagnostics = new List(); private ConnectionContext _initializedContext; @@ -34,29 +30,29 @@ namespace Microsoft.DotNet.ProjectModel.Server private readonly Trigger _refreshDependencies = new Trigger(); private readonly Trigger _filesChanged = new Trigger(); - private Snapshot _local = new Snapshot(); - private Snapshot _remote = new Snapshot(); + private ProjectSnapshot _local = new ProjectSnapshot(); + private ProjectSnapshot _remote = new ProjectSnapshot(); private readonly WorkspaceContext _workspaceContext; private int? _contextProtocolVersion; - private readonly List> _messengers; + private readonly List> _messengers; private ProjectDiagnosticsMessenger _projectDiagnosticsMessenger; private GlobalErrorMessenger _globalErrorMessenger; private ProjectInformationMessenger _projectInforamtionMessenger; - public ProjectContextManager(int contextId, + public ProjectManager(int contextId, ILoggerFactory loggerFactory, WorkspaceContext workspaceContext, ProtocolManager protocolManager) { Id = contextId; - _log = loggerFactory.CreateLogger(); + _log = loggerFactory.CreateLogger(); _workspaceContext = workspaceContext; _protocolManager = protocolManager; - _messengers = new List> + _messengers = new List> { new DependencyDiagnosticsMessenger(Transmit), new DependenciesMessenger(Transmit), @@ -66,7 +62,7 @@ namespace Microsoft.DotNet.ProjectModel.Server }; _projectDiagnosticsMessenger = new ProjectDiagnosticsMessenger(Transmit); - _globalErrorMessenger = new GlobalErrorMessenger(TransmitDiagnostics); + _globalErrorMessenger = new GlobalErrorMessenger(Transmit); _projectInforamtionMessenger = new ProjectInformationMessenger(Transmit); } @@ -96,7 +92,7 @@ namespace Microsoft.DotNet.ProjectModel.Server _inbox.Enqueue(message); } - ThreadPool.QueueUserWorkItem(state => ((ProjectContextManager)state).ProcessLoop(), this); + ThreadPool.QueueUserWorkItem(state => ((ProjectManager)state).ProcessLoop(), this); } private void Transmit(string messageType, object payload) @@ -105,17 +101,6 @@ namespace Microsoft.DotNet.ProjectModel.Server _initializedContext.Transmit(message); } - private void TransmitDiagnostics(string messageType, object payload) - { - var message = Message.FromPayload(messageType, Id, payload); - _initializedContext.Transmit(message); - - foreach (var connection in _waitingForDiagnostics) - { - connection.Transmit(message); - } - } - private void ProcessLoop() { if (!Monitor.TryEnter(_processingLock)) @@ -158,13 +143,6 @@ namespace Microsoft.DotNet.ProjectModel.Server _initializedContext.Transmit(message); _remote.GlobalErrorMessage = error; - - foreach (var connection in _waitingForDiagnostics) - { - connection.Transmit(message); - } - - _waitingForDiagnostics.Clear(); } } @@ -173,12 +151,9 @@ namespace Microsoft.DotNet.ProjectModel.Server while (true) { DrainInbox(); - - var allDiagnostics = new List(); - - UpdateProjectStates(); - SendOutgingMessages(allDiagnostics); - SendDiagnostics(allDiagnostics); + + UpdateProject(); + SendOutgingMessages(); lock (_inbox) { @@ -232,9 +207,6 @@ namespace Microsoft.DotNet.ProjectModel.Server case MessageTypes.FilesChanged: _filesChanged.Value = 0; break; - case MessageTypes.GetDiagnostics: - _waitingForDiagnostics.Add(message.Sender); - break; } return true; @@ -260,9 +232,9 @@ namespace Microsoft.DotNet.ProjectModel.Server } } - private bool UpdateProjectStates() + private bool UpdateProject() { - ProjectState state = null; + ProjectSnapshot newSnapshot = null; if (_appPath.WasAssigned || _configure.WasAssigned || _filesChanged.WasAssigned || _refreshDependencies.WasAssigned) { @@ -271,71 +243,41 @@ namespace Microsoft.DotNet.ProjectModel.Server _filesChanged.ClearAssigned(); _refreshDependencies.ClearAssigned(); - state = ProjectState.Create(_appPath.Value, _configure.Value, _workspaceContext, _remote.ProjectSearchPaths); + newSnapshot = ProjectSnapshot.Create(_appPath.Value, _configure.Value, _workspaceContext, _remote.ProjectSearchPaths); } - if (state == null) + if (newSnapshot == null) { return false; } - _local = Snapshot.CreateFromProject(state.Project); - _local.ProjectDiagnostics = state.Diagnostics; - - foreach (var projectInfo in state.Projects) - { - var projectWorkd = new ProjectSnapshot - { - RootDependency = projectInfo.RootDependency, - TargetFramework = projectInfo.Framework, - SourceFiles = new List(projectInfo.SourceFiles), - CompilerOptions = projectInfo.CompilerOptions, - ProjectReferences = projectInfo.ProjectReferences, - FileReferences = projectInfo.CompilationAssembiles, - DependencyDiagnostics = projectInfo.DependencyDiagnostics, - Dependencies = projectInfo.Dependencies - }; - - _local.Projects[projectInfo.Framework] = projectWorkd; - } + _local = newSnapshot; return true; } - private void SendOutgingMessages(List diagnostics) + private void SendOutgingMessages() { _projectInforamtionMessenger.UpdateRemote(_local, _remote); _projectDiagnosticsMessenger.UpdateRemote(_local, _remote); - if (_local.ProjectDiagnostics != null) + var unprocessedFrameworks = new HashSet(_remote.ProjectContexts.Keys); + foreach (var pair in _local.ProjectContexts) { - diagnostics.Add(new DiagnosticMessageGroup(_local.ProjectDiagnostics)); - } + ProjectContextSnapshot localProjectSnapshot = pair.Value; + ProjectContextSnapshot remoteProjectSnapshot; - var unprocessedFrameworks = new HashSet(_remote.Projects.Keys); - foreach (var pair in _local.Projects) - { - ProjectSnapshot localProjectSnapshot = pair.Value; - ProjectSnapshot remoteProjectSnapshot; - - if (!_remote.Projects.TryGetValue(pair.Key, out remoteProjectSnapshot)) + if (!_remote.ProjectContexts.TryGetValue(pair.Key, out remoteProjectSnapshot)) { - remoteProjectSnapshot = new ProjectSnapshot(); - _remote.Projects[pair.Key] = remoteProjectSnapshot; - } - - if (localProjectSnapshot.DependencyDiagnostics != null) - { - diagnostics.Add(new DiagnosticMessageGroup( - localProjectSnapshot.TargetFramework, - localProjectSnapshot.DependencyDiagnostics)); + remoteProjectSnapshot = new ProjectContextSnapshot(); + _remote.ProjectContexts[pair.Key] = remoteProjectSnapshot; } unprocessedFrameworks.Remove(pair.Key); - foreach(var messenger in _messengers) + foreach (var messenger in _messengers) { - messenger.UpdateRemote(localProjectSnapshot, + messenger.UpdateRemote(localProjectSnapshot, remoteProjectSnapshot); } } @@ -343,35 +285,10 @@ namespace Microsoft.DotNet.ProjectModel.Server // Remove all processed frameworks from the remote view foreach (var framework in unprocessedFrameworks) { - _remote.Projects.Remove(framework); + _remote.ProjectContexts.Remove(framework); } - } - - private void SendDiagnostics(List allDiagnostics) - { - _log.LogInformation($"SendDiagnostics, {allDiagnostics.Count()} diagnostics, {_waitingForDiagnostics.Count()} waiting for diagnostics."); - if (!allDiagnostics.Any()) - { - return; - } - + _globalErrorMessenger.UpdateRemote(_local, _remote); - - // Group all of the diagnostics into group by target framework - var messages = new List(); - foreach (var g in allDiagnostics.GroupBy(g => g.Framework)) - { - var frameworkData = g.Key?.ToPayload(FrameworkReferenceResolver.Default); - var messageGroup = g.SelectMany(d => d.Diagnostics).ToList(); - messages.Add(new DiagnosticsListMessage(messageGroup, frameworkData)); - } - - // Send all diagnostics back - TransmitDiagnostics( - MessageTypes.AllDiagnostics, - messages.Select(d => JToken.FromObject(d))); - - _waitingForDiagnostics.Clear(); } private class Trigger diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContextCollection.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContextCollection.cs index 2654a8100..b65de587a 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContextCollection.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContextCollection.cs @@ -9,6 +9,8 @@ namespace Microsoft.DotNet.ProjectModel { public class ProjectContextCollection { + public Project Project { get; set; } + public List ProjectContexts { get; } = new List(); public List ProjectDiagnostics { get; } = new List(); @@ -51,6 +53,7 @@ namespace Microsoft.DotNet.ProjectModel public void Reset() { + Project = null; ProjectContexts.Clear(); ProjectFilePath = null; LockFilePath = null; diff --git a/src/Microsoft.DotNet.ProjectModel/WorkspaceContext.cs b/src/Microsoft.DotNet.ProjectModel/WorkspaceContext.cs index 1ea288ee4..96a1f80da 100644 --- a/src/Microsoft.DotNet.ProjectModel/WorkspaceContext.cs +++ b/src/Microsoft.DotNet.ProjectModel/WorkspaceContext.cs @@ -210,7 +210,7 @@ namespace Microsoft.DotNet.ProjectModel } private ProjectContextCollection AddProjectContextEntry(string projectDirectory, - ProjectContextCollection currentEntry) + ProjectContextCollection currentEntry) { if (currentEntry == null) { @@ -241,7 +241,8 @@ namespace Microsoft.DotNet.ProjectModel currentEntry.ProjectContexts.Add(builder.Build()); } - + + currentEntry.Project = project; currentEntry.ProjectFilePath = project.ProjectFilePath; currentEntry.LastProjectFileWriteTime = File.GetLastWriteTime(currentEntry.ProjectFilePath); diff --git a/test/Microsoft.DotNet.ProjectModel.Server.Tests/DthStartupTests.cs b/test/Microsoft.DotNet.ProjectModel.Server.Tests/DthStartupTests.cs index f8250182a..d5ddb5be7 100644 --- a/test/Microsoft.DotNet.ProjectModel.Server.Tests/DthStartupTests.cs +++ b/test/Microsoft.DotNet.ProjectModel.Server.Tests/DthStartupTests.cs @@ -83,33 +83,6 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests } } - [Fact] - public void DthCompilation_GetDiagnostics_OnEmptyConsoleApp() - { - var projectPath = _testHelper.FindSampleProject("EmptyConsoleApp"); - Assert.NotNull(projectPath); - - using (var server = new DthTestServer(_testHelper.LoggerFactory)) - using (var client = new DthTestClient(server)) - { - // Drain the inital messages - client.Initialize(projectPath); - client.SendPayLoad(projectPath, "GetDiagnostics"); - - var diagnosticsGroup = client.DrainTillFirst("AllDiagnostics") - .EnsureSource(server, client) - .RetrievePayloadAs() - .AssertJArrayCount(3); - - foreach (var group in diagnosticsGroup) - { - group.AsJObject() - .AssertProperty("Errors", errorsArray => !errorsArray.Any()) - .AssertProperty("Warnings", warningsArray => !warningsArray.Any()); - } - } - } - [Theory] [InlineData("Project", "UnresolvedProjectSample", "EmptyLibrary", "Project")] [InlineData("Package", "UnresolvedPackageSample", "NoSuchPackage", null)]