Skip to content

Commit

Permalink
Lastest
Browse files Browse the repository at this point in the history
  • Loading branch information
davkean committed Jun 12, 2018
1 parent 053a1a7 commit 51eaa93
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.ComponentModel.Composition;
using Microsoft.VisualStudio.TextManager.Interop;

namespace Microsoft.VisualStudio.ProjectSystem.VS.LanguageServices
{
[Export(typeof(IActiveIntellisenseProjectProvider))]
[ExportProjectNodeComService(typeof(IVsContainedLanguageProjectNameProvider))]
internal class ActiveIntellisenseProjectProvider : IActiveIntellisenseProjectProvider, IVsContainedLanguageProjectNameProvider
{
[ImportingConstructor]
public ActiveIntellisenseProjectProvider(UnconfiguredProject project)
{
}

public string ActiveIntellisenseProjectContext
{
get;
set;
}

public int GetProjectName(uint itemid, out string pbstrProjectName)
{
pbstrProjectName = ActiveIntellisenseProjectContext;
return HResult.OK;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "<Pending>", Scope = "member", Target = "~F:Microsoft.VisualStudio.ProjectSystem.LanguageServices.WorkspaceContextHost.WorkspaceContextHostInstance._subscriptions")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2213:Disposable fields should be disposed", Justification = "<Pending>", Scope = "member", Target = "~F:Microsoft.VisualStudio.ProjectSystem.LanguageServices.WorkspaceContextHost.WorkspaceContextHostInstance._applyChangesToWorkspaceContext")]

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using System;
using System.Collections.Generic;

using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.Logging;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public void Initialize(IWorkspaceProjectContext context)

public void ApplyDesignTime(IProjectVersionedValue<IProjectSubscriptionUpdate> update, bool isActiveContext)
{
// TODO: Prevent overlap

Requires.NotNull(update, nameof(update));

if (!IsInitialized)
Expand All @@ -69,6 +71,8 @@ public void ApplyDesignTime(IProjectVersionedValue<IProjectSubscriptionUpdate> u

public void ApplyEvaluation(IProjectVersionedValue<IProjectSubscriptionUpdate> update, bool isActiveContext)
{
// TODO: Prevent overlap

Requires.NotNull(update, nameof(update));

if (!IsInitialized)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.IO;
using Microsoft.VisualStudio.ProjectSystem.Properties;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices
{
internal partial class WorkspaceContextHost
{
private partial class WorkspaceContextHostInstance
{
private struct ProjectData
{
public string LanguageName;
public string BinOutputPath;
public string ProjectFilePath;
public string DisplayName;

public static ProjectData FromSnapshot(ConfiguredProject project, IProjectRuleSnapshot snapshot)
{
var data = new ProjectData();

snapshot.Properties.TryGetValue(ConfigurationGeneral.LanguageServiceNameProperty, out data.LanguageName);
snapshot.Properties.TryGetValue(ConfigurationGeneral.TargetPathProperty, out data.BinOutputPath);
snapshot.Properties.TryGetValue(ConfigurationGeneral.MSBuildProjectFullPathProperty, out data.ProjectFilePath);

data.DisplayName = GetDisplayName(data.ProjectFilePath, project.ProjectConfiguration);

return data;
}

private static string GetDisplayName(string filePath, ProjectConfiguration projectConfiguration)
{
string displayName = Path.GetFileNameWithoutExtension(filePath);

// TODO: Multi-targeting
return $"{displayName} ({projectConfiguration.Name})";
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,71 @@
using System.Threading.Tasks.Dataflow;

using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Microsoft.VisualStudio.ProjectSystem.Properties;
using Microsoft.VisualStudio.ProjectSystem.Utilities;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices
{
partial class WorkspaceContextHost
internal partial class WorkspaceContextHost
{
private class WorkspaceContextHostInstance : AbstractProjectDynamicLoadInstance
private partial class WorkspaceContextHostInstance : AbstractProjectDynamicLoadInstance
{
private readonly ConfiguredProject _project;
private readonly IUnconfiguredProjectCommonServices _projectServices;
private readonly IProjectSubscriptionService _projectSubscriptionService;
private readonly ISafeProjectGuidService _projectGuidService;
private readonly Lazy<IWorkspaceProjectContextFactory> _workspaceProjectContextFactory;
private readonly Lazy<WorkspaceProjectContextCreator> _workspaceProjectContextCreator;
private readonly ExportFactory<IApplyChangesToWorkspaceContext> _applyChangesToWorkspaceContextFactory;
private readonly DisposableBag _subscriptions = new DisposableBag(CancellationToken.None);

private ExportLifetimeContext<IApplyChangesToWorkspaceContext> _applyChangesToWorkspaceContext;
private IWorkspaceProjectContext _context;
private DisposableBag _subscriptions = new DisposableBag(CancellationToken.None);


public WorkspaceContextHostInstance(ConfiguredProject project,
IUnconfiguredProjectCommonServices projectServices,
IProjectSubscriptionService projectSubscriptionService,
ISafeProjectGuidService projectGuidService,
Lazy<IWorkspaceProjectContextFactory> workspaceProjectContextFactory,
IProjectThreadingService threadingService,
Lazy<WorkspaceProjectContextCreator> workspaceProjectContextCreator,
ExportFactory<IApplyChangesToWorkspaceContext> applyChangesToWorkspaceContextFactory)
: base(projectServices.ThreadingService.JoinableTaskContext)
: base(threadingService.JoinableTaskContext)
{
_projectGuidService = projectGuidService;
_project = project;
_projectServices = projectServices;
_projectSubscriptionService = projectSubscriptionService;
_workspaceProjectContextFactory = workspaceProjectContextFactory;
_workspaceProjectContextCreator = workspaceProjectContextCreator;
_applyChangesToWorkspaceContextFactory = applyChangesToWorkspaceContextFactory;
}

internal async Task OnProjectChangedAsync(IProjectVersionedValue<IProjectSubscriptionUpdate> e)
{
if (IsDisposing || IsDisposed)
return;

var details = ProjectData.FromSnapshot(_project, e.Value.CurrentState[ConfigurationGeneral.SchemaName]);

await InitializeProjectContext(details).ConfigureAwait(true);

_context.BinOutputPath = details.BinOutputPath;
_context.DisplayName = details.DisplayName;
_context.ProjectFilePath = details.ProjectFilePath;
}

private async Task InitializeProjectContext(ProjectData details)
{
if (_context != null)
return;

_context = await _workspaceProjectContextCreator.Value.CreateProjectContext(details.LanguageName, details.BinOutputPath, details.ProjectFilePath)
.ConfigureAwait(true);

_applyChangesToWorkspaceContext = _applyChangesToWorkspaceContextFactory.CreateExport();
_applyChangesToWorkspaceContext.Value.Initialize(_context);

_subscriptions.AddDisposable(_project.Services.ProjectSubscription.JointRuleSource.SourceBlock.LinkTo(
new ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>(e => OnDesignTimeChanges(e)),
ruleNames: _applyChangesToWorkspaceContext.Value.GetDesignTimeRules(), suppressVersionOnlyUpdates: true));

_subscriptions.AddDisposable(_project.Services.ProjectSubscription.ProjectRuleSource.SourceBlock.LinkTo(
new ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>(e => OnEvaluationChanges(e)),
ruleNames: _applyChangesToWorkspaceContext.Value.GetEvaluationRules(), suppressVersionOnlyUpdates: true));
}

protected override Task DisposeCoreAsync(bool initialized)
{
_subscriptions.Dispose();
Expand All @@ -64,98 +93,20 @@ protected override Task InitializeCoreAsync(CancellationToken cancellationToken)
return Task.CompletedTask;
}

internal async Task OnProjectChangedAsync(IProjectVersionedValue<IProjectSubscriptionUpdate> e)
private void OnDesignTimeChanges(IProjectVersionedValue<IProjectSubscriptionUpdate> e)
{
if (IsDisposing || IsDisposed)
return;

var details = ProjectData.FromSnapshot(e.Value.CurrentState[ConfigurationGeneral.SchemaName]);

await InitializeProjectContext(details).ConfigureAwait(false);

// Was the project setup correctly?
if (_context == null)
return;

_context.BinOutputPath = details.BinOutputPath;
_context.DisplayName = details.DisplayName;
_context.ProjectFilePath = details.ProjectFilePath;
}

private async Task InitializeProjectContext(ProjectData details)
{
if (_context == null)
{
_context = await CreateProjectContextAsync(details).ConfigureAwait(false);

if (_context == null)
return;

_applyChangesToWorkspaceContext = _applyChangesToWorkspaceContextFactory.CreateExport();
_applyChangesToWorkspaceContext.Value.Initialize(_context);

_subscriptions.AddDisposable(_project.Services.ProjectSubscription.JointRuleSource.SourceBlock.LinkTo(
new ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>(e => OnDesignTimeChanges(e)),
ruleNames: _applyChangesToWorkspaceContext.Value.GetDesignTimeRules(), suppressVersionOnlyUpdates: true));

_subscriptions.AddDisposable(_project.Services.ProjectSubscription.ProjectRuleSource.SourceBlock.LinkTo(
new ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>(e => OnEvaluationChanges(e)),
ruleNames: _applyChangesToWorkspaceContext.Value.GetEvaluationRules(), suppressVersionOnlyUpdates: true));
}
}

private void OnDesignTimeChanges(IProjectVersionedValue<IProjectSubscriptionUpdate> e)
{
_applyChangesToWorkspaceContext.Value.ApplyDesignTime(e, true /* TODO: IsActiveContext */);
}

private void OnEvaluationChanges(IProjectVersionedValue<IProjectSubscriptionUpdate> e)
{
_applyChangesToWorkspaceContext.Value.ApplyEvaluation(e, true /* TODO: IsActiveContext */);
}

private async Task<IWorkspaceProjectContext> CreateProjectContextAsync(ProjectData details)
{
// Bail if our project doesn't have the right properties set
if (string.IsNullOrEmpty(details.LanguageName) || string.IsNullOrEmpty(details.BinOutputPath))
return null;

Guid projectGuid = await _projectGuidService.GetProjectGuidAsync()
.ConfigureAwait(false);

Assumes.False(projectGuid == Guid.Empty);

// Fire up the Roslyn "project"
return _workspaceProjectContextFactory.Value.CreateProjectContext(details.LanguageName, details.DisplayName, details.ProjectFilePath, projectGuid, _projectServices.Project.Services.HostObject, details.BinOutputPath);
}

private struct ProjectData
{
public string LanguageName;
public string BinOutputPath;
public string DisplayName;
public string ProjectFilePath;

public static ProjectData FromSnapshot(IProjectRuleSnapshot snapshot)
{
var data = new ProjectData();

snapshot.Properties.TryGetValue(ConfigurationGeneral.LanguageServiceNameProperty, out data.LanguageName);
snapshot.Properties.TryGetValue(ConfigurationGeneral.TargetPathProperty, out data.BinOutputPath);
snapshot.Properties.TryGetValue(ConfigurationGeneral.MSBuildProjectFullPathProperty, out data.ProjectFilePath);

data.DisplayName = GetDisplayName(data.ProjectFilePath);

return data;
}

public static string GetDisplayName(string filePath)
{
string displayName = Path.GetFileNameWithoutExtension(filePath);
if (IsDisposing || IsDisposed)
return;

// TODO: Multi-targeting
return displayName;
}
_applyChangesToWorkspaceContext.Value.ApplyEvaluation(e, true /* TODO: IsActiveContext */);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public WorkspaceContextHost(ConfiguredProject project,
}

[ConfiguredProjectAutoLoad]
[AppliesTo(ProjectCapability.CSharpOrVisualBasicOrFSharpLanguageService)]
[AppliesTo(ProjectCapability.DotNetLanguageService)]
public Task InitializeAsync()
{
return InitializeAsync(CancellationToken.None);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;

namespace Microsoft.VisualStudio.ProjectSystem.LanguageServices
{
internal partial class WorkspaceProjectContextCreator
{
private class NullWorkspaceProjectContext : IWorkspaceProjectContext
{
public static readonly IWorkspaceProjectContext Instance = new NullWorkspaceProjectContext();

public string DisplayName { get; set; }
public string ProjectFilePath { get; set; }
public Guid Guid { get; set; }
public bool LastDesignTimeBuildSucceeded { get; set; }
public string BinOutputPath { get; set; }

public void AddAdditionalFile(string filePath, bool isInCurrentContext = true)
{
}

public void AddAnalyzerReference(string referencePath)
{
}

public void AddMetadataReference(string referencePath, MetadataReferenceProperties properties)
{
}

public void AddProjectReference(IWorkspaceProjectContext project, MetadataReferenceProperties properties)
{
}

public void AddSourceFile(string filePath, bool isInCurrentContext = true, IEnumerable<string> folderNames = null, SourceCodeKind sourceCodeKind = SourceCodeKind.Regular)
{
}

public void Dispose()
{
}

public void RemoveAdditionalFile(string filePath)
{
}

public void RemoveAnalyzerReference(string referencePath)
{
}

public void RemoveMetadataReference(string referencePath)
{
}

public void RemoveProjectReference(IWorkspaceProjectContext project)
{
}

public void RemoveSourceFile(string filePath)
{
}

public void SetOptions(string commandLineForOptions)
{
}

public void SetRuleSetFile(string filePath)
{
}
}
}
}
Loading

0 comments on commit 51eaa93

Please sign in to comment.