Skip to content

Commit

Permalink
Only build one project unless whole solution converted - fixes #816
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamTheCoder committed Jan 26, 2022
1 parent 69da5ad commit 21322d8
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Vsix

* Only trigger build for converted project where possible [#816](https://github.com/icsharpcode/CodeConverter/issues/816)

### VB -> C#

Expand Down
2 changes: 2 additions & 0 deletions CodeConverter.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CS/@EntryIndexedValue">CS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VB/@EntryIndexedValue">VB</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Exitable/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
15 changes: 7 additions & 8 deletions Vsix/CodeConversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
using System.Threading.Tasks;
using System.Windows;
using CodeConv.Shared.Util;
using ICSharpCode.CodeConverter;
using ICSharpCode.CodeConverter.Shared;
using ICSharpCode.CodeConverter.VB;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServices;
using Microsoft.VisualStudio.Shell;
Expand Down Expand Up @@ -58,7 +56,7 @@ public CodeConversion(IAsyncServiceProvider serviceProvider,
public async Task ConvertProjectsAsync<TLanguageConversion>(IReadOnlyCollection<Project> selectedProjects, CancellationToken cancellationToken) where TLanguageConversion : ILanguageConversion, new()
{
try {
await EnsureBuiltAsync();
await EnsureBuiltAsync(selectedProjects);
await _joinableTaskFactory.RunAsync(async () => {
var convertedFiles = ConvertProjectUnhandled<TLanguageConversion>(selectedProjects, cancellationToken);
await WriteConvertedFilesAndShowSummaryAsync(convertedFiles);
Expand All @@ -73,7 +71,8 @@ await _joinableTaskFactory.RunAsync(async () => {
public async Task ConvertDocumentAsync<TLanguageConversion>(string documentFilePath, Span selected, CancellationToken cancellationToken) where TLanguageConversion : ILanguageConversion, new()
{
try {
await EnsureBuiltAsync();
var containingProject = await VisualStudioInteraction.GetFirstProjectContainingAsync(documentFilePath);
await EnsureBuiltAsync(containingProject is null ? Array.Empty<Project>() : new[]{containingProject});
var conversionResult = await _joinableTaskFactory.RunAsync(async () => {
var result = await ConvertDocumentUnhandledAsync<TLanguageConversion>(documentFilePath, selected, cancellationToken);
await WriteConvertedFilesAndShowSummaryAsync(new[] { result }.ToAsyncEnumerable());
Expand All @@ -96,9 +95,9 @@ await _joinableTaskFactory.RunAsync(async () => {
/// https://github.com/icsharpcode/CodeConverter/issues/592
/// https://github.com/dotnet/roslyn/issues/6615
/// </remarks>
private async Task EnsureBuiltAsync()
private async Task EnsureBuiltAsync(IReadOnlyCollection<Project> readOnlyCollection)
{
await VisualStudioInteraction.EnsureBuiltAsync(m => _outputWindow.WriteToOutputWindowAsync(m));
await VisualStudioInteraction.EnsureBuiltAsync(readOnlyCollection, m => _outputWindow.WriteToOutputWindowAsync(m));
}

private static async Task SetClipboardTextOnUiThreadAsync(string conversionResultConvertedCode)
Expand Down Expand Up @@ -233,8 +232,8 @@ private async Task<string> GetConversionSummaryAsync(IReadOnlyCollection<string>
{
await _outputWindow.WriteToOutputWindowAsync($"Converting {documentPath}...", true, true);

//TODO Figure out when there are multiple document ids for a single file path
var documentId = _visualStudioWorkspace.CurrentSolution.GetDocumentIdsWithFilePath(documentPath).SingleOrDefault();
// If multiple projects contain this file path, there may be multiple ids, but in that the wrong project may have been built too...
var documentId = _visualStudioWorkspace.CurrentSolution.GetDocumentIdsWithFilePath(documentPath).FirstOrDefault();
if (documentId == null) {
//If document doesn't belong to any project
await _outputWindow.WriteToOutputWindowAsync("File is not part of a compiling project, using best effort text conversion (less accurate).");
Expand Down
20 changes: 17 additions & 3 deletions Vsix/VisualStudioInteraction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,21 @@ public static async Task<bool> ShowMessageBoxAsync(IAsyncServiceProvider service
return userAnswer == MessageBoxResult.OK;
}

public static async Task EnsureBuiltAsync(Func<string, Task> writeMessageAsync)
public static async Task EnsureBuiltAsync(IReadOnlyCollection<Project> projects, Func<string, Task> writeMessageAsync)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(CancelAllToken);
var build = Dte.Solution.SolutionBuild;
if (build.BuildState == vsBuildState.vsBuildStateInProgress) {
throw new InvalidOperationException("Build in progress, please wait for it to complete before conversion.");
}
await writeMessageAsync("Building solution prior to conversion for maximum accuracy...");
build.Build(true);
if (projects.Count == 1 && build.ActiveConfiguration?.Name is { } configuration && projects.Single().UniqueName is {} uniqueName) {
await writeMessageAsync($"Building project '{uniqueName}' prior to conversion for maximum accuracy...");
build.BuildProject(configuration, uniqueName);
} else {
await writeMessageAsync("Building solution prior to conversion for maximum accuracy...");
build.Build(true);
}

await TaskScheduler.Default;
}

Expand Down Expand Up @@ -236,6 +242,14 @@ public static async Task<CaretPosition> GetCaretPositionAsync(IAsyncServiceProvi
return caretPositionAsync;
}

public static async Task<Project> GetFirstProjectContainingAsync(string documentFilePath)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(CancelAllToken);
var containingProject = Dte.Solution.FindProjectItem(documentFilePath)?.ContainingProject;
await TaskScheduler.Default;
return containingProject;
}

internal class CaretPosition
{
private readonly ITextEdit _textEdit;
Expand Down

0 comments on commit 21322d8

Please sign in to comment.