Skip to content

Commit

Permalink
[VsIntegration] Move code for the ReferenceManager to separate class.…
Browse files Browse the repository at this point in the history
… ProjectNode now returns property VSHPROPID_ReferenceManagerUser which is used by the Toolkit to enumerate the references.

The ConvertToX#Runtime command now only uses the "common" api and no longer ProjectBase or XSharpCodeModel.
  • Loading branch information
RobertvanderHulst committed Dec 9, 2024
1 parent 735f2f2 commit 9b4a562
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 118 deletions.
65 changes: 23 additions & 42 deletions src/VisualStudio/ProjectPackage/Commands/CommandConvertXsRuntime.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using Community.VisualStudio.Toolkit;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Threading;
using System;
using XSharpModel;
using Task = System.Threading.Tasks.Task;
using System.Collections.Generic;
using Microsoft.VisualStudio.Project;

using System.Linq;
using Microsoft.VisualStudio.Shell.Interop;
namespace XSharp.Project
{
[Command(PackageIds.idConvertXSharpRuntime)]
Expand All @@ -23,13 +21,14 @@ private async Task CheckAvailabilityAsync()
Command.Visible = await Commands.ProjectIsXSharpProjectAsync();
if (Command.Visible)
{
var refs = await GetAssemblyReferencesAsync();
var project = await VS.Solutions.GetActiveProjectAsync();
var refs = project.References.Select(r => r.VsReference.FullPath);
bool isVulcan = false;
if (refs != null)
{
foreach (var asmref in refs)
{
if (asmref.FullName.Contains("Vulcan"))
if (asmref.Contains("Vulcan"))
{
isVulcan = true;
break;
Expand All @@ -39,26 +38,19 @@ private async Task CheckAvailabilityAsync()
Command.Visible = isVulcan;
}
}
async System.Threading.Tasks.Task<List<XAssembly>> GetAssemblyReferencesAsync()
{
var project = await VS.Solutions.GetActiveProjectAsync();
var path = project.FullPath;
var xsproject = XSolution.FindProjectByFileName(path);
if (xsproject != null)
{
return xsproject.AssemblyReferences;
}
return null;
}

protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
var toDelete = new List<string>();
var toAdd = new List<string>();
foreach (var asm in await GetAssemblyReferencesAsync())
var project = await VS.Solutions.GetActiveProjectAsync();
var refs = project.References.Select(r => r.VsReference.FullPath);
foreach (var asm in refs)
{
bool delete = true;
switch (System.IO.Path.GetFileName(asm.FileName).ToLower())
var name = System.IO.Path.GetFileName(asm).ToLower();
switch (name)
{
case VulcanRT:
toAdd.Add(XSharpCore);
Expand Down Expand Up @@ -99,42 +91,31 @@ protected override async Task ExecuteAsync(OleMenuCmdEventArgs e)
}
if (delete)
{
toDelete.Add(asm.FileName);
toDelete.Add(asm);
}
}
if (toDelete.Count == 0 || toAdd.Count == 0)
{
await VS.MessageBox.ShowErrorAsync("No Vulcan assemblies found in the project");
return;
}
var project = await VS.Solutions.GetActiveProjectAsync();
var path = project.FullPath;
var xsproject = XSolution.FindProjectByFileName(path);
var projectNode = (XSharpProjectNode)xsproject.ProjectNode;
var refContainer = projectNode.GetReferenceContainer() as XSharpReferenceContainerNode;
// Delete Vulcan items from the project
var referencesToDelete = new List<Reference>();
foreach (var item in toDelete)
{

var refnode = refContainer.FindChild(item);
if (refnode != null)
foreach (var node in project.References)
{
refnode.Remove(false);
xsproject.RemoveAssemblyReference(item);
}
}
// Add X# items to the project. Make sure to not add items that already exist.
foreach (var item in toAdd)
{
var refnode = refContainer.FindChild(item);
if (refnode == null)
{
refnode = new XSharpAssemblyReferenceNode(projectNode, item);
refContainer.AddChild(refnode);
if (string.Compare(node.VsReference.FullPath, item, StringComparison.OrdinalIgnoreCase) == 0)
{
referencesToDelete.Add(node);
}
}
}
// Let MsBuild figure out where the assemblies are
projectNode.Build(MsBuildTarget.ResolveAssemblyReferences);
await project.References.RemoveAsync(referencesToDelete.ToArray());
await project.References.AddAsync(toAdd.ToArray());
await VS.MessageBox.ShowAsync("The project was converted to the X# runtime successfully. Please recompile and test.",
icon: OLEMSGICON.OLEMSGICON_INFO,
buttons : OLEMSGBUTTON.OLEMSGBUTTON_OK);
}
#region Assembly names
internal const string VulcanRT = "vulcanrt.dll";
Expand Down
35 changes: 33 additions & 2 deletions src/VisualStudio/ProjectPackage/Nodes/XSharpProjectNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ namespace XSharp.Project
[Guid("F1A46976-964A-4A1E-955D-E05F5DB8651F")]
public partial class XSharpProjectNode : XProjectNode, IVsSingleFileGeneratorFactory, IXSharpProject,
/*IVsDesignTimeAssemblyResolution, */IVsProject5, IXsProjectDesigner
, IVsReferenceManagerUser
{
static List<XSharpProjectNode> nodes = new List<XSharpProjectNode>();

Expand Down Expand Up @@ -450,6 +449,7 @@ public override object GetProperty(int propId)
return this;
case (int)__VSHPROPID.VSHPROPID_DefaultNamespace:
return this.RootNameSpace;

case (int)__VSHPROPID5.VSHPROPID_OutputType:
return (uint)GetOutPutType();
case (int)__VSHPROPID2.VSHPROPID_DesignerHiddenCodeGeneration:
Expand All @@ -468,6 +468,9 @@ public override object GetProperty(int propId)
case (int)__VSHPROPID7.VSHPROPID_CanBuildQuickCheck:
case (int)__VSHPROPID7.VSHPROPID_CanDebugLaunchQuickCheck:
return _VSQuickCheckAnswer.QCA_Always;
case (int)__VSHPROPID5.VSHPROPID_ReferenceManagerUser:
return this.VsReferenceManager;

// Added for NuGet Support
case (int)__VSHPROPID8.VSHPROPID_ProjectCapabilitiesChecker:
if (_checker == null)
Expand Down Expand Up @@ -1221,7 +1224,35 @@ internal void RegisterFilesWithModel()
}
}
}

public override int AddProjectReference()
{
ThreadHelper.ThrowIfNotOnUIThread("AddProjectReference");
var referenceManager = this.GetService(typeof(SVsReferenceManager)) as IVsReferenceManager;
if (referenceManager != null)
{
string title = $"Reference Manager - {this.Caption}";
var contextGuids = new[] {
VSConstants.AssemblyReferenceProvider_Guid,
VSConstants.ProjectReferenceProvider_Guid,
//VSConstants.SharedProjectReferenceProvider_Guid,
VSConstants.ComReferenceProvider_Guid,
VSConstants.FileReferenceProvider_Guid,
};
referenceManager.ShowReferenceManager(
VsReferenceManager,
title,
"VS.AddReference",
contextGuids.First(),
fForceShowDefaultProvider: false
);
return VSConstants.S_OK;
}
else
{
return VSConstants.E_NOINTERFACE;
}
}
IVsReferenceManagerUser VsReferenceManager => new ProjectNodeReferenceManager(this);

internal void LoadPackageReferences()
{
Expand Down
Loading

0 comments on commit 9b4a562

Please sign in to comment.