Skip to content

Commit

Permalink
Upgrade Roslyn
Browse files Browse the repository at this point in the history
  • Loading branch information
aelij committed Oct 23, 2021
1 parent 6d97e24 commit a0849f2
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 102 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<Deterministic>True</Deterministic>
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
<EditorPackageVersion>1.3.0</EditorPackageVersion>
<RoslynPackageVersion>4.0.0-4.final</RoslynPackageVersion>
<RoslynPackageVersion>4.0.0-6.final</RoslynPackageVersion>
<RoslynAssemblyVersion>4.0.0.0</RoslynAssemblyVersion>
<AvaloniaVersion>0.10.7</AvaloniaVersion>
<DotNetVersion>[5.0.*,5.0.10]</DotNetVersion>
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RoslynPad is also available as NuGet packages which allow you to use Roslyn serv
|[![NuGet](https://img.shields.io/nuget/v/RoslynPad.Editor.Windows.svg?style=flat-square)](https://www.nuget.org/packages/RoslynPad.Editor.Windows) `RoslynPad.Editor.Windows`|Provides a Roslyn-based code editor using AvaloniaEdit (WPF platform) with completion, diagnostics, and quick actions|
|[![NuGet](https://img.shields.io/nuget/v/RoslynPad.Editor.Avalonia.svg?style=flat-square)](https://www.nuget.org/packages/RoslynPad.Editor.Avalonia) `RoslynPad.Editor.Avalonia`|Provides a Roslyn-based code editor using AvalonEdit (Avalonia platform) with completion, diagnostics, and quick actions|

`RoslynPad.Roslyn*` package versions will correspond to Roslyn's.
`RoslynPad.Roslyn*` package versions must correspond to Roslyn's.

[Code samples](https://github.com/aelij/RoslynPad/tree/master/samples)

Expand All @@ -32,7 +32,7 @@ Open `src\RoslynPad.sln` in Visual Studio 2019.

## Running the cross-platform .NET Core Avalonia version (on Mac or Linux)

* Install .NET Core Runtime 2.2
* Install .NET Core SDK 5.0
* Download and unzip `RoslynPadNetCore.zip`.
* Run `dotnet RoslynPad.dll`

Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "5.0.401"
"version": "5.0.402"
}
}
8 changes: 4 additions & 4 deletions src/RoslynPad.Build/ExecutionPlatform.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using NuGet.Versioning;

namespace RoslynPad.Build
{
public class ExecutionPlatform
{
internal string Name { get; }
internal string TargetFrameworkMoniker { get; }
internal Version? FrameworkVersion { get; }
internal NuGetVersion? FrameworkVersion { get; }
internal Architecture Architecture { get; }
internal bool IsCore { get; }
internal bool IsFramework => !IsCore;

internal ExecutionPlatform(string name, string targetFrameworkMoniker, Version? frameworkVersion, Architecture architecture, bool isCore)
internal ExecutionPlatform(string name, string targetFrameworkMoniker, NuGetVersion? frameworkVersion, Architecture architecture, bool isCore)
{
Name = name;
TargetFrameworkMoniker = targetFrameworkMoniker;
Expand Down
28 changes: 16 additions & 12 deletions src/RoslynPad.Build/ProcessUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,38 @@ public static async Task<ProcessResult> RunProcessAsync(string path, string work
RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false,
}
},
EnableRaisingEvents = true,
};

var exitTcs = new TaskCompletionSource<object?>();
process.Exited += (_, _) => exitTcs.TrySetResult(null);

using var _ = cancellationToken.Register(() =>
{
try { process.Kill(); }
try
{
exitTcs.TrySetCanceled();
process.Kill();
}
catch { }
});

await Task.Run(() => process.Start()).ConfigureAwait(false);

return new ProcessResult(process);
return new ProcessResult(process, exitTcs);
}

public class ProcessResult : IDisposable
{
private readonly Process _process;
private readonly TaskCompletionSource<object?> _exitTcs;
private readonly StringBuilder _standardOutput;

internal ProcessResult(Process process)
internal ProcessResult(Process process, TaskCompletionSource<object?> exitTcs)
{
_process = process;
_exitTcs = exitTcs;
_standardOutput = new StringBuilder();

_ = Task.Run(ReadStandardErrorAsync);
Expand All @@ -60,6 +70,7 @@ public async IAsyncEnumerable<string> GetStandardOutputLinesAsync()
var line = await output.ReadLineAsync().ConfigureAwait(false);
if (line == null)
{
await _exitTcs.Task.ConfigureAwait(false);
yield break;
}

Expand All @@ -71,14 +82,7 @@ public async IAsyncEnumerable<string> GetStandardOutputLinesAsync()
}
}

public int ExitCode
{
get
{
_process.WaitForExit();
return _process.ExitCode;
}
}
public int ExitCode => _process.ExitCode;

public string StandardOutput => _standardOutput.ToString();
public string? StandardError { get; private set; }
Expand Down
41 changes: 17 additions & 24 deletions src/RoslynPad.Common.UI/PlatformsFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,11 @@ internal class PlatformsFactory : IPlatformsFactory
private string? _dotnetExe;
private string? _sdkPath;

public event Action Changed = delegate { };

public IEnumerable<ExecutionPlatform> GetExecutionPlatforms()
{
if (GetCoreVersions() is var core)
foreach (var version in GetCoreVersions())
{
foreach (var version in core.versions)
{
if (Version.TryParse(version.name, out var parsedVersion))
{
yield return new ExecutionPlatform(".NET Core", version.tfm, parsedVersion, Architecture.X64, isCore: true);
}
}
yield return new ExecutionPlatform(version.name, version.tfm, version.verion, Architecture.X64, isCore: true);
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Expand All @@ -43,28 +35,29 @@ public IEnumerable<ExecutionPlatform> GetExecutionPlatforms()

public string DotNetExecutable => FindNetCore().dotnetExe;

private (IReadOnlyList<(string tfm, string name)> versions, string dotnetExe) GetCoreVersions()
private IReadOnlyList<(string name, string tfm, NuGetVersion verion)> GetCoreVersions()
{
var (dotnetExe, sdkPath) = FindNetCore();
var (_, sdkPath) = FindNetCore();

if (!string.IsNullOrEmpty(dotnetExe))
if (string.IsNullOrEmpty(sdkPath))
{
var dictionary = new Dictionary<NuGetVersion, (string tfm, string name)>();
return ImmutableArray<(string, string, NuGetVersion)>.Empty;
}

foreach (var directory in IOUtilities.EnumerateDirectories(sdkPath))
var versions = new List<(string name, string tfm, NuGetVersion version)>();

foreach (var directory in IOUtilities.EnumerateDirectories(sdkPath))
{
var versionName = Path.GetFileName(directory);
if (NuGetVersion.TryParse(versionName, out var version) && version.Major > 1)
{
var versionName = Path.GetFileName(directory);
if (NuGetVersion.TryParse(versionName, out var version) && version.Major > 1)
{
dictionary.Add(version, ($"netcoreapp{version.Major}.{version.Minor}", versionName));
}
var name = version.Major < 5 ? ".NET Core" : ".NET";
var tfm = version.Major < 5 ? $"netcoreapp{version.Major}.{version.Minor}" : $"net{version.Major}.{version.Minor}";
versions.Add((name, tfm, version));
}

return (dictionary.OrderBy(c => c.Key.IsPrerelease).ThenByDescending(c => c.Key).Select(c => c.Value).ToImmutableArray(),
dotnetExe);
}

return (ImmutableArray<(string, string)>.Empty, string.Empty);
return versions.OrderBy(c => c.version.IsPrerelease).ThenByDescending(c => c.version).ToImmutableArray();
}

private (string dotnetExe, string sdkPath) FindNetCore()
Expand Down
7 changes: 2 additions & 5 deletions src/RoslynPad.Common.UI/Services/IPlatformsFactory.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using RoslynPad.Build;

namespace RoslynPad.UI
Expand All @@ -9,7 +8,5 @@ internal interface IPlatformsFactory
IEnumerable<ExecutionPlatform> GetExecutionPlatforms();

string DotNetExecutable { get; }

event Action Changed;
}
}
}
3 changes: 1 addition & 2 deletions src/RoslynPad.Common.UI/ViewModels/OpenDocumentViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ public OpenDocumentViewModel(IServiceProvider serviceProvider, MainViewModelBase

_restoreSuccessful = true; // initially set to true so we can immediately start running and wait for restore
_dispatcher = appDispatcher;
_platformsFactory.Changed += InitializePlatforms;

OpenBuildPathCommand = commands.Create(() => OpenBuildPath());
SaveCommand = commands.CreateAsync(() => SaveAsync(promptSave: false));
Expand Down Expand Up @@ -274,7 +273,7 @@ private void AddRestoreResult(RestoreResultObject o)
lock (_results)
{
_restoreResults.Add(o);
AddRestoreResult(o);
AddResult(o);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
var position = context.Position;
var semanticModel = await originatingDocument.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false);
var service = originatingDocument.GetRequiredLanguageService<ISyntaxContextService>();
var solution = originatingDocument.Project.Solution;
var syntaxContext = service.CreateContext(solution.Workspace, semanticModel, position, cancellationToken);
var syntaxContext = service.CreateContext(originatingDocument, semanticModel, position, cancellationToken);
if (!syntaxContext.IsPreProcessorExpressionContext)
{
return;
Expand Down
8 changes: 4 additions & 4 deletions src/RoslynPad.Roslyn/Navigation/DocumentNavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ internal sealed class DocumentNavigationService : IDocumentNavigationService
public bool CanNavigateToSpan(Workspace workspace, DocumentId documentId, TextSpan textSpan, CancellationToken cancellationToken) => true;
public bool CanNavigateToLineAndOffset(Workspace workspace, DocumentId documentId, int lineNumber, int offset, CancellationToken cancellationToken) => true;
public bool CanNavigateToPosition(Workspace workspace, DocumentId documentId, int position, int virtualSpace, CancellationToken cancellationToken) => true;
public bool TryNavigateToSpan(Workspace workspace, DocumentId documentId, TextSpan textSpan, OptionSet options, bool allowInvalidSpan, CancellationToken cancellationToken) => true;
public bool TryNavigateToLineAndOffset(Workspace workspace, DocumentId documentId, int lineNumber, int offset, OptionSet options, CancellationToken cancellationToken) => true;
public bool TryNavigateToPosition(Workspace workspace, DocumentId documentId, int position, int virtualSpace, OptionSet options, CancellationToken cancellationToken) => true;
public Task<bool> CanNavigateToSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, CancellationToken cancellationToken) => Task.FromResult(true);
public Task<bool> TryNavigateToSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, OptionSet options, bool allowInvalidSpan, CancellationToken cancellationToken) => Task.FromResult(true);
public bool TryNavigateToSpan(Workspace workspace, DocumentId documentId, TextSpan textSpan, OptionSet? options, bool allowInvalidSpan, CancellationToken cancellationToken) => true;
public Task<bool> TryNavigateToSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, OptionSet? options, bool allowInvalidSpan, CancellationToken cancellationToken) => Task.FromResult(true);
public bool TryNavigateToLineAndOffset(Workspace workspace, DocumentId documentId, int lineNumber, int offset, OptionSet? options, CancellationToken cancellationToken) => true;
public bool TryNavigateToPosition(Workspace workspace, DocumentId documentId, int position, int virtualSpace, OptionSet? options, CancellationToken cancellationToken) => true;
}
}
3 changes: 1 addition & 2 deletions src/RoslynPad.Roslyn/QuickInfo/QuickInfoProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -164,7 +163,7 @@ private static bool ShouldCheckPreviousToken(SyntaxToken token)
}
}

var supportedPlatforms = new SupportedPlatformData(invalidProjects, candidateProjects, document.Project.Solution.Workspace);
var supportedPlatforms = new SupportedPlatformData(document.Project.Solution, invalidProjects, candidateProjects);
return await CreateContentAsync(document.Project.Solution.Workspace, token, bestBinding.Item2, bestBinding.Item3, supportedPlatforms, cancellationToken).ConfigureAwait(false);
}

Expand Down
47 changes: 4 additions & 43 deletions src/RoslynPad.Roslyn/Rename/RenameHelper.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Linq;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Rename;
using Microsoft.CodeAnalysis.Shared.Extensions;
Expand Down Expand Up @@ -62,56 +61,18 @@ public static class RenameHelper
// RenameOverloads option should be forced on.
var forceRenameOverloads = tokenRenameInfo.IsMemberGroup;

if (triggerToken.Parent != null && syntaxFactsService.IsTypeNamedVarInVariableOrFieldDeclaration(triggerToken, triggerToken.Parent))
{
// To check if var in this context is a real type, or the keyword, we need to
// speculatively bind the identifier "var". If it returns a symbol, it's a real type,
// if not, it's the keyword.
// see bugs 659683 (compiler API) and 659705 (rename/workspace api) for examples
var symbolForVar = semanticModel.GetSpeculativeSymbolInfo(
triggerToken.SpanStart,
triggerToken.Parent,
SpeculativeBindingOption.BindAsTypeOrNamespace).Symbol;

if (symbolForVar == null)
{
return null;
}
}

var symbol = await RenameLocations.ReferenceProcessing.TryGetRenamableSymbolAsync(document, triggerToken.SpanStart, cancellationToken: cancellationToken).ConfigureAwait(false);
if (symbol == null)
{
return null;
}

if (symbol.Kind == SymbolKind.Alias && symbol.IsExtern)
if (symbol.Kind == SymbolKind.Alias && symbol.IsExtern ||
triggerToken.IsTypeNamedDynamic() && symbol.Kind == SymbolKind.DynamicType)
{
return null;
}

// Cannot rename constructors in VB. TODO: this logic should be in the VB subclass of this type.
var workspace = document.Project.Solution.Workspace;
if (symbol.Kind == SymbolKind.NamedType &&
symbol.Language == LanguageNames.VisualBasic &&
triggerToken.ToString().Equals("New", StringComparison.OrdinalIgnoreCase))
{
var originalSymbol = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, triggerToken.SpanStart, workspace, cancellationToken: cancellationToken).ConfigureAwait(false);

if (originalSymbol != null && originalSymbol.IsConstructor())
{
return null;
}
}

if (syntaxFactsService.IsTypeNamedDynamic(triggerToken, triggerToken.Parent))
{
if (symbol.Kind == SymbolKind.DynamicType)
{
return null;
}
}

// we allow implicit locals and parameters of Event handlers
if (symbol.IsImplicitlyDeclared &&
symbol.Kind != SymbolKind.Local &&
Expand Down

0 comments on commit a0849f2

Please sign in to comment.