From fc040b27609878ef47a9373c0c95eb5695971adc Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Mon, 16 Dec 2019 16:15:17 -0800 Subject: [PATCH 001/222] Add an empty console application that will hold the LSIF generator --- Roslyn.sln | 7 +++++++ .../Microsoft.CodeAnalysis.Lsif.Generator.csproj | 15 +++++++++++++++ src/Features/Lsif/Generator/Program.cs | 11 +++++++++++ src/Features/Lsif/Generator/README.md | 1 + 4 files changed, 34 insertions(+) create mode 100644 src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj create mode 100644 src/Features/Lsif/Generator/Program.cs create mode 100644 src/Features/Lsif/Generator/README.md diff --git a/Roslyn.sln b/Roslyn.sln index 6f27a2d84dbde..5614e696f1a61 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -422,6 +422,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompilersIOperationGenerator", "src\Tools\Source\CompilerGeneratorTools\Source\IOperationGenerator\CompilersIOperationGenerator.csproj", "{D55FB2BD-CC9E-454B-9654-94AF5D910BF7}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Lsif.Generator", "src\Features\Lsif\Generator\Microsoft.CodeAnalysis.Lsif.Generator.csproj", "{B9899CF1-E0EB-4599-9E24-6939A04B4979}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{1ee8cad3-55f9-4d91-96b2-084641da9a6c}*SharedItemsImports = 5 @@ -1123,6 +1125,10 @@ Global {D55FB2BD-CC9E-454B-9654-94AF5D910BF7}.Debug|Any CPU.Build.0 = Debug|Any CPU {D55FB2BD-CC9E-454B-9654-94AF5D910BF7}.Release|Any CPU.ActiveCfg = Release|Any CPU {D55FB2BD-CC9E-454B-9654-94AF5D910BF7}.Release|Any CPU.Build.0 = Release|Any CPU + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.ActiveCfg = Debug|x64 + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.Build.0 = Debug|x64 + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.ActiveCfg = Release|x64 + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1318,6 +1324,7 @@ Global {CE7F7553-DB2D-4839-92E3-F042E4261B4E} = {8DBA5174-B0AA-4561-82B1-A46607697753} {FF38E9C9-7A25-44F0-B2C4-24C9BFD6A8F6} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {D55FB2BD-CC9E-454B-9654-94AF5D910BF7} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} + {B9899CF1-E0EB-4599-9E24-6939A04B4979} = {3E5FE3DB-45F7-4D83-9097-8F05D3B3AEC6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {604E6B91-7BC0-4126-AE07-D4D2FEFC3D29} diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj new file mode 100644 index 0000000000000..0c6c274721565 --- /dev/null +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -0,0 +1,15 @@ + + + + + x64 + x64 + x64 + Exe + Microsoft.CodeAnalysis.Lsif.Generator + True + netcoreapp3.0 + $(RoslynPortableRuntimeIdentifiers) + enable + + \ No newline at end of file diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs new file mode 100644 index 0000000000000..060ef91bd31c0 --- /dev/null +++ b/src/Features/Lsif/Generator/Program.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator +{ + internal static class Program + { + public static void Main(string[] args) + { + } + } +} diff --git a/src/Features/Lsif/Generator/README.md b/src/Features/Lsif/Generator/README.md new file mode 100644 index 0000000000000..790c3c2e49672 --- /dev/null +++ b/src/Features/Lsif/Generator/README.md @@ -0,0 +1 @@ +This tool consumes a project or solution and generates a Language Server Index Format file per the [LSIF specification](https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md). \ No newline at end of file From fafc11e36a800e934aeae26422711ee626938c19 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 10:49:02 -0800 Subject: [PATCH 002/222] Add command line parsing and handling for output and log files --- eng/Versions.props | 4 +- src/Features/Lsif/Generator/.editorconfig | 5 ++ ...crosoft.CodeAnalysis.Lsif.Generator.csproj | 7 +++ src/Features/Lsif/Generator/Program.cs | 47 ++++++++++++++++++- 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/Features/Lsif/Generator/.editorconfig diff --git a/eng/Versions.props b/eng/Versions.props index 2fe0eb0c0c8ca..6fa546d6179c0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -41,7 +41,6 @@ 0.9.3 0.11.4 - 2.0.273-beta 1.4.4 17.144.28413-buildid7983345 8.0.2 @@ -179,8 +178,7 @@ 0.0.4 1.0.21 4.5.0 - 0.1.0-alpha-63729-01 - 0.1.0-alpha-63729-01 + 0.3.0-alpha.19577.1 4.5.0 4.5.0 4.3.0 diff --git a/src/Features/Lsif/Generator/.editorconfig b/src/Features/Lsif/Generator/.editorconfig new file mode 100644 index 0000000000000..b79fad3bd5c9c --- /dev/null +++ b/src/Features/Lsif/Generator/.editorconfig @@ -0,0 +1,5 @@ +# This .editorconfig customizes some diagnostic rules that are specific to this project. + +[*.cs] +dotnet_diagnostic.CA2007.severity = none # Disable warnings about ConfigureAwait, since this is a console app +dotnet_diagnostic.VSTHRD111.severity = none # Disable warnings about ConfigureAwait, since this is a console app \ No newline at end of file diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj index 0c6c274721565..291d121a5d973 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -12,4 +12,11 @@ $(RoslynPortableRuntimeIdentifiers) enable + + + + + + + \ No newline at end of file diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 060ef91bd31c0..fbdcac40d4e77 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -1,11 +1,56 @@ // 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.CommandLine; +using System.CommandLine.Builder; +using System.CommandLine.Invocation; +using System.IO; +using System.Threading.Tasks; + namespace Microsoft.CodeAnalysis.Lsif.Generator { internal static class Program { - public static void Main(string[] args) + public static Task Main(string[] args) + { + var generateCommand = new RootCommand("generates an LSIF file") + { + new Option("--output", "file to write the LSIF output to, instead of the console") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() }, + new Option("--log", "file to write a log to") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() } + }; + + generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); + + return generateCommand.InvokeAsync(args); + } + + private static async Task GenerateAsync(string? output, string? log) + { + // If we have an output file, we'll write to that, else we'll use Console.Out + using StreamWriter? outputFile = output != null ? new StreamWriter(output) : null; + TextWriter outputWriter = outputFile ?? Console.Out; + + using TextWriter logFile = log != null ? new StreamWriter(log) : TextWriter.Null; + + try + { + await GenerateAsync(outputWriter, logFile); + } + catch (Exception e) + { + // If it failed, write out to the logs and error, but propagate the error too + var message = "Unhandled exception: " + e.ToString(); + await logFile.WriteLineAsync(message); + Console.Error.WriteLine(message); + throw; + } + + await logFile.WriteLineAsync("Generation complete."); + } + + private static Task GenerateAsync(TextWriter outputWriter, TextWriter logFile) { + return Task.CompletedTask; } } } From d553cdc1a1bfee53e259b929b8fd866789c5912f Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 12:41:32 -0800 Subject: [PATCH 003/222] Support loading solutions with MSBuildWorkspace This switches the tool back to a .NET Framework executable to avoid using .NET Core msbuild, since that might have some compat issues we will need to sort out on some repositories. --- Roslyn.sln | 8 ++--- ...crosoft.CodeAnalysis.Lsif.Generator.csproj | 15 ++++++---- src/Features/Lsif/Generator/Program.cs | 30 +++++++++++++++---- src/Features/Lsif/Generator/Utilities.cs | 14 +++++++++ 4 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 src/Features/Lsif/Generator/Utilities.cs diff --git a/Roslyn.sln b/Roslyn.sln index 5614e696f1a61..5cbe0325d90b7 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -1125,10 +1125,10 @@ Global {D55FB2BD-CC9E-454B-9654-94AF5D910BF7}.Debug|Any CPU.Build.0 = Debug|Any CPU {D55FB2BD-CC9E-454B-9654-94AF5D910BF7}.Release|Any CPU.ActiveCfg = Release|Any CPU {D55FB2BD-CC9E-454B-9654-94AF5D910BF7}.Release|Any CPU.Build.0 = Release|Any CPU - {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.ActiveCfg = Debug|x64 - {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.Build.0 = Debug|x64 - {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.ActiveCfg = Release|x64 - {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.Build.0 = Release|x64 + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj index 291d121a5d973..ca9b01590541d 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -2,21 +2,26 @@ - x64 - x64 - x64 + AnyCPU Exe Microsoft.CodeAnalysis.Lsif.Generator - True - netcoreapp3.0 + true + net472 + AnyCPU $(RoslynPortableRuntimeIdentifiers) enable + + + + + + \ No newline at end of file diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index fbdcac40d4e77..aa770afaace2e 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -4,8 +4,11 @@ using System.CommandLine; using System.CommandLine.Builder; using System.CommandLine.Invocation; +using System.Diagnostics; using System.IO; using System.Threading.Tasks; +using Microsoft.Build.Locator; +using Microsoft.CodeAnalysis.MSBuild; namespace Microsoft.CodeAnalysis.Lsif.Generator { @@ -15,16 +18,17 @@ public static Task Main(string[] args) { var generateCommand = new RootCommand("generates an LSIF file") { + new Option("--solution", "input solution file") { Argument = new Argument().ExistingOnly(), Required = true }, new Option("--output", "file to write the LSIF output to, instead of the console") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() }, new Option("--log", "file to write a log to") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() } }; - generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); + generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); return generateCommand.InvokeAsync(args); } - private static async Task GenerateAsync(string? output, string? log) + private static async Task GenerateAsync(FileInfo solution, string? output, string? log) { // If we have an output file, we'll write to that, else we'll use Console.Out using StreamWriter? outputFile = output != null ? new StreamWriter(output) : null; @@ -34,7 +38,7 @@ private static async Task GenerateAsync(string? output, string? log) try { - await GenerateAsync(outputWriter, logFile); + await GenerateAsync(solution, outputWriter, logFile); } catch (Exception e) { @@ -48,9 +52,25 @@ private static async Task GenerateAsync(string? output, string? log) await logFile.WriteLineAsync("Generation complete."); } - private static Task GenerateAsync(TextWriter outputWriter, TextWriter logFile) + private static async Task GenerateAsync(FileInfo solutionFile, TextWriter outputWriter, TextWriter logFile) { - return Task.CompletedTask; + await logFile.WriteLineAsync($"Loading {solutionFile.FullName}..."); + + var solutionLoadStopwatch = Stopwatch.StartNew(); + + MSBuildLocator.RegisterDefaults(); + var msbuildWorkspace = MSBuildWorkspace.Create(); + var solution = await msbuildWorkspace.OpenSolutionAsync(solutionFile.FullName); + + await logFile.WriteLineAsync($"Load of the solution completed in {solutionLoadStopwatch.ToDisplayString()}."); + + foreach (var project in solution.Projects) + { + var compilationCreationStopwatch = Stopwatch.StartNew(); + var compilation = await project.GetCompilationAsync(); + + await logFile.WriteLineAsync($"Fetch of compilation for {project.FilePath} completed in {compilationCreationStopwatch.ToDisplayString()}."); + } } } } diff --git a/src/Features/Lsif/Generator/Utilities.cs b/src/Features/Lsif/Generator/Utilities.cs new file mode 100644 index 0000000000000..3708f276dfe25 --- /dev/null +++ b/src/Features/Lsif/Generator/Utilities.cs @@ -0,0 +1,14 @@ +// 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.Diagnostics; + +namespace Microsoft.CodeAnalysis.Lsif.Generator +{ + internal static class Utilities + { + public static string ToDisplayString(this Stopwatch stopwatch) + { + return stopwatch.Elapsed.TotalSeconds.ToString("N2") + " second(s)"; + } + } +} From 324010b3042abbdc3ed9f5fa7f86c5b78884296d Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 14:29:46 -0800 Subject: [PATCH 004/222] Emit project vertices and the appropriate events --- src/Features/Lsif/Generator/Generator.cs | 40 +++++++++ .../Lsif/Generator/LsifGraph/Element.cs | 21 +++++ .../Lsif/Generator/LsifGraph/Event.cs | 35 ++++++++ src/Features/Lsif/Generator/LsifGraph/Id.cs | 83 +++++++++++++++++++ .../Lsif/Generator/LsifGraph/Project.cs | 24 ++++++ .../Lsif/Generator/LsifGraph/Vertex.cs | 15 ++++ ...crosoft.CodeAnalysis.Lsif.Generator.csproj | 1 + src/Features/Lsif/Generator/Program.cs | 17 +++- .../Lsif/Generator/Writing/ILsifJsonWriter.cs | 11 +++ .../Generator/Writing/TextLsifJsonWriter.cs | 78 +++++++++++++++++ 10 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 src/Features/Lsif/Generator/Generator.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/Element.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/Event.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/Id.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/Project.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/Vertex.cs create mode 100644 src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs create mode 100644 src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs new file mode 100644 index 0000000000000..170b396f8cafd --- /dev/null +++ b/src/Features/Lsif/Generator/Generator.cs @@ -0,0 +1,40 @@ +// 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.Threading.Tasks; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.Lsif.Generator.Writing; + +namespace Microsoft.CodeAnalysis.Lsif.Generator +{ + internal sealed class Generator + { + private readonly ILsifJsonWriter _lsifJsonWriter; + + public Generator(ILsifJsonWriter lsifJsonWriter) + { + _lsifJsonWriter = lsifJsonWriter; + } + + public Task GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) + { + var projectVertex = new LsifGraph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath)); + _lsifJsonWriter.Write(projectVertex); + _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, projectVertex.GetId())); + _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); + + return Task.CompletedTask; + } + + private static string GetLanguageKind(string languageName) + { + return languageName switch + { + LanguageNames.CSharp => "csharp", + LanguageNames.VisualBasic => "vb", + _ => throw new NotSupportedException(languageName), + }; + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Element.cs b/src/Features/Lsif/Generator/LsifGraph/Element.cs new file mode 100644 index 0000000000000..3e604ccb89a99 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Element.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// The base class of an element in the LSIF format. + /// + internal abstract class Element + { + public Id Id { get; } + public string Type { get; } + public string Label { get; } + + protected Element(string type, string label) + { + this.Id = Id.Create(); + this.Label = label; + this.Type = type; + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Event.cs b/src/Features/Lsif/Generator/LsifGraph/Event.cs new file mode 100644 index 0000000000000..419d9801c6173 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Event.cs @@ -0,0 +1,35 @@ +// 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; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// Represents an event. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#events for further details. + /// + internal sealed class Event : Vertex + { + public string Kind { get; } + public string Scope { get; } + public Id Data { get; } + + private Event(EventKind kind, string scope, Id data) + : base(label: "$event") + { + this.Kind = kind switch { EventKind.Begin => "begin", EventKind.End => "end", _ => throw new ArgumentException(nameof(kind)) }; + this.Scope = scope; + this.Data = data; + } + + public Event(EventKind kind, Id data) + : this(kind, "project", data.As()) + { + } + + public enum EventKind + { + Begin, + End + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Id.cs b/src/Features/Lsif/Generator/LsifGraph/Id.cs new file mode 100644 index 0000000000000..512785c8c469b --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Id.cs @@ -0,0 +1,83 @@ +// 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.Threading; +using Newtonsoft.Json; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// Represents an ID of a vertex or edge. + /// + /// Used to distinguish what type of object this ID applies to. This is not actually used, but simply helps + /// to ensure type safety since it's not uncommon to hold onto just an ID somewhere. + internal struct Id : IEquatable>, ISerializableId where T : Element + { + /// + /// The next numberic ID that will be used for an object. Accessed only with Interlocked.Increment. + /// + private static int s_globalId = 0; + + public Id(int id) + { + NumericId = id; + } + + public int NumericId { get; } + + public static Id Create() + { + var id = Interlocked.Increment(ref s_globalId); + return new Id(id); + } + + public override bool Equals(object? obj) + { + return obj is Id other && Equals(other); + } + + public bool Equals(Id other) + { + return other.NumericId == NumericId; + } + + public override int GetHashCode() + { + return NumericId.GetHashCode(); + } + + public static bool operator ==(Id left, Id right) + { + return left.Equals(right); + } + + public static bool operator !=(Id left, Id right) + { + return !(left == right); + } + } + + interface ISerializableId + { + public int NumericId { get; } + } + + internal static class IdExtensions + { + /// + /// "Casts" a strongly type ID representing a derived type to a base type. + /// + public static Id As(this Id id) where TOut : Element where TIn : TOut + { + return new Id(id.NumericId); + } + + /// + /// Fetches a strongly-typed for a given element. + /// + public static Id GetId(this T element) where T : Element + { + return new Id(element.Id.NumericId); + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Project.cs b/src/Features/Lsif/Generator/LsifGraph/Project.cs new file mode 100644 index 0000000000000..45e511b2c6306 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Project.cs @@ -0,0 +1,24 @@ +// 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; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// Represents a top-level project. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex for further details. + /// + internal sealed class Project : Vertex + { + public string Kind { get; } + public Uri? Resource { get; } + public string? Contents { get; } + + public Project(string kind, Uri? resource = null, string? contents = null) + : base(label: "project") + { + Kind = kind; + Resource = resource; + Contents = contents; + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Vertex.cs b/src/Features/Lsif/Generator/LsifGraph/Vertex.cs new file mode 100644 index 0000000000000..5ba035a321000 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Vertex.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// The base class of any vertex in the graph. + /// + internal abstract class Vertex : Element + { + protected Vertex(string label) + : base(type: "vertex", label) + { + } + } +} diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj index ca9b01590541d..f1d2d7edf837a 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index aa770afaace2e..f72e810d5a9e9 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -8,6 +8,7 @@ using System.IO; using System.Threading.Tasks; using Microsoft.Build.Locator; +using Microsoft.CodeAnalysis.Lsif.Generator.Writing; using Microsoft.CodeAnalysis.MSBuild; namespace Microsoft.CodeAnalysis.Lsif.Generator @@ -64,12 +65,22 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output await logFile.WriteLineAsync($"Load of the solution completed in {solutionLoadStopwatch.ToDisplayString()}."); + using var lsifWriter = new TextLsifJsonWriter(outputWriter); + var lsifGenerator = new Generator(lsifWriter); + foreach (var project in solution.Projects) { - var compilationCreationStopwatch = Stopwatch.StartNew(); - var compilation = await project.GetCompilationAsync(); + if (project.SupportsCompilation && project.FilePath != null) + { + var compilationCreationStopwatch = Stopwatch.StartNew(); + var compilation = (await project.GetCompilationAsync())!; + + await logFile.WriteLineAsync($"Fetch of compilation for {project.FilePath} completed in {compilationCreationStopwatch.ToDisplayString()}."); - await logFile.WriteLineAsync($"Fetch of compilation for {project.FilePath} completed in {compilationCreationStopwatch.ToDisplayString()}."); + var generationForProjectStopwatch = Stopwatch.StartNew(); + await lsifGenerator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices); + await logFile.WriteLineAsync($"Generation for {project.FilePath} completed in {generationForProjectStopwatch.ToDisplayString()}."); + } } } } diff --git a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs new file mode 100644 index 0000000000000..bd3599aaae1af --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs @@ -0,0 +1,11 @@ +// 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 Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +{ + internal interface ILsifJsonWriter + { + void Write(Vertex vertex); + } +} diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs new file mode 100644 index 0000000000000..94a8b10132afb --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs @@ -0,0 +1,78 @@ +// 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.IO; +using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +{ + internal sealed class TextLsifJsonWriter : ILsifJsonWriter, IDisposable + { + private readonly JsonTextWriter _jsonTextWriter; + private readonly JsonSerializer _jsonSerializer; + + public TextLsifJsonWriter(TextWriter outputWriter) + { + _jsonTextWriter = new JsonTextWriter(outputWriter); + _jsonTextWriter.WriteStartArray(); + + var settings = new JsonSerializerSettings + { + Formatting = Newtonsoft.Json.Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore, + ContractResolver = new CamelCasePropertyNamesContractResolver(), + TypeNameHandling = TypeNameHandling.None, + Converters = new[] { new LsifConverter() } + }; + + _jsonSerializer = JsonSerializer.Create(settings); + } + + public void Write(Vertex vertex) + { + _jsonSerializer.Serialize(_jsonTextWriter, vertex); + } + + public void Dispose() + { + _jsonTextWriter.WriteEndArray(); + _jsonTextWriter.Close(); + } + + internal class LsifConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return typeof(ISerializableId).IsAssignableFrom(objectType) || + objectType == typeof(Uri); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + switch (value) + { + case ISerializableId id: + + writer.WriteValue(id.NumericId); + break; + + case Uri uri: + + writer.WriteValue(uri.AbsoluteUri); + break; + + default: + + throw new NotSupportedException(); + } + } + } + } +} From e8ae2cfce9ffc5c5d0a983fb3b9e9b74a5522544 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 15:24:22 -0800 Subject: [PATCH 005/222] Write document vertices for each source file --- src/Features/Lsif/Generator/Generator.cs | 27 +++++++++- .../Lsif/Generator/LsifGraph/Document.cs | 21 ++++++++ src/Features/Lsif/Generator/LsifGraph/Edge.cs | 50 +++++++++++++++++++ .../Lsif/Generator/LsifGraph/Event.cs | 5 ++ .../Lsif/Generator/Writing/ILsifJsonWriter.cs | 1 + .../Generator/Writing/TextLsifJsonWriter.cs | 5 ++ 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/Features/Lsif/Generator/LsifGraph/Document.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/Edge.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 170b396f8cafd..cc839a2a9600d 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -1,6 +1,7 @@ // 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 System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; @@ -17,14 +18,36 @@ public Generator(ILsifJsonWriter lsifJsonWriter) _lsifJsonWriter = lsifJsonWriter; } - public Task GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) + public async Task GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) { var projectVertex = new LsifGraph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath)); _lsifJsonWriter.Write(projectVertex); _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, projectVertex.GetId())); + + var documentIds = new List>(); + + foreach (var syntaxTree in compilation.SyntaxTrees) + { + var semanticModel = compilation.GetSemanticModel(syntaxTree); + + documentIds.Add(await GenerateForDocument(semanticModel, languageServices)); + } + + _lsifJsonWriter.Write(Edge.Create("contains", projectVertex.GetId(), documentIds)); + _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); + } + + private Task> GenerateForDocument(SemanticModel semanticModel, HostLanguageServices languageServices) + { + var syntaxTree = semanticModel.SyntaxTree; + var documentVertex = new LsifGraph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); + + _lsifJsonWriter.Write(documentVertex); + _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); + _lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId())); - return Task.CompletedTask; + return Task.FromResult(documentVertex.GetId()); } private static string GetLanguageKind(string languageName) diff --git a/src/Features/Lsif/Generator/LsifGraph/Document.cs b/src/Features/Lsif/Generator/LsifGraph/Document.cs new file mode 100644 index 0000000000000..72dea15e86a18 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Document.cs @@ -0,0 +1,21 @@ +// 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; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + internal sealed class Document : Vertex + { + public Uri Uri { get; } + public string LanguageId { get; } + public string? Contents { get; } + + public Document(Uri uri, string languageId, string? contents = null) + : base(label: "document") + { + this.Uri = uri; + this.LanguageId = languageId; + this.Contents = contents; + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Edge.cs b/src/Features/Lsif/Generator/LsifGraph/Edge.cs new file mode 100644 index 0000000000000..845038e1ec3d5 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Edge.cs @@ -0,0 +1,50 @@ +// 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.Collections.Generic; +using Newtonsoft.Json; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// Represents an edge from one vertex to another. + /// + internal sealed class Edge : Element + { + [JsonProperty("outV")] + public Id OutVertex { get; } + + // The LSIF format allows both for a one-to-one edge and a one-to-many edge. We'll just always use a one-to-many edge when + // emitting since the format isn't really that much larger but keeps everything much simpler. + [JsonProperty("inVs")] + public Id[] InVertices { get; } + + public Edge(string label, Id outVertex, Id[] inVertices) + : base(type: "edge", label: label) + { + OutVertex = outVertex; + InVertices = inVertices; + } + + public static Edge Create(string label, Id outVertex, Id inVertex) where TOutVertex : Vertex where TInVertex : Vertex + { + var inVerticesArray = new Id[1]; + inVerticesArray[0] = inVertex.As(); + + return new Edge(label, outVertex.As(), inVerticesArray); + } + + public static Edge Create(string label, Id outVertex, IList> inVertices) where TOutVertex : Vertex where TInVertex : Vertex + { + var inVerticesArray = new Id[inVertices.Count]; + + // Note: this is ultimately just an array copy, but in a strongly-typed way. The JIT might see through this as a memory copy, + // but might require some more explicit code if not. + for (int i = 0; i < inVertices.Count; i++) + { + inVerticesArray[i] = inVertices[i].As(); + } + + return new Edge(label, outVertex.As(), inVerticesArray); + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Event.cs b/src/Features/Lsif/Generator/LsifGraph/Event.cs index 419d9801c6173..f37dc31e30850 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Event.cs +++ b/src/Features/Lsif/Generator/LsifGraph/Event.cs @@ -26,6 +26,11 @@ public Event(EventKind kind, Id data) { } + public Event(EventKind kind, Id data) + : this(kind, "document", data.As()) + { + } + public enum EventKind { Begin, diff --git a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs index bd3599aaae1af..2503cfa90ce66 100644 --- a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs @@ -7,5 +7,6 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing internal interface ILsifJsonWriter { void Write(Vertex vertex); + void Write(Edge edge); } } diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs index 94a8b10132afb..ada6c766a161d 100644 --- a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs @@ -35,6 +35,11 @@ public void Write(Vertex vertex) _jsonSerializer.Serialize(_jsonTextWriter, vertex); } + public void Write(Edge edge) + { + _jsonSerializer.Serialize(_jsonTextWriter, edge); + } + public void Dispose() { _jsonTextWriter.WriteEndArray(); From 294d627fb6f04477217814dfea9cb3d2a6039477 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 16:22:02 -0800 Subject: [PATCH 006/222] Write out ranges for all bindable tokens This is doing the binding, but isn't actually writing out anything interesting with it yet. --- src/Features/Lsif/Generator/Generator.cs | 31 ++++++++++++++++++ .../Lsif/Generator/LsifGraph/Range.cs | 32 +++++++++++++++++++ ...crosoft.CodeAnalysis.Lsif.Generator.csproj | 1 + .../Microsoft.CodeAnalysis.Workspaces.csproj | 1 + 4 files changed, 65 insertions(+) create mode 100644 src/Features/Lsif/Generator/LsifGraph/Range.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index cc839a2a9600d..63f72fca11c23 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; +using System.CommandLine; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; using Microsoft.CodeAnalysis.Lsif.Generator.Writing; @@ -41,10 +43,39 @@ public async Task GenerateForCompilation(Compilation compilation, string project private Task> GenerateForDocument(SemanticModel semanticModel, HostLanguageServices languageServices) { var syntaxTree = semanticModel.SyntaxTree; + var sourceText = semanticModel.SyntaxTree.GetText(); + var syntaxFactsService = languageServices.GetRequiredService(); + var documentVertex = new LsifGraph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); _lsifJsonWriter.Write(documentVertex); _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); + + // We will walk the file token-by-token, making a range for each one and then attaching information for it + var rangeVertices = new List>(); + + foreach (var syntaxToken in syntaxTree.GetRoot().DescendantTokens(descendIntoTrivia: true)) + { + if (syntaxFactsService.IsBindableToken(syntaxToken)) + { + var bindableParent = syntaxFactsService.GetBindableParent(syntaxToken); + + if (bindableParent != null) + { + var symbolInfo = semanticModel.GetSymbolInfo(bindableParent); + + if (symbolInfo.Symbol != null) + { + var rangeVertex = LsifGraph.Range.FromTextSpan(syntaxToken.Span, sourceText); + + _lsifJsonWriter.Write(rangeVertex); + rangeVertices.Add(rangeVertex.GetId()); + } + } + } + } + + _lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices)); _lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId())); return Task.FromResult(documentVertex.GetId()); diff --git a/src/Features/Lsif/Generator/LsifGraph/Range.cs b/src/Features/Lsif/Generator/LsifGraph/Range.cs new file mode 100644 index 0000000000000..2fab8d0aa5903 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Range.cs @@ -0,0 +1,32 @@ +// 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 Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.LanguageServer.Protocol; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + internal sealed class Range : Vertex + { + public Position Start { get; } + public Position End { get; } + + public Range(Position start, Position end) + : base(label: "range") + { + Start = start; + End = end; + } + + public static Range FromTextSpan(TextSpan textSpan, SourceText sourceText) + { + var linePositionSpan = sourceText.Lines.GetLinePositionSpan(textSpan); + + return new Range(start: FromLinePositionSpan(linePositionSpan.Start), end: FromLinePositionSpan(linePositionSpan.End)); + } + + private static Position FromLinePositionSpan(LinePosition linePosition) + { + return new Position { Line = linePosition.Line, Character = linePosition.Character }; + } + } +} diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj index f1d2d7edf837a..eda7a4c776e1b 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj b/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj index 524bc035d673b..07f7d7dcc1740 100644 --- a/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj @@ -262,6 +262,7 @@ + From e2f0e4f833b8b4e7b13ad454d08e9010be1d646a Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 16:34:23 -0800 Subject: [PATCH 007/222] Output total time spent in the generation phase --- src/Features/Lsif/Generator/Program.cs | 14 +++++++++++--- src/Features/Lsif/Generator/Utilities.cs | 5 +++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index f72e810d5a9e9..34540dfe30629 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -63,11 +63,13 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output var msbuildWorkspace = MSBuildWorkspace.Create(); var solution = await msbuildWorkspace.OpenSolutionAsync(solutionFile.FullName); - await logFile.WriteLineAsync($"Load of the solution completed in {solutionLoadStopwatch.ToDisplayString()}."); + await logFile.WriteLineAsync($"Load of the solution completed in {solutionLoadStopwatch.Elapsed.ToDisplayString()}."); using var lsifWriter = new TextLsifJsonWriter(outputWriter); var lsifGenerator = new Generator(lsifWriter); + TimeSpan totalTimeInGenerationPhase = TimeSpan.Zero; + foreach (var project in solution.Projects) { if (project.SupportsCompilation && project.FilePath != null) @@ -75,13 +77,19 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output var compilationCreationStopwatch = Stopwatch.StartNew(); var compilation = (await project.GetCompilationAsync())!; - await logFile.WriteLineAsync($"Fetch of compilation for {project.FilePath} completed in {compilationCreationStopwatch.ToDisplayString()}."); + await logFile.WriteLineAsync($"Fetch of compilation for {project.FilePath} completed in {compilationCreationStopwatch.Elapsed.ToDisplayString()}."); var generationForProjectStopwatch = Stopwatch.StartNew(); await lsifGenerator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices); - await logFile.WriteLineAsync($"Generation for {project.FilePath} completed in {generationForProjectStopwatch.ToDisplayString()}."); + generationForProjectStopwatch.Stop(); + + totalTimeInGenerationPhase += generationForProjectStopwatch.Elapsed; + + await logFile.WriteLineAsync($"Generation for {project.FilePath} completed in {generationForProjectStopwatch.Elapsed.ToDisplayString()}."); } } + + await logFile.WriteLineAsync($"Total time spent in the generation phase for all projects, excluding compilation fetch time: {totalTimeInGenerationPhase.ToDisplayString()}"); } } } diff --git a/src/Features/Lsif/Generator/Utilities.cs b/src/Features/Lsif/Generator/Utilities.cs index 3708f276dfe25..518e97ff2686e 100644 --- a/src/Features/Lsif/Generator/Utilities.cs +++ b/src/Features/Lsif/Generator/Utilities.cs @@ -1,14 +1,15 @@ // 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.Diagnostics; namespace Microsoft.CodeAnalysis.Lsif.Generator { internal static class Utilities { - public static string ToDisplayString(this Stopwatch stopwatch) + public static string ToDisplayString(this TimeSpan timeSpan) { - return stopwatch.Elapsed.TotalSeconds.ToString("N2") + " second(s)"; + return timeSpan.TotalSeconds.ToString("N2") + " seconds"; } } } From 97f60b6b17f41513fab7082a926feb5382eab2d7 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 17:38:41 -0800 Subject: [PATCH 008/222] Add pointers from ranges to the resultSet for the original symbol --- src/Features/Lsif/Generator/Generator.cs | 35 ++++++++++---- .../Lsif/Generator/LsifGraph/ResultSet.cs | 15 ++++++ .../DeferredFlushResultSetTracker.cs | 48 +++++++++++++++++++ .../ResultSetTracking/IResultSetTracker.cs | 14 ++++++ .../Writing/InMemoryLsifJsonWriter.cs | 38 +++++++++++++++ 5 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 src/Features/Lsif/Generator/LsifGraph/ResultSet.cs create mode 100644 src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs create mode 100644 src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs create mode 100644 src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 63f72fca11c23..2eb83e2bbae5c 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -2,11 +2,11 @@ using System; using System.Collections.Generic; -using System.CommandLine; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking; using Microsoft.CodeAnalysis.Lsif.Generator.Writing; namespace Microsoft.CodeAnalysis.Lsif.Generator @@ -28,11 +28,22 @@ public async Task GenerateForCompilation(Compilation compilation, string project var documentIds = new List>(); + var symbolResultsTracker = new DeferredFlushResultSetTracker(); + foreach (var syntaxTree in compilation.SyntaxTrees) { var semanticModel = compilation.GetSemanticModel(syntaxTree); - documentIds.Add(await GenerateForDocument(semanticModel, languageServices)); + // We generate the document contents into an in-memory copy, and then write that out at once at the end. This + // allows us to collect everything and avoid a lot of fine-grained contention on the write to the single + // LSIF file. Becasue of the rule that vertices must be written before they're used by an edge, we'll flush any top- + // level symbol result sets made first, since the document contents will point to that. + var documentWriter = new InMemoryLsifJsonWriter(); + var documentId = await GenerateForDocument(semanticModel, languageServices, symbolResultsTracker, documentWriter); + symbolResultsTracker.Flush(_lsifJsonWriter); + documentWriter.CopyTo(_lsifJsonWriter); + + documentIds.Add(documentId); } _lsifJsonWriter.Write(Edge.Create("contains", projectVertex.GetId(), documentIds)); @@ -40,7 +51,11 @@ public async Task GenerateForCompilation(Compilation compilation, string project _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); } - private Task> GenerateForDocument(SemanticModel semanticModel, HostLanguageServices languageServices) + private static Task> GenerateForDocument( + SemanticModel semanticModel, + HostLanguageServices languageServices, + IResultSetTracker symbolResultsTracker, + ILsifJsonWriter lsifJsonWriter) { var syntaxTree = semanticModel.SyntaxTree; var sourceText = semanticModel.SyntaxTree.GetText(); @@ -48,8 +63,8 @@ public async Task GenerateForCompilation(Compilation compilation, string project var documentVertex = new LsifGraph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); - _lsifJsonWriter.Write(documentVertex); - _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); + lsifJsonWriter.Write(documentVertex); + lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); // We will walk the file token-by-token, making a range for each one and then attaching information for it var rangeVertices = new List>(); @@ -68,15 +83,19 @@ public async Task GenerateForCompilation(Compilation compilation, string project { var rangeVertex = LsifGraph.Range.FromTextSpan(syntaxToken.Span, sourceText); - _lsifJsonWriter.Write(rangeVertex); + lsifJsonWriter.Write(rangeVertex); rangeVertices.Add(rangeVertex.GetId()); + + // For now, we will link the range to the original definition. We'll have to fix this once we start supporting + // hover, since we show different contents for different constructed types there. + lsifJsonWriter.Write(Edge.Create("next", rangeVertex.GetId(), symbolResultsTracker.GetResultSetIdForSymbol(symbolInfo.Symbol.OriginalDefinition))); } } } } - _lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices)); - _lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId())); + lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices)); + lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId())); return Task.FromResult(documentVertex.GetId()); } diff --git a/src/Features/Lsif/Generator/LsifGraph/ResultSet.cs b/src/Features/Lsif/Generator/LsifGraph/ResultSet.cs new file mode 100644 index 0000000000000..c61ad70e7a69e --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/ResultSet.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// Represents a single ResultSet in the LSIF file. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set for further details. + /// + internal sealed class ResultSet : Vertex + { + public ResultSet() + : base(label: "resultSet") + { + } + } +} diff --git a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs new file mode 100644 index 0000000000000..51272d8484d3a --- /dev/null +++ b/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs @@ -0,0 +1,48 @@ +// 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.Collections.Generic; +using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.Lsif.Generator.Writing; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking +{ + internal sealed class DeferredFlushResultSetTracker : IResultSetTracker + { + private readonly Dictionary _symbolToResultSetId = new Dictionary(); + private readonly List _resultSetsNeedingFlush = new List(); + + public Id GetResultSetIdForSymbol(ISymbol symbol) + { + if (_symbolToResultSetId.TryGetValue(symbol, out var trackedResultSet)) + { + return trackedResultSet.Id; + } + + var resultSet = new ResultSet(); + _resultSetsNeedingFlush.Add(resultSet); + _symbolToResultSetId.Add(symbol, new TrackedResultSet(resultSet.GetId())); + + return resultSet.GetId(); + } + + public void Flush(ILsifJsonWriter lsifJsonWriter) + { + foreach (var resultSetNeedingFlush in _resultSetsNeedingFlush) + { + lsifJsonWriter.Write(resultSetNeedingFlush); + } + + _resultSetsNeedingFlush.Clear(); + } + + private class TrackedResultSet + { + public Id Id { get; } + + public TrackedResultSet(Id id) + { + Id = id; + } + } + } +} diff --git a/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs new file mode 100644 index 0000000000000..47931f7a994b1 --- /dev/null +++ b/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs @@ -0,0 +1,14 @@ +// 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 Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking +{ + /// + /// An object that tracks a mapping from symbols to the result sets that have information about those symbols. + /// + internal interface IResultSetTracker + { + Id GetResultSetIdForSymbol(ISymbol symbol); + } +} diff --git a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs new file mode 100644 index 0000000000000..14dffcc3bc6c2 --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs @@ -0,0 +1,38 @@ +// 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.Collections.Generic; +using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +{ + internal sealed class InMemoryLsifJsonWriter : ILsifJsonWriter + { + private readonly List _vertices = new List(); + private readonly List _edges = new List(); + + public void Write(Vertex vertex) + { + _vertices.Add(vertex); + } + + public void Write(Edge edge) + { + _edges.Add(edge); + } + + public void CopyTo(ILsifJsonWriter writer) + { + // We always write vertices before edges, as the underlying LSIF format requires that vertices used by an edge must + // be written before the edge. The easiest way to ensure this is just write all vertices first. + foreach (var vertex in _vertices) + { + writer.Write(vertex); + } + + foreach (var edge in _edges) + { + writer.Write(edge); + } + } + } +} From b35e1f498711075ef930828ef1f1caf84f5ad3a2 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 17 Dec 2019 18:01:07 -0800 Subject: [PATCH 009/222] Simplify ILsifJsonWriter Having separate methods for writing vertices and edges isn't terribly useful in the end, so merge them. --- .../DeferredFlushResultSetTracker.cs | 10 ++++---- .../Lsif/Generator/Writing/ILsifJsonWriter.cs | 3 +-- .../Writing/InMemoryLsifJsonWriter.cs | 23 ++++--------------- .../Generator/Writing/TextLsifJsonWriter.cs | 9 ++------ 4 files changed, 13 insertions(+), 32 deletions(-) diff --git a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs index 51272d8484d3a..45bf1c6b288bc 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking internal sealed class DeferredFlushResultSetTracker : IResultSetTracker { private readonly Dictionary _symbolToResultSetId = new Dictionary(); - private readonly List _resultSetsNeedingFlush = new List(); + private readonly List _elementsNeedingFlush = new List(); public Id GetResultSetIdForSymbol(ISymbol symbol) { @@ -19,7 +19,7 @@ public Id GetResultSetIdForSymbol(ISymbol symbol) } var resultSet = new ResultSet(); - _resultSetsNeedingFlush.Add(resultSet); + _elementsNeedingFlush.Add(resultSet); _symbolToResultSetId.Add(symbol, new TrackedResultSet(resultSet.GetId())); return resultSet.GetId(); @@ -27,12 +27,12 @@ public Id GetResultSetIdForSymbol(ISymbol symbol) public void Flush(ILsifJsonWriter lsifJsonWriter) { - foreach (var resultSetNeedingFlush in _resultSetsNeedingFlush) + foreach (var elementNeedingFlush in _elementsNeedingFlush) { - lsifJsonWriter.Write(resultSetNeedingFlush); + lsifJsonWriter.Write(elementNeedingFlush); } - _resultSetsNeedingFlush.Clear(); + _elementsNeedingFlush.Clear(); } private class TrackedResultSet diff --git a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs index 2503cfa90ce66..1068d63819a0d 100644 --- a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs @@ -6,7 +6,6 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing { internal interface ILsifJsonWriter { - void Write(Vertex vertex); - void Write(Edge edge); + void Write(Element element); } } diff --git a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs index 14dffcc3bc6c2..3684027c6bfd8 100644 --- a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs @@ -7,31 +7,18 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing { internal sealed class InMemoryLsifJsonWriter : ILsifJsonWriter { - private readonly List _vertices = new List(); - private readonly List _edges = new List(); + private readonly List _elements = new List(); - public void Write(Vertex vertex) + public void Write(Element element) { - _vertices.Add(vertex); - } - - public void Write(Edge edge) - { - _edges.Add(edge); + _elements.Add(element); } public void CopyTo(ILsifJsonWriter writer) { - // We always write vertices before edges, as the underlying LSIF format requires that vertices used by an edge must - // be written before the edge. The easiest way to ensure this is just write all vertices first. - foreach (var vertex in _vertices) - { - writer.Write(vertex); - } - - foreach (var edge in _edges) + foreach (var element in _elements) { - writer.Write(edge); + writer.Write(element); } } } diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs index ada6c766a161d..3cd1b585f2a49 100644 --- a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs @@ -30,14 +30,9 @@ public TextLsifJsonWriter(TextWriter outputWriter) _jsonSerializer = JsonSerializer.Create(settings); } - public void Write(Vertex vertex) + public void Write(Element element) { - _jsonSerializer.Serialize(_jsonTextWriter, vertex); - } - - public void Write(Edge edge) - { - _jsonSerializer.Serialize(_jsonTextWriter, edge); + _jsonSerializer.Serialize(_jsonTextWriter, element); } public void Dispose() From 71331342d9a9bf7f3f9ad0cc2e1faa13f26b1e9f Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 18 Dec 2019 14:40:55 -0800 Subject: [PATCH 010/222] Link referenceResults for a resultSet back to the referencing ranges --- src/Features/Lsif/Generator/Generator.cs | 8 +- src/Features/Lsif/Generator/LsifGraph/Edge.cs | 2 +- src/Features/Lsif/Generator/LsifGraph/Item.cs | 19 ++++ .../Generator/LsifGraph/ReferenceResult.cs | 12 +++ .../DeferredFlushResultSetTracker.cs | 92 +++++++++++++++++-- .../ResultSetTracking/IResultSetTracker.cs | 3 + 6 files changed, 128 insertions(+), 8 deletions(-) create mode 100644 src/Features/Lsif/Generator/LsifGraph/Item.cs create mode 100644 src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 2eb83e2bbae5c..a92e47ebbe41a 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; using Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking; using Microsoft.CodeAnalysis.Lsif.Generator.Writing; +using Methods = Microsoft.VisualStudio.LanguageServer.Protocol.Methods; namespace Microsoft.CodeAnalysis.Lsif.Generator { @@ -88,7 +89,12 @@ public async Task GenerateForCompilation(Compilation compilation, string project // For now, we will link the range to the original definition. We'll have to fix this once we start supporting // hover, since we show different contents for different constructed types there. - lsifJsonWriter.Write(Edge.Create("next", rangeVertex.GetId(), symbolResultsTracker.GetResultSetIdForSymbol(symbolInfo.Symbol.OriginalDefinition))); + var findReferencesSymbol = symbolInfo.Symbol.OriginalDefinition; + lsifJsonWriter.Write(Edge.Create("next", rangeVertex.GetId(), symbolResultsTracker.GetResultSetIdForSymbol(findReferencesSymbol))); + + // Create the link from the references back to this range + var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(findReferencesSymbol, Methods.TextDocumentReferencesName, () => new ReferenceResult()); + lsifJsonWriter.Write(new Item(referenceResultsId.As(), rangeVertex.GetId(), documentVertex.GetId(), property: "references")); } } } diff --git a/src/Features/Lsif/Generator/LsifGraph/Edge.cs b/src/Features/Lsif/Generator/LsifGraph/Edge.cs index 845038e1ec3d5..2bca4be04dbaf 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Edge.cs +++ b/src/Features/Lsif/Generator/LsifGraph/Edge.cs @@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph /// /// Represents an edge from one vertex to another. /// - internal sealed class Edge : Element + internal class Edge : Element { [JsonProperty("outV")] public Id OutVertex { get; } diff --git a/src/Features/Lsif/Generator/LsifGraph/Item.cs b/src/Features/Lsif/Generator/LsifGraph/Item.cs new file mode 100644 index 0000000000000..dad6ec3357679 --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Item.cs @@ -0,0 +1,19 @@ +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + /// + /// Represents a single item that points to a range from a result. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#request-textdocumentreferences + /// for an example of item edges. + /// + internal sealed class Item : Edge + { + public Id Document { get; } + public string Property { get; } + + public Item(Id outVertex, Id range, Id document, string property) + : base(label: "item", outVertex, new[] { range.As() }) + { + Document = document; + Property = property; + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs b/src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs new file mode 100644 index 0000000000000..288d3e2712fbf --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + internal sealed class ReferenceResult : Vertex + { + public ReferenceResult() + : base(label: "referenceResult") + { + } + } +} diff --git a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs index 45bf1c6b288bc..54535ac9644b6 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs @@ -1,5 +1,6 @@ // 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.Lsif.Generator.LsifGraph; using Microsoft.CodeAnalysis.Lsif.Generator.Writing; @@ -11,18 +12,39 @@ internal sealed class DeferredFlushResultSetTracker : IResultSetTracker private readonly Dictionary _symbolToResultSetId = new Dictionary(); private readonly List _elementsNeedingFlush = new List(); + private TrackedResultSet GetTrackedResultSet(ISymbol symbol) + { + if (!_symbolToResultSetId.TryGetValue(symbol, out var trackedResultSet)) + { + var resultSet = new ResultSet(); + _elementsNeedingFlush.Add(resultSet); + trackedResultSet = new TrackedResultSet(resultSet.GetId()); + _symbolToResultSetId.Add(symbol, trackedResultSet); + } + + return trackedResultSet; + } + public Id GetResultSetIdForSymbol(ISymbol symbol) { - if (_symbolToResultSetId.TryGetValue(symbol, out var trackedResultSet)) + return GetTrackedResultSet(symbol).Id; + } + + public Id GetResultIdForSymbol(ISymbol symbol, string edgeKind, Func vertexCreator) where T : Vertex + { + var id = GetTrackedResultSet(symbol).GetResultId(edgeKind, vertexCreator, out Element[]? elementsNeedingFlush); + + if (elementsNeedingFlush != null) { - return trackedResultSet.Id; + _elementsNeedingFlush.AddRange(elementsNeedingFlush); } - var resultSet = new ResultSet(); - _elementsNeedingFlush.Add(resultSet); - _symbolToResultSetId.Add(symbol, new TrackedResultSet(resultSet.GetId())); + return id; + } - return resultSet.GetId(); + public bool ResultSetNeedsInformationalEdgeAdded(ISymbol symbol, string edgeKind) + { + return GetTrackedResultSet(symbol).ResultSetNeedsInformationalEdgeAdded(edgeKind); } public void Flush(ILsifJsonWriter lsifJsonWriter) @@ -39,10 +61,68 @@ private class TrackedResultSet { public Id Id { get; } + /// + /// A map which holds the per-symbol results that are linked from the resultSet. The value will be null if the entry was + /// added via . + /// + /// + /// This class assumes that we more or less have two kinds of edges in the LSIF world: + /// + /// 1. the resultSet might point to a node that doesn't really have any data, but simply points to other data like referenceResults. + /// In this case, it's important for clients to get to that Id. + /// 2. the resultSet points to a node that itself has data, but nobody needs to know the ID, like a hover result. In this case, those results + /// are often expensive to compute, but we do want to record that somebody is adding them somewhere. + /// + /// We record the first kind of this in this dictionary with a non-null Id, and the second kind with a null ID. We could conceptually store + /// two dictionaries for this, but that will add memory pressure and also limit the catching of mistakes if people cross these two APIs. + /// + private readonly Dictionary?> _edgeKindToVertexId = new Dictionary?>(); + public TrackedResultSet(Id id) { Id = id; } + + public Id GetResultId(string edgeKind, Func vertexCreator, out Element[]? elementsNeedingFlush) where T : Vertex + { + if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) + { + if (!existingId.HasValue) + { + throw new Exception($"This ResultSet already has an edge of {edgeKind} as {nameof(ResultSetNeedsInformationalEdgeAdded)} was called with this edge kind."); + } + + // TODO: this is a violation of the type system here, really: we're assuming that all calls to this function with the same edge kind + // will have the same type parameter. If that's violated, the Id returned here isn't really the right type. + elementsNeedingFlush = null; + return new Id(existingId.Value.NumericId); + } + + T vertex = vertexCreator(); + _edgeKindToVertexId.Add(edgeKind, vertex.GetId().As()); + + elementsNeedingFlush = new Element[2]; + elementsNeedingFlush[0] = vertex; + elementsNeedingFlush[1] = Edge.Create(edgeKind, Id, vertex.GetId()); + + return vertex.GetId(); + } + + public bool ResultSetNeedsInformationalEdgeAdded(string edgeKind) + { + if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) + { + if (existingId.HasValue) + { + throw new InvalidOperationException($"This edge kind was already called with a call to {nameof(GetResultId)} which would imply we are mixing edge types incorrectly."); + } + + return false; + } + + _edgeKindToVertexId.Add(edgeKind, null); + return true; + } } } } diff --git a/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs index 47931f7a994b1..e092d34e44064 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs @@ -1,5 +1,6 @@ // 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 Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking @@ -10,5 +11,7 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking internal interface IResultSetTracker { Id GetResultSetIdForSymbol(ISymbol symbol); + Id GetResultIdForSymbol(ISymbol symbol, string edgeKind, Func vertexCreator) where T : Vertex; + bool ResultSetNeedsInformationalEdgeAdded(ISymbol symbol, string edgeKind); } } From 1db220dcc65116fcf18d8d80318b0d449cdbdbe4 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 18 Dec 2019 15:59:00 -0800 Subject: [PATCH 011/222] Add moniker generation --- src/Features/Lsif/Generator/Generator.cs | 101 ++++++++++++++++-- .../Lsif/Generator/LsifGraph/Moniker.cs | 19 ++++ 2 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 src/Features/Lsif/Generator/LsifGraph/Moniker.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index a92e47ebbe41a..b2180abc7dfcb 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -2,6 +2,8 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServices; @@ -89,12 +91,27 @@ public async Task GenerateForCompilation(Compilation compilation, string project // For now, we will link the range to the original definition. We'll have to fix this once we start supporting // hover, since we show different contents for different constructed types there. - var findReferencesSymbol = symbolInfo.Symbol.OriginalDefinition; - lsifJsonWriter.Write(Edge.Create("next", rangeVertex.GetId(), symbolResultsTracker.GetResultSetIdForSymbol(findReferencesSymbol))); - - // Create the link from the references back to this range - var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(findReferencesSymbol, Methods.TextDocumentReferencesName, () => new ReferenceResult()); - lsifJsonWriter.Write(new Item(referenceResultsId.As(), rangeVertex.GetId(), documentVertex.GetId(), property: "references")); + var originalDefinition = symbolInfo.Symbol.OriginalDefinition; + var originalDefinitionResultSetId = symbolResultsTracker.GetResultSetIdForSymbol(originalDefinition); + lsifJsonWriter.Write(Edge.Create("next", rangeVertex.GetId(), originalDefinitionResultSetId)); + + if (IncludeSymbolInReferences(originalDefinition)) + { + // Create the link from the references back to this range + var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(originalDefinition, Methods.TextDocumentReferencesName, () => new ReferenceResult()); + lsifJsonWriter.Write(new Item(referenceResultsId.As(), rangeVertex.GetId(), documentVertex.GetId(), property: "references")); + + // Attach the moniker if needed + if (symbolResultsTracker.ResultSetNeedsInformationalEdgeAdded(originalDefinition, "moniker")) + { + var monikerVertex = CreateMonikerVertexForSymbol(originalDefinition, semanticModel.Compilation); + if (monikerVertex != null) + { + lsifJsonWriter.Write(monikerVertex); + lsifJsonWriter.Write(Edge.Create("moniker", originalDefinitionResultSetId, monikerVertex.GetId())); + } + } + } } } } @@ -106,6 +123,78 @@ public async Task GenerateForCompilation(Compilation compilation, string project return Task.FromResult(documentVertex.GetId()); } + private static bool IncludeSymbolInReferences(ISymbol symbol) + { + // Skip built in-operators. We could pick some sort of moniker for these, but I doubt anybody really needs to search for all uses of + // + in the world's projects at once. + if (symbol is IMethodSymbol method && method.MethodKind == MethodKind.BuiltinOperator) + { + return false; + } + + // Skip some type of symbols that don't really make sense + if (symbol.Kind == SymbolKind.ArrayType || + symbol.Kind == SymbolKind.Discard || + symbol.Kind == SymbolKind.ErrorType) + { + return false; + } + + return true; + } + + private static Moniker? CreateMonikerVertexForSymbol(ISymbol symbol, Compilation compilation) + { + // This uses the existing format that earlier prototypes of the Roslyn LSIF tool implemented; a different format may make more sense long term, but changing the + // moniker makes it difficult for other systems that have older LSIF indexes to the connect the two indexes together. + + // Namespaces are special: they're just a name that exists in the ether between compilations + if (symbol.Kind == SymbolKind.Namespace) + { + return new Moniker("dotnet-namespace", symbol.ToDisplayString()); + } + + string symbolMoniker = symbol.ContainingAssembly.Name + "#"; + + if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter || symbol.Kind == SymbolKind.RangeVariable) + { + symbolMoniker += GetRequiredDocumentationCommentId(symbol.ContainingSymbol) + "#" + symbol.Name; + } + else + { + symbolMoniker += GetRequiredDocumentationCommentId(symbol); + } + + string kind; + + if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.RangeVariable) + { + kind = "local"; + } + else if (symbol.ContainingAssembly.Equals(compilation.Assembly)) + { + kind = "export"; + } + else + { + kind = "import"; + } + + return new Moniker("dotnet-xml-doc", symbolMoniker, kind); + + static string GetRequiredDocumentationCommentId(ISymbol symbol) + { + var documentationCommentId = symbol.GetDocumentationCommentId(); + + if (documentationCommentId == null) + { + throw new Exception($"Unable to get documentation comment ID for {symbol.ToDisplayString()}"); + } + + return documentationCommentId; + } + } + private static string GetLanguageKind(string languageName) { return languageName switch diff --git a/src/Features/Lsif/Generator/LsifGraph/Moniker.cs b/src/Features/Lsif/Generator/LsifGraph/Moniker.cs new file mode 100644 index 0000000000000..b3fe7185beede --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/Moniker.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + internal sealed class Moniker : Vertex + { + public string Scheme { get; } + public string Identifier { get; } + public string? Kind { get; } + + public Moniker(string scheme, string identifier, string? kind = null) + : base(label: "moniker") + { + Scheme = scheme; + Identifier = identifier; + Kind = kind; + } + } +} From 7dde8a436718f8c974d69830118e9e8e5f3f6bb1 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 18 Dec 2019 16:00:30 -0800 Subject: [PATCH 012/222] Remove deferred nature DeferredFlushResultSetTracker Since we already have a way to defer writing with the InMemoryLsifJsonWriter, we can just use that rather than having it also written in there directly. --- src/Features/Lsif/Generator/Generator.cs | 11 ++++-- ...er.cs => SymbolHoldingResultSetTracker.cs} | 38 ++++++------------- .../Writing/InMemoryLsifJsonWriter.cs | 4 +- 3 files changed, 22 insertions(+), 31 deletions(-) rename src/Features/Lsif/Generator/ResultSetTracking/{DeferredFlushResultSetTracker.cs => SymbolHoldingResultSetTracker.cs} (81%) diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index b2180abc7dfcb..23b9b4dfd5916 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -31,7 +31,10 @@ public async Task GenerateForCompilation(Compilation compilation, string project var documentIds = new List>(); - var symbolResultsTracker = new DeferredFlushResultSetTracker(); + // We create a ResultSetTracker to track all top-level symbols in the project. We don't want all writes to immediately go to + // the JSON file once we support parallel processing, so we'll accumulate them and then apply at once. + var topLevelSymbolsWriter = new InMemoryLsifJsonWriter(); + var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter); foreach (var syntaxTree in compilation.SyntaxTrees) { @@ -42,9 +45,9 @@ public async Task GenerateForCompilation(Compilation compilation, string project // LSIF file. Becasue of the rule that vertices must be written before they're used by an edge, we'll flush any top- // level symbol result sets made first, since the document contents will point to that. var documentWriter = new InMemoryLsifJsonWriter(); - var documentId = await GenerateForDocument(semanticModel, languageServices, symbolResultsTracker, documentWriter); - symbolResultsTracker.Flush(_lsifJsonWriter); - documentWriter.CopyTo(_lsifJsonWriter); + var documentId = await GenerateForDocument(semanticModel, languageServices, topLevelSymbolsResultSetTracker, documentWriter); + topLevelSymbolsWriter.CopyToAndEmpty(_lsifJsonWriter); + documentWriter.CopyToAndEmpty(_lsifJsonWriter); documentIds.Add(documentId); } diff --git a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs similarity index 81% rename from src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs rename to src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 54535ac9644b6..1bf15734cd7d4 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/DeferredFlushResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -7,17 +7,22 @@ namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking { - internal sealed class DeferredFlushResultSetTracker : IResultSetTracker + internal sealed class SymbolHoldingResultSetTracker : IResultSetTracker { private readonly Dictionary _symbolToResultSetId = new Dictionary(); - private readonly List _elementsNeedingFlush = new List(); + private readonly ILsifJsonWriter _lsifJsonWriter; + + public SymbolHoldingResultSetTracker(ILsifJsonWriter lsifJsonWriter) + { + _lsifJsonWriter = lsifJsonWriter; + } private TrackedResultSet GetTrackedResultSet(ISymbol symbol) { if (!_symbolToResultSetId.TryGetValue(symbol, out var trackedResultSet)) { var resultSet = new ResultSet(); - _elementsNeedingFlush.Add(resultSet); + _lsifJsonWriter.Write(resultSet); trackedResultSet = new TrackedResultSet(resultSet.GetId()); _symbolToResultSetId.Add(symbol, trackedResultSet); } @@ -32,14 +37,7 @@ public Id GetResultSetIdForSymbol(ISymbol symbol) public Id GetResultIdForSymbol(ISymbol symbol, string edgeKind, Func vertexCreator) where T : Vertex { - var id = GetTrackedResultSet(symbol).GetResultId(edgeKind, vertexCreator, out Element[]? elementsNeedingFlush); - - if (elementsNeedingFlush != null) - { - _elementsNeedingFlush.AddRange(elementsNeedingFlush); - } - - return id; + return GetTrackedResultSet(symbol).GetResultId(edgeKind, vertexCreator, _lsifJsonWriter); } public bool ResultSetNeedsInformationalEdgeAdded(ISymbol symbol, string edgeKind) @@ -47,16 +45,6 @@ public bool ResultSetNeedsInformationalEdgeAdded(ISymbol symbol, string edgeKind return GetTrackedResultSet(symbol).ResultSetNeedsInformationalEdgeAdded(edgeKind); } - public void Flush(ILsifJsonWriter lsifJsonWriter) - { - foreach (var elementNeedingFlush in _elementsNeedingFlush) - { - lsifJsonWriter.Write(elementNeedingFlush); - } - - _elementsNeedingFlush.Clear(); - } - private class TrackedResultSet { public Id Id { get; } @@ -83,7 +71,7 @@ public TrackedResultSet(Id id) Id = id; } - public Id GetResultId(string edgeKind, Func vertexCreator, out Element[]? elementsNeedingFlush) where T : Vertex + public Id GetResultId(string edgeKind, Func vertexCreator, ILsifJsonWriter lsifJsonWriter) where T : Vertex { if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) { @@ -94,16 +82,14 @@ public Id GetResultId(string edgeKind, Func vertexCreator, out Element[ // TODO: this is a violation of the type system here, really: we're assuming that all calls to this function with the same edge kind // will have the same type parameter. If that's violated, the Id returned here isn't really the right type. - elementsNeedingFlush = null; return new Id(existingId.Value.NumericId); } T vertex = vertexCreator(); _edgeKindToVertexId.Add(edgeKind, vertex.GetId().As()); - elementsNeedingFlush = new Element[2]; - elementsNeedingFlush[0] = vertex; - elementsNeedingFlush[1] = Edge.Create(edgeKind, Id, vertex.GetId()); + lsifJsonWriter.Write(vertex); + lsifJsonWriter.Write(Edge.Create(edgeKind, Id, vertex.GetId())); return vertex.GetId(); } diff --git a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs index 3684027c6bfd8..be32728425e39 100644 --- a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs @@ -14,12 +14,14 @@ public void Write(Element element) _elements.Add(element); } - public void CopyTo(ILsifJsonWriter writer) + public void CopyToAndEmpty(ILsifJsonWriter writer) { foreach (var element in _elements) { writer.Write(element); } + + _elements.Clear(); } } } From fcaa044d3b317fcd280c6694522c77cca0b17ba6 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 18 Dec 2019 16:13:34 -0800 Subject: [PATCH 013/222] Don't hold onto symbols in our ResultSetTracker if they can't be seen There's no reason in holding onto locals and other types of symbols once processing a document if they can't been seen outside that document. --- src/Features/Lsif/Generator/Generator.cs | 25 ++++++++++++++- .../DelegatingResultSetTracker.cs | 32 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 23b9b4dfd5916..f25cc5d651144 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -60,7 +60,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project private static Task> GenerateForDocument( SemanticModel semanticModel, HostLanguageServices languageServices, - IResultSetTracker symbolResultsTracker, + IResultSetTracker topLevelSymbolsResultSetTracker, ILsifJsonWriter lsifJsonWriter) { var syntaxTree = semanticModel.SyntaxTree; @@ -72,6 +72,29 @@ public async Task GenerateForCompilation(Compilation compilation, string project lsifJsonWriter.Write(documentVertex); lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); + // As we are processing this file, we are going to encounter symbols that have a shared resultSet with other documents like types + // or methods. We're also going to encounter locals that never leave this document. We don't want those locals being held by + // the topLevelSymbolsResultSetTracker, so we'll make another tracker for document local symbols, and then have a delegating + // one that picks the correct one of the two. + var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter); + var symbolResultsTracker = new DelegatingResultSetTracker(symbol => + { + if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.RangeVariable) + { + // These symbols can go in the document local one because they can't escape methods + return documentLocalSymbolsResultSetTracker; + } + else if (symbol.ContainingType != null && symbol.DeclaredAccessibility == Accessibility.Private && symbol.ContainingType.Locations.Length == 1) + { + // This is a private member in a class that isn't partial, so it can't escape the file + return documentLocalSymbolsResultSetTracker; + } + else + { + return topLevelSymbolsResultSetTracker; + } + }); + // We will walk the file token-by-token, making a range for each one and then attaching information for it var rangeVertices = new List>(); diff --git a/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs new file mode 100644 index 0000000000000..81f34316d3fc1 --- /dev/null +++ b/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs @@ -0,0 +1,32 @@ +// 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 Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; + +namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking +{ + internal sealed class DelegatingResultSetTracker : IResultSetTracker + { + private readonly Func _chooseTrackerForSymbol; + + public DelegatingResultSetTracker(Func chooseTrackerForSymbol) + { + _chooseTrackerForSymbol = chooseTrackerForSymbol; + } + + public Id GetResultIdForSymbol(ISymbol symbol, string edgeKind, Func vertexCreator) where T : Vertex + { + return _chooseTrackerForSymbol(symbol).GetResultIdForSymbol(symbol, edgeKind, vertexCreator); + } + + public Id GetResultSetIdForSymbol(ISymbol symbol) + { + return _chooseTrackerForSymbol(symbol).GetResultSetIdForSymbol(symbol); + } + + public bool ResultSetNeedsInformationalEdgeAdded(ISymbol symbol, string edgeKind) + { + return _chooseTrackerForSymbol(symbol).ResultSetNeedsInformationalEdgeAdded(symbol, edgeKind); + } + } +} From 6f5fe84276d4e50baa0b3be201d7786d6c91cf61 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 18 Dec 2019 16:46:32 -0800 Subject: [PATCH 014/222] Make CreateMonikerVertexForSymbol no longer return nullable It doesn't anymore, so no reason to mark it. --- src/Features/Lsif/Generator/Generator.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index f25cc5d651144..cac1cddc18a84 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServices; @@ -131,11 +129,8 @@ public async Task GenerateForCompilation(Compilation compilation, string project if (symbolResultsTracker.ResultSetNeedsInformationalEdgeAdded(originalDefinition, "moniker")) { var monikerVertex = CreateMonikerVertexForSymbol(originalDefinition, semanticModel.Compilation); - if (monikerVertex != null) - { - lsifJsonWriter.Write(monikerVertex); - lsifJsonWriter.Write(Edge.Create("moniker", originalDefinitionResultSetId, monikerVertex.GetId())); - } + lsifJsonWriter.Write(monikerVertex); + lsifJsonWriter.Write(Edge.Create("moniker", originalDefinitionResultSetId, monikerVertex.GetId())); } } } @@ -169,7 +164,7 @@ private static bool IncludeSymbolInReferences(ISymbol symbol) return true; } - private static Moniker? CreateMonikerVertexForSymbol(ISymbol symbol, Compilation compilation) + private static Moniker CreateMonikerVertexForSymbol(ISymbol symbol, Compilation compilation) { // This uses the existing format that earlier prototypes of the Roslyn LSIF tool implemented; a different format may make more sense long term, but changing the // moniker makes it difficult for other systems that have older LSIF indexes to the connect the two indexes together. From 2fb347dc5b0e49a5352ca1376181590e71db5bc2 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 18 Dec 2019 16:59:42 -0800 Subject: [PATCH 015/222] Add support for labels --- src/Features/Lsif/Generator/Generator.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index cac1cddc18a84..f4f3b6290f959 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -77,7 +77,9 @@ public async Task GenerateForCompilation(Compilation compilation, string project var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter); var symbolResultsTracker = new DelegatingResultSetTracker(symbol => { - if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.RangeVariable) + if (symbol.Kind == SymbolKind.Local || + symbol.Kind == SymbolKind.RangeVariable || + symbol.Kind == SymbolKind.Label) { // These symbols can go in the document local one because they can't escape methods return documentLocalSymbolsResultSetTracker; @@ -177,7 +179,10 @@ private static Moniker CreateMonikerVertexForSymbol(ISymbol symbol, Compilation string symbolMoniker = symbol.ContainingAssembly.Name + "#"; - if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.Parameter || symbol.Kind == SymbolKind.RangeVariable) + if (symbol.Kind == SymbolKind.Local || + symbol.Kind == SymbolKind.Parameter || + symbol.Kind == SymbolKind.RangeVariable || + symbol.Kind == SymbolKind.Label) { symbolMoniker += GetRequiredDocumentationCommentId(symbol.ContainingSymbol) + "#" + symbol.Name; } @@ -188,7 +193,9 @@ private static Moniker CreateMonikerVertexForSymbol(ISymbol symbol, Compilation string kind; - if (symbol.Kind == SymbolKind.Local || symbol.Kind == SymbolKind.RangeVariable) + if (symbol.Kind == SymbolKind.Local || + symbol.Kind == SymbolKind.RangeVariable || + symbol.Kind == SymbolKind.Label) { kind = "local"; } From 44963d8512bae37b759ec34baecd351b430ab838 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 19 Dec 2019 11:14:11 -0800 Subject: [PATCH 016/222] Output the total time for everything including fetching compilations --- src/Features/Lsif/Generator/Program.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 34540dfe30629..759c105e27f1a 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -68,6 +68,7 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output using var lsifWriter = new TextLsifJsonWriter(outputWriter); var lsifGenerator = new Generator(lsifWriter); + Stopwatch totalTimeInGenerationAndCompilationFetchStopwatch = Stopwatch.StartNew(); TimeSpan totalTimeInGenerationPhase = TimeSpan.Zero; foreach (var project in solution.Projects) @@ -90,6 +91,7 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output } await logFile.WriteLineAsync($"Total time spent in the generation phase for all projects, excluding compilation fetch time: {totalTimeInGenerationPhase.ToDisplayString()}"); + await logFile.WriteLineAsync($"Total time spent in the generation phase for all projects, including compilation fetch time: {totalTimeInGenerationAndCompilationFetchStopwatch.Elapsed.ToDisplayString()}"); } } } From 790f1c0179ac3166c1eb543428cc4a0ee1cbfe51 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 19 Dec 2019 11:15:10 -0800 Subject: [PATCH 017/222] Filter out some other symbol types that are giving us trouble --- src/Features/Lsif/Generator/Generator.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index f4f3b6290f959..1c6166f56b209 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -155,6 +155,13 @@ private static bool IncludeSymbolInReferences(ISymbol symbol) return false; } + // TODO: some symbols for things some things in crefs don't have a ContainingAssembly. We'll skip those for now but do + // want those to work. + if (symbol.Kind != SymbolKind.Namespace && symbol.ContainingAssembly == null) + { + return false; + } + // Skip some type of symbols that don't really make sense if (symbol.Kind == SymbolKind.ArrayType || symbol.Kind == SymbolKind.Discard || From 369c14ba901d9a8fefe09f9e84210c13efc218a8 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 20 Dec 2019 17:38:59 -0500 Subject: [PATCH 018/222] Add support for controlling the LSIF output format This brings back the line format, instead of JSON only. --- src/Features/Lsif/Generator/Program.cs | 11 +++++---- .../Lsif/Generator/Writing/LsifFormat.cs | 17 ++++++++++++++ .../Generator/Writing/TextLsifJsonWriter.cs | 23 +++++++++++++++---- 3 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 src/Features/Lsif/Generator/Writing/LsifFormat.cs diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 759c105e27f1a..757c1a32798c0 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -21,15 +21,16 @@ public static Task Main(string[] args) { new Option("--solution", "input solution file") { Argument = new Argument().ExistingOnly(), Required = true }, new Option("--output", "file to write the LSIF output to, instead of the console") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() }, + new Option("--output-format", "format of LSIF output") { Argument = new Argument(defaultValue: () => LsifFormat.Line) }, new Option("--log", "file to write a log to") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() } }; - generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); + generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); return generateCommand.InvokeAsync(args); } - private static async Task GenerateAsync(FileInfo solution, string? output, string? log) + private static async Task GenerateAsync(FileInfo solution, string? output, LsifFormat outputFormat, string? log) { // If we have an output file, we'll write to that, else we'll use Console.Out using StreamWriter? outputFile = output != null ? new StreamWriter(output) : null; @@ -39,7 +40,7 @@ private static async Task GenerateAsync(FileInfo solution, string? output, strin try { - await GenerateAsync(solution, outputWriter, logFile); + await GenerateAsync(solution, outputWriter, outputFormat, logFile); } catch (Exception e) { @@ -53,7 +54,7 @@ private static async Task GenerateAsync(FileInfo solution, string? output, strin await logFile.WriteLineAsync("Generation complete."); } - private static async Task GenerateAsync(FileInfo solutionFile, TextWriter outputWriter, TextWriter logFile) + private static async Task GenerateAsync(FileInfo solutionFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) { await logFile.WriteLineAsync($"Loading {solutionFile.FullName}..."); @@ -65,7 +66,7 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output await logFile.WriteLineAsync($"Load of the solution completed in {solutionLoadStopwatch.Elapsed.ToDisplayString()}."); - using var lsifWriter = new TextLsifJsonWriter(outputWriter); + using var lsifWriter = new TextLsifJsonWriter(outputWriter, outputFormat); var lsifGenerator = new Generator(lsifWriter); Stopwatch totalTimeInGenerationAndCompilationFetchStopwatch = Stopwatch.StartNew(); diff --git a/src/Features/Lsif/Generator/Writing/LsifFormat.cs b/src/Features/Lsif/Generator/Writing/LsifFormat.cs new file mode 100644 index 0000000000000..fda090f668065 --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/LsifFormat.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +{ + internal enum LsifFormat + { + /// + /// Line format, where each line is a JSON object. + /// + Line, + + /// + /// JSON format, where the entire output is a single JSON array. + /// + Json + } +} diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs index 3cd1b585f2a49..d8d40f0c8b8d3 100644 --- a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs @@ -12,15 +12,16 @@ internal sealed class TextLsifJsonWriter : ILsifJsonWriter, IDisposable { private readonly JsonTextWriter _jsonTextWriter; private readonly JsonSerializer _jsonSerializer; + private readonly LsifFormat _format; - public TextLsifJsonWriter(TextWriter outputWriter) + public TextLsifJsonWriter(TextWriter outputWriter, LsifFormat format) { + _format = format; _jsonTextWriter = new JsonTextWriter(outputWriter); - _jsonTextWriter.WriteStartArray(); var settings = new JsonSerializerSettings { - Formatting = Newtonsoft.Json.Formatting.Indented, + Formatting = _format == LsifFormat.Json ? Newtonsoft.Json.Formatting.Indented : Newtonsoft.Json.Formatting.None, NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver(), TypeNameHandling = TypeNameHandling.None, @@ -28,16 +29,30 @@ public TextLsifJsonWriter(TextWriter outputWriter) }; _jsonSerializer = JsonSerializer.Create(settings); + + if (_format == LsifFormat.Json) + { + _jsonTextWriter.WriteStartArray(); + } } public void Write(Element element) { _jsonSerializer.Serialize(_jsonTextWriter, element); + + if (_format == LsifFormat.Line) + { + _jsonTextWriter.WriteWhitespace("\r\n"); + } } public void Dispose() { - _jsonTextWriter.WriteEndArray(); + if (_format == LsifFormat.Json) + { + _jsonTextWriter.WriteEndArray(); + } + _jsonTextWriter.Close(); } From 9e2b582a4a64419736337f67f8cde9125e1c1501 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 20 Dec 2019 17:45:53 -0500 Subject: [PATCH 019/222] Update documentation for current command line switches --- src/Features/Lsif/Generator/README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Features/Lsif/Generator/README.md b/src/Features/Lsif/Generator/README.md index 790c3c2e49672..8b28d4e24fcb7 100644 --- a/src/Features/Lsif/Generator/README.md +++ b/src/Features/Lsif/Generator/README.md @@ -1 +1,17 @@ -This tool consumes a project or solution and generates a Language Server Index Format file per the [LSIF specification](https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md). \ No newline at end of file +This tool consumes a project or solution and generates a Language Server Index Format file per the +[LSIF specification](https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md). + +# Command Line Switches +## `--solution` +The path to the Visual Studio Solution file to process. The LSIF graph for all projects will be outputted. + +## `--output` +Accepts a file path, and writes the results to that file instead of the console output. + +## `--output-format` +Either "Line" (the default) to write out the LSIF where each line in the text is a separate JSON object, or +"JSON" where the LSIF is written out as a single large JSON array. + +## `--log` +Accepts a file path where a log file is written to. The log file contains information regarding how long various +parts of the LSIF generation took. \ No newline at end of file From d6a663fbb3d395c0abf463bfb69b233842da20c8 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 20 Dec 2019 19:35:36 -0500 Subject: [PATCH 020/222] Add a basic unit testing infrastructure and a first basic test --- Roslyn.sln | 7 ++ ...crosoft.CodeAnalysis.Lsif.Generator.csproj | 3 + ...deAnalysis.Lsif.Generator.UnitTests.vbproj | 19 +++++ .../GeneratorTest/ProjectStructureTests.vb | 27 ++++++ .../GeneratorTest/Utilities/TestGenerator.vb | 17 ++++ .../Utilities/TestLsifJsonWriter.vb | 85 +++++++++++++++++++ 6 files changed, 158 insertions(+) create mode 100644 src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj create mode 100644 src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb create mode 100644 src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb create mode 100644 src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb diff --git a/Roslyn.sln b/Roslyn.sln index 5cbe0325d90b7..59664719e7744 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -424,6 +424,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompilersIOperationGenerato EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Lsif.Generator", "src\Features\Lsif\Generator\Microsoft.CodeAnalysis.Lsif.Generator.csproj", "{B9899CF1-E0EB-4599-9E24-6939A04B4979}" EndProject +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.CodeAnalysis.Lsif.Generator.UnitTests", "src\Features\Lsif\GeneratorTest\Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj", "{D15BF03E-04ED-4BEE-A72B-7620F541F4E2}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{1ee8cad3-55f9-4d91-96b2-084641da9a6c}*SharedItemsImports = 5 @@ -1129,6 +1131,10 @@ Global {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Debug|Any CPU.Build.0 = Debug|Any CPU {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.ActiveCfg = Release|Any CPU {B9899CF1-E0EB-4599-9E24-6939A04B4979}.Release|Any CPU.Build.0 = Release|Any CPU + {D15BF03E-04ED-4BEE-A72B-7620F541F4E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D15BF03E-04ED-4BEE-A72B-7620F541F4E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D15BF03E-04ED-4BEE-A72B-7620F541F4E2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D15BF03E-04ED-4BEE-A72B-7620F541F4E2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1325,6 +1331,7 @@ Global {FF38E9C9-7A25-44F0-B2C4-24C9BFD6A8F6} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {D55FB2BD-CC9E-454B-9654-94AF5D910BF7} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {B9899CF1-E0EB-4599-9E24-6939A04B4979} = {3E5FE3DB-45F7-4D83-9097-8F05D3B3AEC6} + {D15BF03E-04ED-4BEE-A72B-7620F541F4E2} = {3E5FE3DB-45F7-4D83-9097-8F05D3B3AEC6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {604E6B91-7BC0-4126-AE07-D4D2FEFC3D29} diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj index eda7a4c776e1b..f688bad21fd2e 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -26,4 +26,7 @@ + + + \ No newline at end of file diff --git a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj new file mode 100644 index 0000000000000..249510315f32b --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj @@ -0,0 +1,19 @@ + + + + + + net472 + Library + + UnitTest + + + + + + + + + + \ No newline at end of file diff --git a/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb b/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb new file mode 100644 index 0000000000000..40e270cf83e3d --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb @@ -0,0 +1,27 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities + +Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests + + Public NotInheritable Class ProjectStructureTests + + Public Async Sub ProjectContainsDocuments() + Dim lsif = Await GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + + + + + )) + + Dim projectVertex = Assert.Single(lsif.Vertices.OfType(Of LsifGraph.Project)) + Dim documentVertices = lsif.GetLinkedVertices(Of LsifGraph.Document)(projectVertex, "contains") + + Assert.Single(documentVertices, Function(d) d.Uri.LocalPath = "Z:\A.cs") + Assert.Single(documentVertices, Function(d) d.Uri.LocalPath = "Z:\B.cs") + End Sub + End Class +End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb new file mode 100644 index 0000000000000..96d8540184ceb --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb @@ -0,0 +1,17 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities + Friend Module TestGenerator + Public Async Function GenerateForWorkspaceAsync(workspace As Workspace) As Task(Of TestLsifJsonWriter) + Dim testLsifJsonWriter = New TestLsifJsonWriter() + Dim generator = New Generator(testLsifJsonWriter) + + For Each Project In workspace.CurrentSolution.Projects + Dim compilation = Await Project.GetCompilationAsync() + Await generator.GenerateForCompilation(compilation, Project.FilePath, Project.LanguageServices) + Next + + Return testLsifJsonWriter + End Function + End Module +End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb new file mode 100644 index 0000000000000..fdfe1d58e3f6d --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb @@ -0,0 +1,85 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +Imports Microsoft.CodeAnalysis.Lsif.Generator.Writing +Imports Xunit + +Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities + ''' + ''' A implementation of for use in unit tests. It does additional validation of the + ''' correctness of the output, And stores the entire output And offers useful helpers to inspect the result. + ''' + Class TestLsifJsonWriter + Implements ILsifJsonWriter + + Private ReadOnly _elementsById As Dictionary(Of Id(Of Element), Element) = New Dictionary(Of Id(Of Element), Element) + Private ReadOnly _edgesByOutVertex As Dictionary(Of Vertex, List(Of Edge)) = New Dictionary(Of Vertex, List(Of Edge)) + + Private Sub ILsifJsonWriter_Write(element As Element) Implements ILsifJsonWriter.Write + ' We intentionally use Add so it'll throw if we have a duplicate ID. + _elementsById.Add(element.Id, element) + + Dim edge = TryCast(element, Edge) + + If edge IsNot Nothing Then + ' Fetch all the out And in vertices, which validates they exist. This ensures we satisfy the rule + ' that an edge can only be written after all the vertices it writes to already exist. + Dim outVertex = GetElementById(edge.OutVertex) + + For Each inVertexId In edge.InVertices + ' We are ignoring the return, but this call implicitly validates the element + ' exists and is of the correct type. + GetElementById(inVertexId) + Next + + ' Record the edge in a map of edges exiting this outVertex. We could do a nested Dictionary + ' for this but that seems a bit expensive when many nodes may only have one item. + Dim edgesForOutVertex As List(Of Edge) = Nothing + If Not _edgesByOutVertex.TryGetValue(outVertex, edgesForOutVertex) Then + edgesForOutVertex = New List(Of Edge)(capacity:=1) + _edgesByOutVertex.Add(outVertex, edgesForOutVertex) + End If + + If (edgesForOutVertex.Any(Function(e) e.Label = edge.Label)) Then + Throw New InvalidOperationException($"The outVertex {outVertex} already has an edge with label {edge.Label}.") + End If + + edgesForOutVertex.Add(edge) + End If + End Sub + + ''' + ''' Returns all the vertices linked to the given vertex by the edge type. + ''' + Public Iterator Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As IEnumerable(Of T) + + Dim edges As List(Of Edge) = Nothing + If _edgesByOutVertex.TryGetValue(vertex, edges) Then + Dim inVerticesId = edges.Where(Function(e) e.Label = edgeLabel).SelectMany(Function(e) e.InVertices) + + For Each inVertexId In inVerticesId + ' This is an unsafe "cast" if you will converting the ID to the expected type; + ' GetElementById checks the real vertex type so thta will stay safe in the end. + Yield GetElementById(Of T)(New Id(Of T)(inVertexId.NumericId)) + Next + End If + End Function + + Public ReadOnly Property Vertices As IEnumerable(Of Vertex) + Get + Return _elementsById.Values.OfType(Of Vertex) + End Get + End Property + + Public Function GetElementById(Of T As Element)(id As Id(Of T)) As T + Dim element As Element = Nothing + + ' TODO: why am I unable to use the extension method As here? + If Not _elementsById.TryGetValue(New Id(Of Element)(id.NumericId), element) Then + Throw New Exception($"Element with ID {id} could not be found.") + End If + + Return Assert.IsAssignableFrom(Of T)(element) + End Function + End Class +End Namespace From 5103827e48bca28f6348468c0bf6adf584070c5a Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 26 Dec 2019 19:10:11 -0500 Subject: [PATCH 021/222] Hand out a separate class for unit test results This keeps the TestLsifJsonWriter as more of an implementation detail with the test helper handing out a TestLsifOutput that holds onto the writer. This also can hold onto the Workspace for other helpers too. --- .../GeneratorTest/ProjectStructureTests.vb | 2 +- .../GeneratorTest/Utilities/TestGenerator.vb | 17 ------- .../GeneratorTest/Utilities/TestLsifOutput.vb | 45 +++++++++++++++++++ 3 files changed, 46 insertions(+), 18 deletions(-) delete mode 100644 src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb create mode 100644 src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb diff --git a/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb b/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb index 40e270cf83e3d..fe6bdcd58e895 100644 --- a/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb +++ b/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb @@ -8,7 +8,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Public NotInheritable Class ProjectStructureTests Public Async Sub ProjectContainsDocuments() - Dim lsif = Await GenerateForWorkspaceAsync( + Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb deleted file mode 100644 index 96d8540184ceb..0000000000000 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestGenerator.vb +++ /dev/null @@ -1,17 +0,0 @@ -' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities - Friend Module TestGenerator - Public Async Function GenerateForWorkspaceAsync(workspace As Workspace) As Task(Of TestLsifJsonWriter) - Dim testLsifJsonWriter = New TestLsifJsonWriter() - Dim generator = New Generator(testLsifJsonWriter) - - For Each Project In workspace.CurrentSolution.Projects - Dim compilation = Await Project.GetCompilationAsync() - Await generator.GenerateForCompilation(compilation, Project.FilePath, Project.LanguageServices) - Next - - Return testLsifJsonWriter - End Function - End Module -End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb new file mode 100644 index 0000000000000..219969ed10e4d --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -0,0 +1,45 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph + +Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities + Friend Class TestLsifOutput + Private ReadOnly _testLsifJsonWriter As TestLsifJsonWriter + Private ReadOnly _workspace As TestWorkspace + + Public Sub New(testLsifJsonWriter As TestLsifJsonWriter, workspace As TestWorkspace) + _testLsifJsonWriter = testLsifJsonWriter + _workspace = workspace + End Sub + + Public Shared Async Function GenerateForWorkspaceAsync(workspace As TestWorkspace) As Task(Of TestLsifOutput) + Dim testLsifJsonWriter = New TestLsifJsonWriter() + Dim generator = New Generator(testLsifJsonWriter) + + For Each project In workspace.CurrentSolution.Projects + Dim compilation = Await project.GetCompilationAsync() + Await generator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices) + Next + + Return New TestLsifOutput(testLsifJsonWriter, workspace) + End Function + + Public Function GetElementById(Of T As Element)(id As Id(Of T)) As T + Return _testLsifJsonWriter.GetElementById(id) + End Function + + ''' + ''' Returns all the vertices linked to the given vertex by the edge type. + ''' + Public Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As IEnumerable(Of T) + Return _testLsifJsonWriter.GetLinkedVertices(Of T)(vertex, edgeLabel) + End Function + + Public ReadOnly Property Vertices As IEnumerable(Of Vertex) + Get + Return _testLsifJsonWriter.Vertices + End Get + End Property + End Class +End Namespace From 3f572a56b54c9fdf02847b18e3bb92efead3ccaa Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 26 Dec 2019 19:58:49 -0500 Subject: [PATCH 022/222] Switch GetLinkedVertices to return an ImmutableArray intsead of an interator This makes debugging a lot easier if you have to debug the test, since there's no lazy evaluation. --- .../Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb | 8 ++++++-- .../Lsif/GeneratorTest/Utilities/TestLsifOutput.vb | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb index fdfe1d58e3f6d..1b10e0a01156a 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb @@ -1,5 +1,6 @@ ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph Imports Microsoft.CodeAnalysis.Lsif.Generator.Writing Imports Xunit @@ -51,7 +52,8 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities ''' ''' Returns all the vertices linked to the given vertex by the edge type. ''' - Public Iterator Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As IEnumerable(Of T) + Public Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As ImmutableArray(Of T) + Dim builder = ImmutableArray.CreateBuilder(Of T) Dim edges As List(Of Edge) = Nothing If _edgesByOutVertex.TryGetValue(vertex, edges) Then @@ -60,9 +62,11 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities For Each inVertexId In inVerticesId ' This is an unsafe "cast" if you will converting the ID to the expected type; ' GetElementById checks the real vertex type so thta will stay safe in the end. - Yield GetElementById(Of T)(New Id(Of T)(inVertexId.NumericId)) + builder.Add(GetElementById(Of T)(New Id(Of T)(inVertexId.NumericId))) Next End If + + Return builder.ToImmutable() End Function Public ReadOnly Property Vertices As IEnumerable(Of Vertex) diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index 219969ed10e4d..8bbcb6378a7d5 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -1,5 +1,6 @@ ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph @@ -32,7 +33,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities ''' ''' Returns all the vertices linked to the given vertex by the edge type. ''' - Public Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As IEnumerable(Of T) + Public Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As ImmutableArray(Of T) Return _testLsifJsonWriter.GetLinkedVertices(Of T)(vertex, edgeLabel) End Function From 01bd3f71cf49894637857cdcdee08b7946fc8424 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 26 Dec 2019 19:59:15 -0500 Subject: [PATCH 023/222] Add tests that a range has a correct moniker and is a reference --- .../Lsif/GeneratorTest/RangeResultSetTests.vb | 55 +++++++++++++++++++ .../GeneratorTest/Utilities/TestLsifOutput.vb | 20 +++++++ 2 files changed, 75 insertions(+) create mode 100644 src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb new file mode 100644 index 0000000000000..77bb1bba1e09a --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -0,0 +1,55 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.VisualStudio.LanguageServer.Protocol + +Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests + + Public NotInheritable Class RangeResultSetTests + Private Const TestProjectAssemblyName As String = "TestProject" + + + + + + Public Async Sub ReferenceMonikerAsync(code As String, expectedMoniker As String) + Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + FilePath="Z:\TestProject.csproj" CommonReferences="true"> + + <%= code %> + + + )) + + Dim rangeVertex = Await lsif.GetSelectedRangeAsync() + Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() + Dim monikerVertex = lsif.GetLinkedVertices(Of LsifGraph.Moniker)(resultSetVertex, "moniker").Single() + + Assert.Equal(expectedMoniker, monikerVertex.Identifier) + End Sub + + + Public Async Sub ReferenceIncludedInReferenceResultAsync() + Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + FilePath="Z:\TestProject.csproj" CommonReferences="true"> + + class C { [|string|] s; } + + + )) + + Dim rangeVertex = Await lsif.GetSelectedRangeAsync() + Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() + Dim referencesVertex = lsif.GetLinkedVertices(Of LsifGraph.ReferenceResult)(resultSetVertex, Methods.TextDocumentReferencesName).Single() + + ' The references vertex should point back to our range + Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of LsifGraph.Range)(referencesVertex, "item")) + Assert.Same(rangeVertex, referencedRange) + End Sub + End Class +End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index 8bbcb6378a7d5..a6bf15d9e3fe7 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -42,5 +42,25 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities Return _testLsifJsonWriter.Vertices End Get End Property + + ''' + ''' Returns the vertex in the output that corresponds to the selected range in the . + ''' + Public Async Function GetSelectedRangeAsync() As Task(Of LsifGraph.Range) + Dim selectedTestDocument = _workspace.Documents.Single(Function(d) d.SelectedSpans.Any()) + Dim selectedDocument = _workspace.CurrentSolution.GetDocument(selectedTestDocument.Id) + Dim selectionTextSpan = selectedTestDocument.SelectedSpans.Single() + Dim selectionRange = Range.FromTextSpan(selectionTextSpan, Await selectedDocument.GetTextAsync()) + + Dim documentVertex = _testLsifJsonWriter.Vertices _ + .OfType(Of LsifGraph.Document) _ + .Where(Function(d) d.Uri.LocalPath = selectedDocument.FilePath) _ + .Single() + + Return _testLsifJsonWriter.GetLinkedVertices(Of Range)(documentVertex, "contains") _ + .Where(Function(r) r.Start = selectionRange.Start AndAlso + r.End = selectionRange.End) _ + .Single() + End Function End Class End Namespace From 01fe5121e430f1e1d354286f0e8cfeecf8035623 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 2 Jan 2020 16:19:54 -0800 Subject: [PATCH 024/222] Don't block multiple edges if the label is "item" We obviously allow multiple of those! --- .../Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb index 1b10e0a01156a..c72d8b7ec18f7 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb @@ -41,8 +41,11 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities _edgesByOutVertex.Add(outVertex, edgesForOutVertex) End If - If (edgesForOutVertex.Any(Function(e) e.Label = edge.Label)) Then - Throw New InvalidOperationException($"The outVertex {outVertex} already has an edge with label {edge.Label}.") + ' It's possible to have more than one item edge, but for anything else we really only expect one. + If edge.Label <> "item" Then + If (edgesForOutVertex.Any(Function(e) e.Label = edge.Label)) Then + Throw New InvalidOperationException($"The outVertex {outVertex} already has an edge with label {edge.Label}.") + End If End If edgesForOutVertex.Add(edge) From 9e290af0516dda4660a66f1f7026da9d9ff8c601 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Mon, 30 Dec 2019 11:45:05 -0700 Subject: [PATCH 025/222] Add support for definition results The interesting bit of this change is it moves the moniker generation logic to the ResultSetTracker -- once a ResultSet is created for either a definition or a reference we want a moniker to be attached. --- src/Features/Lsif/Generator/Generator.cs | 149 ++++++------------ .../Generator/LsifGraph/DefinitionResult.cs | 12 ++ src/Features/Lsif/Generator/LsifGraph/Item.cs | 4 +- .../SymbolHoldingResultSetTracker.cs | 97 +++++++++++- .../Lsif/GeneratorTest/RangeResultSetTests.vb | 26 ++- 5 files changed, 183 insertions(+), 105 deletions(-) create mode 100644 src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 1c6166f56b209..3c7fbc6c2a380 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServices; @@ -32,7 +33,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project // We create a ResultSetTracker to track all top-level symbols in the project. We don't want all writes to immediately go to // the JSON file once we support parallel processing, so we'll accumulate them and then apply at once. var topLevelSymbolsWriter = new InMemoryLsifJsonWriter(); - var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter); + var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter, compilation); foreach (var syntaxTree in compilation.SyntaxTrees) { @@ -64,6 +65,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project var syntaxTree = semanticModel.SyntaxTree; var sourceText = semanticModel.SyntaxTree.GetText(); var syntaxFactsService = languageServices.GetRequiredService(); + var semanticFactsService = languageServices.GetRequiredService(); var documentVertex = new LsifGraph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); @@ -74,7 +76,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project // or methods. We're also going to encounter locals that never leave this document. We don't want those locals being held by // the topLevelSymbolsResultSetTracker, so we'll make another tracker for document local symbols, and then have a delegating // one that picks the correct one of the two. - var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter); + var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter, semanticModel.Compilation); var symbolResultsTracker = new DelegatingResultSetTracker(symbol => { if (symbol.Kind == SymbolKind.Local || @@ -100,6 +102,21 @@ public async Task GenerateForCompilation(Compilation compilation, string project foreach (var syntaxToken in syntaxTree.GetRoot().DescendantTokens(descendIntoTrivia: true)) { + // We'll only create the Range vertex once it's needed, but any number of bits of code might create it first, + // so we'll just make it Lazy. + var lazyRangeVertex = new Lazy(() => + { + var rangeVertex = LsifGraph.Range.FromTextSpan(syntaxToken.Span, sourceText); + + lsifJsonWriter.Write(rangeVertex); + rangeVertices.Add(rangeVertex.GetId()); + + return rangeVertex; + }, LazyThreadSafetyMode.None); + + var declaredSymbol = semanticFactsService.GetDeclaredSymbol(semanticModel, syntaxToken, CancellationToken.None); + ISymbol? referencedSymbol = null; + if (syntaxFactsService.IsBindableToken(syntaxToken)) { var bindableParent = syntaxFactsService.GetBindableParent(syntaxToken); @@ -107,37 +124,40 @@ public async Task GenerateForCompilation(Compilation compilation, string project if (bindableParent != null) { var symbolInfo = semanticModel.GetSymbolInfo(bindableParent); - - if (symbolInfo.Symbol != null) + if (symbolInfo.Symbol != null && IncludeSymbolInReferences(symbolInfo.Symbol)) { - var rangeVertex = LsifGraph.Range.FromTextSpan(syntaxToken.Span, sourceText); - - lsifJsonWriter.Write(rangeVertex); - rangeVertices.Add(rangeVertex.GetId()); - - // For now, we will link the range to the original definition. We'll have to fix this once we start supporting - // hover, since we show different contents for different constructed types there. - var originalDefinition = symbolInfo.Symbol.OriginalDefinition; - var originalDefinitionResultSetId = symbolResultsTracker.GetResultSetIdForSymbol(originalDefinition); - lsifJsonWriter.Write(Edge.Create("next", rangeVertex.GetId(), originalDefinitionResultSetId)); - - if (IncludeSymbolInReferences(originalDefinition)) - { - // Create the link from the references back to this range - var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(originalDefinition, Methods.TextDocumentReferencesName, () => new ReferenceResult()); - lsifJsonWriter.Write(new Item(referenceResultsId.As(), rangeVertex.GetId(), documentVertex.GetId(), property: "references")); - - // Attach the moniker if needed - if (symbolResultsTracker.ResultSetNeedsInformationalEdgeAdded(originalDefinition, "moniker")) - { - var monikerVertex = CreateMonikerVertexForSymbol(originalDefinition, semanticModel.Compilation); - lsifJsonWriter.Write(monikerVertex); - lsifJsonWriter.Write(Edge.Create("moniker", originalDefinitionResultSetId, monikerVertex.GetId())); - } - } + referencedSymbol = symbolInfo.Symbol; } } } + + if (declaredSymbol != null || referencedSymbol != null) + { + // For now, we will link the range to the original definition, preferring the definition, as this is the symbol + // that would be used if we invoke a feature on this range. This is analogous to the logic in + // SymbolFinder.FindSymbolAtPositionAsync where if a token is both a reference and definition we'll prefer the + // definition. Once we start supporting hover we'll hae to remove the "original defintion" part of this, since + // since we show different contents for different constructed types there. + var symbolForLinkedResultSet = (declaredSymbol ?? referencedSymbol)!.OriginalDefinition; + var symbolForLinkedResultSetId = symbolResultsTracker.GetResultSetIdForSymbol(symbolForLinkedResultSet); + lsifJsonWriter.Write(Edge.Create("next", lazyRangeVertex.Value.GetId(), symbolForLinkedResultSetId)); + + if (declaredSymbol != null) + { + var definitionResultsId = symbolResultsTracker.GetResultIdForSymbol(declaredSymbol, Methods.TextDocumentDefinitionName, () => new DefinitionResult()); + lsifJsonWriter.Write(new Item(definitionResultsId.As(), lazyRangeVertex.Value.GetId(), documentVertex.GetId())); + } + + if (referencedSymbol != null) + { + // Create the link from the references back to this range. Note: this range can be reference to a + // symbol but the range can point a different symbol's resultSet. This can happen if the token is + // both a definition of a symbol (where we will point to the definition) but also a reference to some + // other symbol. + var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(referencedSymbol.OriginalDefinition, Methods.TextDocumentReferencesName, () => new ReferenceResult()); + lsifJsonWriter.Write(new Item(referenceResultsId.As(), lazyRangeVertex.Value.GetId(), documentVertex.GetId(), property: "references")); + } + } } lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices)); @@ -148,20 +168,6 @@ public async Task GenerateForCompilation(Compilation compilation, string project private static bool IncludeSymbolInReferences(ISymbol symbol) { - // Skip built in-operators. We could pick some sort of moniker for these, but I doubt anybody really needs to search for all uses of - // + in the world's projects at once. - if (symbol is IMethodSymbol method && method.MethodKind == MethodKind.BuiltinOperator) - { - return false; - } - - // TODO: some symbols for things some things in crefs don't have a ContainingAssembly. We'll skip those for now but do - // want those to work. - if (symbol.Kind != SymbolKind.Namespace && symbol.ContainingAssembly == null) - { - return false; - } - // Skip some type of symbols that don't really make sense if (symbol.Kind == SymbolKind.ArrayType || symbol.Kind == SymbolKind.Discard || @@ -173,63 +179,6 @@ private static bool IncludeSymbolInReferences(ISymbol symbol) return true; } - private static Moniker CreateMonikerVertexForSymbol(ISymbol symbol, Compilation compilation) - { - // This uses the existing format that earlier prototypes of the Roslyn LSIF tool implemented; a different format may make more sense long term, but changing the - // moniker makes it difficult for other systems that have older LSIF indexes to the connect the two indexes together. - - // Namespaces are special: they're just a name that exists in the ether between compilations - if (symbol.Kind == SymbolKind.Namespace) - { - return new Moniker("dotnet-namespace", symbol.ToDisplayString()); - } - - string symbolMoniker = symbol.ContainingAssembly.Name + "#"; - - if (symbol.Kind == SymbolKind.Local || - symbol.Kind == SymbolKind.Parameter || - symbol.Kind == SymbolKind.RangeVariable || - symbol.Kind == SymbolKind.Label) - { - symbolMoniker += GetRequiredDocumentationCommentId(symbol.ContainingSymbol) + "#" + symbol.Name; - } - else - { - symbolMoniker += GetRequiredDocumentationCommentId(symbol); - } - - string kind; - - if (symbol.Kind == SymbolKind.Local || - symbol.Kind == SymbolKind.RangeVariable || - symbol.Kind == SymbolKind.Label) - { - kind = "local"; - } - else if (symbol.ContainingAssembly.Equals(compilation.Assembly)) - { - kind = "export"; - } - else - { - kind = "import"; - } - - return new Moniker("dotnet-xml-doc", symbolMoniker, kind); - - static string GetRequiredDocumentationCommentId(ISymbol symbol) - { - var documentationCommentId = symbol.GetDocumentationCommentId(); - - if (documentationCommentId == null) - { - throw new Exception($"Unable to get documentation comment ID for {symbol.ToDisplayString()}"); - } - - return documentationCommentId; - } - } - private static string GetLanguageKind(string languageName) { return languageName switch diff --git a/src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs b/src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs new file mode 100644 index 0000000000000..e8a058f7f727c --- /dev/null +++ b/src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +{ + internal sealed class DefinitionResult : Vertex + { + public DefinitionResult() + : base(label: "definitionResult") + { + } + } +} diff --git a/src/Features/Lsif/Generator/LsifGraph/Item.cs b/src/Features/Lsif/Generator/LsifGraph/Item.cs index dad6ec3357679..494f026182f5f 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Item.cs +++ b/src/Features/Lsif/Generator/LsifGraph/Item.cs @@ -7,9 +7,9 @@ internal sealed class Item : Edge { public Id Document { get; } - public string Property { get; } + public string? Property { get; } - public Item(Id outVertex, Id range, Id document, string property) + public Item(Id outVertex, Id range, Id document, string? property = null) : base(label: "item", outVertex, new[] { range.As() }) { Document = document; diff --git a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 1bf15734cd7d4..14e0e85f35380 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -12,9 +12,18 @@ internal sealed class SymbolHoldingResultSetTracker : IResultSetTracker private readonly Dictionary _symbolToResultSetId = new Dictionary(); private readonly ILsifJsonWriter _lsifJsonWriter; - public SymbolHoldingResultSetTracker(ILsifJsonWriter lsifJsonWriter) + /// + /// The compilation which we are analyzing. When we make ResultSets, we attach monikers to them, and those + /// monikers express an import/export concept for symbols being consumed from another project. We must distinguish + /// from source symbols that come from the project being analyzed versus symbols from referenced compilations, so + /// we can't just use to make the determination. + /// + private readonly Compilation _sourceCompilation; + + public SymbolHoldingResultSetTracker(ILsifJsonWriter lsifJsonWriter, Compilation sourceCompilation) { _lsifJsonWriter = lsifJsonWriter; + _sourceCompilation = sourceCompilation; } private TrackedResultSet GetTrackedResultSet(ISymbol symbol) @@ -25,11 +34,97 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) _lsifJsonWriter.Write(resultSet); trackedResultSet = new TrackedResultSet(resultSet.GetId()); _symbolToResultSetId.Add(symbol, trackedResultSet); + + // Since we're creating a ResultSet for a symbol for the first time, let's also attach the moniker. We only generate + // monikers for original definitions as we don't have a moniker system for those, but also because the place where + // monikers are needed -- cross-solution find references and go to definition -- only operates on original definitions + // anyways. + if (symbol.OriginalDefinition.Equals(symbol)) + { + var monikerVertex = TryCreateMonikerVertexForSymbol(symbol); + + if (monikerVertex != null) + { + _lsifJsonWriter.Write(monikerVertex); + _lsifJsonWriter.Write(Edge.Create("moniker", trackedResultSet.Id, monikerVertex.GetId())); + } + } } return trackedResultSet; } + private Moniker? TryCreateMonikerVertexForSymbol(ISymbol symbol) + { + // This uses the existing format that earlier prototypes of the Roslyn LSIF tool implemented; a different format may make more sense long term, but changing the + // moniker makes it difficult for other systems that have older LSIF indexes to the connect the two indexes together. + + // Skip built in-operators. We could pick some sort of moniker for these, but I doubt anybody really needs to search for all uses of + // + in the world's projects at once. + if (symbol is IMethodSymbol method && method.MethodKind == MethodKind.BuiltinOperator) + { + return null; + } + + // TODO: some symbols for things some things in crefs don't have a ContainingAssembly. We'll skip those for now but do + // want those to work. + if (symbol.Kind != SymbolKind.Namespace && symbol.ContainingAssembly == null) + { + return null; + } + + // Namespaces are special: they're just a name that exists in the ether between compilations + if (symbol.Kind == SymbolKind.Namespace) + { + return new Moniker("dotnet-namespace", symbol.ToDisplayString()); + } + + string symbolMoniker = symbol.ContainingAssembly.Name + "#"; + + if (symbol.Kind == SymbolKind.Local || + symbol.Kind == SymbolKind.Parameter || + symbol.Kind == SymbolKind.RangeVariable || + symbol.Kind == SymbolKind.Label) + { + symbolMoniker += GetRequiredDocumentationCommentId(symbol.ContainingSymbol) + "#" + symbol.Name; + } + else + { + symbolMoniker += GetRequiredDocumentationCommentId(symbol); + } + + string kind; + + if (symbol.Kind == SymbolKind.Local || + symbol.Kind == SymbolKind.RangeVariable || + symbol.Kind == SymbolKind.Label) + { + kind = "local"; + } + else if (symbol.ContainingAssembly.Equals(_sourceCompilation.Assembly)) + { + kind = "export"; + } + else + { + kind = "import"; + } + + return new Moniker("dotnet-xml-doc", symbolMoniker, kind); + + static string GetRequiredDocumentationCommentId(ISymbol symbol) + { + var documentationCommentId = symbol.GetDocumentationCommentId(); + + if (documentationCommentId == null) + { + throw new Exception($"Unable to get documentation comment ID for {symbol.ToDisplayString()}"); + } + + return documentationCommentId; + } + } + public Id GetResultSetIdForSymbol(ISymbol symbol) { return GetTrackedResultSet(symbol).Id; diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb index 77bb1bba1e09a..a28cdd613f328 100644 --- a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -13,6 +13,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests + Public Async Sub ReferenceMonikerAsync(code As String, expectedMoniker As String) Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( @@ -26,9 +27,30 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Dim rangeVertex = Await lsif.GetSelectedRangeAsync() Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() - Dim monikerVertex = lsif.GetLinkedVertices(Of LsifGraph.Moniker)(resultSetVertex, "moniker").Single() + Dim monikerVertex = lsif.GetLinkedVertices(Of LsifGraph.Moniker)(resultSetVertex, "moniker").SingleOrDefault() - Assert.Equal(expectedMoniker, monikerVertex.Identifier) + Assert.Equal(expectedMoniker, monikerVertex?.Identifier) + End Sub + + + Public Async Sub DefinitionIncludedInDefinitionResultAsync() + Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + FilePath="Z:\TestProject.csproj" CommonReferences="true"> + + class [|C|] { } + + + )) + + Dim rangeVertex = Await lsif.GetSelectedRangeAsync() + Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() + Dim definitionsVertex = lsif.GetLinkedVertices(Of LsifGraph.DefinitionResult)(resultSetVertex, Methods.TextDocumentDefinitionName).Single() + + ' The definition vertex should point back to our range + Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of LsifGraph.Range)(definitionsVertex, "item")) + Assert.Same(rangeVertex, referencedRange) End Sub From b7f6616230e83e6062ac26cdd2367525a340bd47 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 2 Jan 2020 17:54:25 -0800 Subject: [PATCH 026/222] Don't try to create monikers for aliases --- .../ResultSetTracking/SymbolHoldingResultSetTracker.cs | 6 ++++++ src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb | 1 + 2 files changed, 7 insertions(+) diff --git a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 14e0e85f35380..33cda1b8388ac 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -66,6 +66,12 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) return null; } + // We don't have a moniker format for aliases for now. They're local to a file so it's not clear if we really need one...? + if (symbol.Kind == SymbolKind.Alias) + { + return null; + } + // TODO: some symbols for things some things in crefs don't have a ContainingAssembly. We'll skip those for now but do // want those to work. if (symbol.Kind != SymbolKind.Namespace && symbol.ContainingAssembly == null) diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb index a28cdd613f328..569dc7696abd0 100644 --- a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -14,6 +14,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests + Public Async Sub ReferenceMonikerAsync(code As String, expectedMoniker As String) Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( From 8eb3fa9fd612af2d7c980d050e58e1e57c9aad0f Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Mon, 6 Jan 2020 11:31:47 -0800 Subject: [PATCH 027/222] Change moniker generation logic to simply never generate local monikers There's no reason for us to try generating them since nothing was ever using them downstream. --- .../SymbolHoldingResultSetTracker.cs | 27 ++++++++----------- .../Lsif/GeneratorTest/RangeResultSetTests.vb | 1 + 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 33cda1b8388ac..af927d141e582 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -59,15 +59,19 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) // This uses the existing format that earlier prototypes of the Roslyn LSIF tool implemented; a different format may make more sense long term, but changing the // moniker makes it difficult for other systems that have older LSIF indexes to the connect the two indexes together. - // Skip built in-operators. We could pick some sort of moniker for these, but I doubt anybody really needs to search for all uses of - // + in the world's projects at once. - if (symbol is IMethodSymbol method && method.MethodKind == MethodKind.BuiltinOperator) + // Skip all local things that cannot escape outside of a single file: downstream consumers simply treat this as meaning a references/definition result + // doesn't need to be stitched together across files or multiple projects or repositories. + if (symbol.Kind == SymbolKind.Local || + symbol.Kind == SymbolKind.RangeVariable || + symbol.Kind == SymbolKind.Label || + symbol.Kind == SymbolKind.Alias) { return null; } - // We don't have a moniker format for aliases for now. They're local to a file so it's not clear if we really need one...? - if (symbol.Kind == SymbolKind.Alias) + // Skip built in-operators. We could pick some sort of moniker for these, but I doubt anybody really needs to search for all uses of + // + in the world's projects at once. + if (symbol is IMethodSymbol method && method.MethodKind == MethodKind.BuiltinOperator) { return null; } @@ -87,10 +91,7 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) string symbolMoniker = symbol.ContainingAssembly.Name + "#"; - if (symbol.Kind == SymbolKind.Local || - symbol.Kind == SymbolKind.Parameter || - symbol.Kind == SymbolKind.RangeVariable || - symbol.Kind == SymbolKind.Label) + if (symbol.Kind == SymbolKind.Parameter) { symbolMoniker += GetRequiredDocumentationCommentId(symbol.ContainingSymbol) + "#" + symbol.Name; } @@ -101,13 +102,7 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) string kind; - if (symbol.Kind == SymbolKind.Local || - symbol.Kind == SymbolKind.RangeVariable || - symbol.Kind == SymbolKind.Label) - { - kind = "local"; - } - else if (symbol.ContainingAssembly.Equals(_sourceCompilation.Assembly)) + if (symbol.ContainingAssembly.Equals(_sourceCompilation.Assembly)) { kind = "export"; } diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb index 569dc7696abd0..e2c460bfe590f 100644 --- a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -13,6 +13,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests + Public Async Sub ReferenceMonikerAsync(code As String, expectedMoniker As String) From dcff247c58cfc26a085a7f30aab56f9a171696a4 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Mon, 6 Jan 2020 15:42:17 -0800 Subject: [PATCH 028/222] Add support for a --compiler-invocation switch to create Compilations For some build systems or environments, rather than having the LSIF tool run MSBuildWorkspace we'd rather it just reuse an existing compiler invocation that was previously logged. For example, if you know the command line string that was passed to the compiler as a part of a build, you can do the LSIF analysis later without having to run MSBuild. This is handy for non-MSBuild-based build systems, or in some distributed build systems which supports the concept of doing analyzer- like things on different machines in parallel with the main build. This adds a new switch, --compiler-invocation that points to a JSON file that contains: - Command line switches. - The path to the project file - Path mapping information The latter is useful if you are trying to run this analysis on a different machine than the original build happened on; for example, if the command line switches were on a machine where your source was under S:\Source, and now your machine has the same sources, but under S:\Source2, the JSON file can contain the original command line string but we'll map everything when producing the compilation. --- .../Lsif/Generator/CompilerInvocation.cs | 177 ++++++++++++++++++ src/Features/Lsif/Generator/Program.cs | 39 +++- src/Features/Lsif/Generator/README.md | 13 +- .../GeneratorTest/CompilerInvocationTests.vb | 150 +++++++++++++++ 4 files changed, 371 insertions(+), 8 deletions(-) create mode 100644 src/Features/Lsif/Generator/CompilerInvocation.cs create mode 100644 src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb diff --git a/src/Features/Lsif/Generator/CompilerInvocation.cs b/src/Features/Lsif/Generator/CompilerInvocation.cs new file mode 100644 index 0000000000000..b2fb42c2d5a58 --- /dev/null +++ b/src/Features/Lsif/Generator/CompilerInvocation.cs @@ -0,0 +1,177 @@ +// 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 System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Newtonsoft.Json; + +namespace Microsoft.CodeAnalysis.Lsif.Generator +{ + internal class CompilerInvocation + { + public Compilation Compilation { get; } + public HostLanguageServices LanguageServices { get; internal set; } + public string ProjectFilePath { get; internal set; } + + public CompilerInvocation(Compilation compilation, HostLanguageServices languageServices, string projectFilePath) + { + Compilation = compilation; + LanguageServices = languageServices; + ProjectFilePath = projectFilePath; + } + + public static async Task CreateFromJsonAsync(string jsonContents) + { + var invocationInfo = JsonConvert.DeserializeObject(jsonContents); + + // We will use a Workspace to simplify the creation of the compilation, but will be careful not to return the Workspace instance from this class. + // We will still provide the language services which are used by the generator itself, but we don't tie it to a Workspace object so we can + // run this as an in-proc source generator if one day desired. + var workspace = new AdhocWorkspace(); + + var languageName = GetLanguageName(invocationInfo); + var languageServices = workspace.Services.GetLanguageServices(languageName); + + var mapPath = GetPathMapper(invocationInfo); + + var splitCommandLine = CommandLineParser.SplitCommandLineIntoArguments(invocationInfo.Arguments, removeHashComments: false).ToList(); + + // Unfortunately for us there are a few paths that get directly read by the command line parse which we need to remap, + // such as /ruleset files. So let's go through and process them now. + for (int i = 0; i < splitCommandLine.Count; i++) + { + const string RuleSetSwitch = "/ruleset:"; + + if (splitCommandLine[i].StartsWith(RuleSetSwitch, StringComparison.Ordinal)) + { + string rulesetPath = splitCommandLine[i].Substring(RuleSetSwitch.Length); + + bool quoted = rulesetPath.Length > 2 && + rulesetPath.StartsWith("\"", StringComparison.Ordinal) && + rulesetPath.EndsWith("\"", StringComparison.Ordinal); + + if (quoted) + { + rulesetPath = rulesetPath.Substring(1, rulesetPath.Length - 2); + } + + rulesetPath = mapPath(rulesetPath); + + if (quoted) + { + rulesetPath = "\"" + rulesetPath + "\""; + } + + splitCommandLine[i] = RuleSetSwitch + rulesetPath; + } + } + + var commandLineParserService = languageServices.GetRequiredService(); + var parsedCommandLine = commandLineParserService.Parse(splitCommandLine, Path.GetDirectoryName(invocationInfo.ProjectFilePath), isInteractive: false, sdkDirectory: null); + + var projectId = ProjectId.CreateNewId(invocationInfo.ProjectFilePath); + + DocumentInfo CreateDocumentInfo(string unmappedPath) + { + var mappedPath = mapPath(unmappedPath); + return DocumentInfo.Create( + DocumentId.CreateNewId(projectId, mappedPath), + name: mappedPath, + filePath: mappedPath, + loader: new FileTextLoader(mappedPath, parsedCommandLine.Encoding)); + } + + var projectInfo = ProjectInfo.Create( + projectId, + VersionStamp.Default, + name: Path.GetFileNameWithoutExtension(invocationInfo.ProjectFilePath), + assemblyName: parsedCommandLine.CompilationName, + language: languageName, + filePath: invocationInfo.ProjectFilePath, + outputFilePath: parsedCommandLine.OutputFileName, + parsedCommandLine.CompilationOptions, + parsedCommandLine.ParseOptions, + parsedCommandLine.SourceFiles.Select(s => CreateDocumentInfo(unmappedPath: s.Path)), + metadataReferences: parsedCommandLine.MetadataReferences.Select(r => MetadataReference.CreateFromFile(mapPath(r.Reference), r.Properties)), + additionalDocuments: parsedCommandLine.AdditionalFiles.Select(f => CreateDocumentInfo(unmappedPath: f.Path))) + .WithAnalyzerConfigDocuments(parsedCommandLine.AnalyzerConfigPaths.Select(CreateDocumentInfo)); + + workspace.AddProject(projectInfo); + + var compilation = await workspace.CurrentSolution.GetProject(projectId)!.GetRequiredCompilationAsync(CancellationToken.None); + + return new CompilerInvocation(compilation, languageServices, invocationInfo.ProjectFilePath); + } + + private static string GetLanguageName(CompilerInvocationInfo invocationInfo) + { + return invocationInfo.Tool switch + { + "csc" => LanguageNames.CSharp, + "vbc" => LanguageNames.VisualBasic, + _ => throw new NotSupportedException($"Tool {invocationInfo.Tool} is not supported."), + }; + } + + /// + /// Given the JSON description, returns a function that will map paths from the original paths to the current paths. + /// + private static Func GetPathMapper(CompilerInvocationInfo invocationInfo) + { + return unmappedPath => + { + foreach (var potentialPathMapping in invocationInfo.PathMappings) + { + // If it's just a file name being mapped, just a direct map + if (unmappedPath.Equals(potentialPathMapping.From, StringComparison.OrdinalIgnoreCase)) + { + return potentialPathMapping.To; + } + + // Map arbitrary contents under subdirectories + var fromWithDirectorySuffix = potentialPathMapping.From.EndsWith("\\", StringComparison.OrdinalIgnoreCase) ? potentialPathMapping.From : potentialPathMapping.From + "\\"; + + if (unmappedPath.StartsWith(fromWithDirectorySuffix, StringComparison.OrdinalIgnoreCase)) + { + // Trim off any leading \, which would happen if you have a path like C:\Directory\\File.cs with a double slash, and happen to be + // mapping C:\Directory somewhere. + string relativePath = unmappedPath.Substring(fromWithDirectorySuffix.Length).TrimStart('\\'); + + return Path.Combine(potentialPathMapping.To, relativePath); + } + } + + return unmappedPath; + }; + } + + /// + /// A simple data class that represents the schema for JSON serialization. + /// + private sealed class CompilerInvocationInfo + { +#nullable disable // this class is used for deserialization by Newtonsoft.Json, so we don't really need warnings about this class itself + + public string Tool { get; set; } + + public string Arguments { get; set; } + + public string ProjectFilePath { get; set; } + + public List PathMappings { get; set; } = new List(); + + public sealed class PathMapping + { + public string From { get; set; } + public string To { get; set; } + } + +#nullable restore + } + } +} diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 757c1a32798c0..07f7126f12e6b 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -19,18 +19,19 @@ public static Task Main(string[] args) { var generateCommand = new RootCommand("generates an LSIF file") { - new Option("--solution", "input solution file") { Argument = new Argument().ExistingOnly(), Required = true }, + new Option("--solution", "input solution file") { Argument = new Argument().ExistingOnly() }, + new Option("--compiler-invocation", "path to a .json file that contains the information for a csc/vbc invocation") { Argument = new Argument().ExistingOnly() }, new Option("--output", "file to write the LSIF output to, instead of the console") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() }, new Option("--output-format", "format of LSIF output") { Argument = new Argument(defaultValue: () => LsifFormat.Line) }, new Option("--log", "file to write a log to") { Argument = new Argument(defaultValue: () => null).LegalFilePathsOnly() } }; - generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); + generateCommand.Handler = CommandHandler.Create((Func)GenerateAsync); return generateCommand.InvokeAsync(args); } - private static async Task GenerateAsync(FileInfo solution, string? output, LsifFormat outputFormat, string? log) + private static async Task GenerateAsync(FileInfo? solution, FileInfo? compilerInvocation, string? output, LsifFormat outputFormat, string? log) { // If we have an output file, we'll write to that, else we'll use Console.Out using StreamWriter? outputFile = output != null ? new StreamWriter(output) : null; @@ -40,7 +41,19 @@ private static async Task GenerateAsync(FileInfo solution, string? output, LsifF try { - await GenerateAsync(solution, outputWriter, outputFormat, logFile); + // Exactly one of "solution" or "compilerInvocation" should be specified + if (solution != null && compilerInvocation == null) + { + await GenerateFromSolutionAsync(solution, outputWriter, outputFormat, logFile); + } + else if (compilerInvocation != null && solution == null) + { + await GenerateFromCompilerInvocationAsync(compilerInvocation, outputWriter, outputFormat, logFile); + } + else + { + throw new Exception("Exactly one of either a solution path or a compiler invocation path should be supplied."); + } } catch (Exception e) { @@ -54,7 +67,7 @@ private static async Task GenerateAsync(FileInfo solution, string? output, LsifF await logFile.WriteLineAsync("Generation complete."); } - private static async Task GenerateAsync(FileInfo solutionFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) + private static async Task GenerateFromSolutionAsync(FileInfo solutionFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) { await logFile.WriteLineAsync($"Loading {solutionFile.FullName}..."); @@ -94,5 +107,21 @@ private static async Task GenerateAsync(FileInfo solutionFile, TextWriter output await logFile.WriteLineAsync($"Total time spent in the generation phase for all projects, excluding compilation fetch time: {totalTimeInGenerationPhase.ToDisplayString()}"); await logFile.WriteLineAsync($"Total time spent in the generation phase for all projects, including compilation fetch time: {totalTimeInGenerationAndCompilationFetchStopwatch.Elapsed.ToDisplayString()}"); } + + private static async Task GenerateFromCompilerInvocationAsync(FileInfo compilerInvocationFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) + { + await logFile.WriteLineAsync($"Processing compiler invocation from {compilerInvocationFile.FullName}..."); + + var compilerInvocationLoadStopwatch = Stopwatch.StartNew(); + var compilerInvocation = await CompilerInvocation.CreateFromJsonAsync(File.ReadAllText(compilerInvocationFile.FullName)); + await logFile.WriteLineAsync($"Load of the project completed in {compilerInvocationLoadStopwatch.Elapsed.ToDisplayString()}."); + + var generationStopwatch = Stopwatch.StartNew(); + using var lsifWriter = new TextLsifJsonWriter(outputWriter, outputFormat); + var lsifGenerator = new Generator(lsifWriter); + + await lsifGenerator.GenerateForCompilation(compilerInvocation.Compilation, compilerInvocation.ProjectFilePath, compilerInvocation.LanguageServices); + await logFile.WriteLineAsync($"Generation for {compilerInvocation.ProjectFilePath} completed in {generationStopwatch.Elapsed.ToDisplayString()}."); + } } } diff --git a/src/Features/Lsif/Generator/README.md b/src/Features/Lsif/Generator/README.md index 8b28d4e24fcb7..27f9b6ab715e4 100644 --- a/src/Features/Lsif/Generator/README.md +++ b/src/Features/Lsif/Generator/README.md @@ -2,16 +2,23 @@ [LSIF specification](https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md). # Command Line Switches -## `--solution` +## Specifying the Project to Process +### `--solution` The path to the Visual Studio Solution file to process. The LSIF graph for all projects will be outputted. -## `--output` +### `--compiler-invocation` +Specifies a path to a JSON file that contains the information of a compiler invocation. This JSON file includes the compiler that was ran, the command string passed, and path information. This allows you to generate an LSIF file that +matches the same setup as an actual build without the tool having to run MSBuild itself to regreate the compiler command line string. + +## Output Files + +### `--output` Accepts a file path, and writes the results to that file instead of the console output. ## `--output-format` Either "Line" (the default) to write out the LSIF where each line in the text is a separate JSON object, or "JSON" where the LSIF is written out as a single large JSON array. -## `--log` +### `--log` Accepts a file path where a log file is written to. The log file contains information regarding how long various parts of the LSIF generation took. \ No newline at end of file diff --git a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb new file mode 100644 index 0000000000000..1c951f4680538 --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb @@ -0,0 +1,150 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Test.Utilities + +Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests + + Public Class CompilerInvocationTests + + Public Async Sub TestCSharpProject() + ' PortableExecutableReference.CreateFromFile implicitly reads the file so the file must exist. + Dim referencePath = GetType(Object).Assembly.Location + + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""csc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG /reference:" + referencePath.Replace("\", "\\") + " Z:\\SourceFile.cs /target:library /out:Z:\\Output.dll"", + ""projectFilePath"": ""Z:\\Project.csproj"", + ""sourceRootPath"": ""Z:\\"" + }") + + Assert.Equal(LanguageNames.CSharp, compilerInvocation.Compilation.Language) + Assert.Equal("Z:\Project.csproj", compilerInvocation.ProjectFilePath) + Assert.Equal(OutputKind.DynamicallyLinkedLibrary, compilerInvocation.Compilation.Options.OutputKind) + + Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) + Assert.Equal("Z:\SourceFile.cs", syntaxTree.FilePath) + Assert.Equal("DEBUG", Assert.Single(syntaxTree.Options.PreprocessorSymbolNames)) + + Dim metadataReference = Assert.Single(compilerInvocation.Compilation.References) + + Assert.Equal(referencePath, DirectCast(metadataReference, PortableExecutableReference).FilePath) + End Sub + + + Public Async Sub TestVisualBasicProject() + ' PortableExecutableReference.CreateFromFile implicitly reads the file so the file must exist. + Dim referencePath = GetType(Object).Assembly.Location + + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""vbc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG /reference:" + referencePath.Replace("\", "\\") + " Z:\\SourceFile.vb /target:library /out:Z:\\Output.dll"", + ""projectFilePath"": ""Z:\\Project.vbproj"", + ""sourceRootPath"": ""Z:\\"" + }") + + Assert.Equal(LanguageNames.VisualBasic, compilerInvocation.Compilation.Language) + Assert.Equal("Z:\Project.vbproj", compilerInvocation.ProjectFilePath) + Assert.Equal(OutputKind.DynamicallyLinkedLibrary, compilerInvocation.Compilation.Options.OutputKind) + + Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) + Assert.Equal("Z:\SourceFile.vb", syntaxTree.FilePath) + Assert.Contains("DEBUG", syntaxTree.Options.PreprocessorSymbolNames) + + Dim metadataReference = Assert.Single(compilerInvocation.Compilation.References) + + Assert.Equal(referencePath, DirectCast(metadataReference, PortableExecutableReference).FilePath) + End Sub + + + Public Async Sub TestSourceFilePathMapping() + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""csc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\SourceFile.cs /target:library /out:F:\\Output.dll"", + ""projectFilePath"": ""F:\\Project.csproj"", + ""sourceRootPath"": ""F:\\"", + ""pathMappings"": [ + { + ""from"": ""F:\\"", + ""to"": ""T:\\"" + }] + }") + + Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) + + Assert.Equal("T:\SourceFile.cs", syntaxTree.FilePath) + End Sub + + + Public Async Sub TestSourceFilePathMappingWithSubdirectoriesWithoutTrailingSlashes() + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""csc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\Directory\\SourceFile.cs /target:library /out:F:\\Output.dll"", + ""projectFilePath"": ""F:\\Project.csproj"", + ""sourceRootPath"": ""F:\\"", + ""pathMappings"": [ + { + ""from"": ""F:\\Directory"", + ""to"": ""T:\\Directory"" + }] + }") + + Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) + + Assert.Equal("T:\Directory\SourceFile.cs", syntaxTree.FilePath) + End Sub + + + Public Async Sub TestSourceFilePathMappingWithSubdirectoriesWithDoubleSlashesInFilePath() + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""csc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\Directory\\\\SourceFile.cs /target:library /out:F:\\Output.dll"", + ""projectFilePath"": ""F:\\Project.csproj"", + ""sourceRootPath"": ""F:\\"", + ""pathMappings"": [ + { + ""from"": ""F:\\Directory"", + ""to"": ""T:\\Directory"" + }] + }") + + Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) + + Assert.Equal("T:\Directory\SourceFile.cs", syntaxTree.FilePath) + End Sub + + + Public Async Sub TestRuleSetPathMapping() + Const RuleSetContents = " + + + + +" + + Using ruleSet = New DisposableFile(extension:=".ruleset") + ruleSet.WriteAllText(RuleSetContents) + + ' We will test that if we redirect the ruleset to the temporary file that we wrote that the values are still read. + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""csc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG /ruleset:F:\\Ruleset.ruleset /out:Output.dll"", + ""projectFilePath"": ""F:\\Project.csproj"", + ""sourceRootPath"": ""F:\\"", + ""pathMappings"": [ + { + ""from"": ""F:\\Ruleset.ruleset"", + ""to"": """ + ruleSet.Path.Replace("\", "\\") + """ + }] + }") + + Assert.Equal(ReportDiagnostic.Warn, compilerInvocation.Compilation.Options.SpecificDiagnosticOptions("CA1001")) + End Using + End Sub + End Class +End Namespace From 297cf4de8a7352fd696b84cc0e3f9f716d0f1904 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 9 Jan 2020 12:46:31 -0800 Subject: [PATCH 029/222] Pick the highest version of MSBuild on the machine MSBuildLocator.RegisterDefault picks "the first" which could pick 2017 if you have both 2017 and 2019 installed. --- src/Features/Lsif/Generator/Program.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 07f7126f12e6b..68ff6422ec6f3 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -6,6 +6,7 @@ using System.CommandLine.Invocation; using System.Diagnostics; using System.IO; +using System.Linq; using System.Threading.Tasks; using Microsoft.Build.Locator; using Microsoft.CodeAnalysis.Lsif.Generator.Writing; @@ -69,11 +70,23 @@ private static async Task GenerateAsync(FileInfo? solution, FileInfo? compilerIn private static async Task GenerateFromSolutionAsync(FileInfo solutionFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) { + // Make sure we pick the highest version + var msbuildInstance = MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(i => i.Version).FirstOrDefault(); + if (msbuildInstance == null) + { + throw new Exception("No MSBuild instances installed with Visual Studio could be found."); + } + else + { + await logFile.WriteLineAsync($"Using the MSBuild instance located at {msbuildInstance.MSBuildPath}."); + } + + MSBuildLocator.RegisterInstance(msbuildInstance); + await logFile.WriteLineAsync($"Loading {solutionFile.FullName}..."); var solutionLoadStopwatch = Stopwatch.StartNew(); - MSBuildLocator.RegisterDefaults(); var msbuildWorkspace = MSBuildWorkspace.Create(); var solution = await msbuildWorkspace.OpenSolutionAsync(solutionFile.FullName); From c5cdb48e76f99d9fbd9fd4cbfe9c42368d9936c6 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 17 Jan 2020 16:24:48 -0800 Subject: [PATCH 030/222] Package the LSIF tool into a NuGet package --- ...crosoft.CodeAnalysis.Lsif.Generator.csproj | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj index f688bad21fd2e..78f24bf57b274 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj @@ -10,22 +10,63 @@ AnyCPU $(RoslynPortableRuntimeIdentifiers) enable + + + true + true + tools + $(TargetsForTfmSpecificContentInPackage);_GetFilesToPackage + + + $(NoWarn);NU5128 + + + <_ResolveReferenceDependencies>true + + Microsoft.CodeAnalysis.Lsif.Generator + A tool to consume projects and compilations and emit an LSIF-compatible output that provides information about definitions, references and more. + For more information about LSIF, see https://code.visualstudio.com/blogs/2019/02/19/lsif + + false + + + + + + + + + + + + + + + + + + + + From 6634c8f57f4f2daf7e74ebf0cb9875e21ef98bc7 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 7 Feb 2020 17:11:10 -0800 Subject: [PATCH 031/222] Deal with file mappings where the drive letter doesn't have a \ Path.Combine("C:", "Foo.txt") returns "C:Foo.txt" which reflects the behavior that Foo.txt is relative not to C:\ but to the working directory of C: which is C:Foo.txt. This isn't the behavior I expected so this was broken. Add the extra directory slash in and do more testing so we get this right. --- .../Lsif/Generator/CompilerInvocation.cs | 9 +++++-- .../GeneratorTest/CompilerInvocationTests.vb | 25 +++++++++++++++++-- ...deAnalysis.Lsif.Generator.UnitTests.vbproj | 3 +++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/Features/Lsif/Generator/CompilerInvocation.cs b/src/Features/Lsif/Generator/CompilerInvocation.cs index b2fb42c2d5a58..8cdfa47eba228 100644 --- a/src/Features/Lsif/Generator/CompilerInvocation.cs +++ b/src/Features/Lsif/Generator/CompilerInvocation.cs @@ -134,7 +134,7 @@ private static Func GetPathMapper(CompilerInvocationInfo invocat } // Map arbitrary contents under subdirectories - var fromWithDirectorySuffix = potentialPathMapping.From.EndsWith("\\", StringComparison.OrdinalIgnoreCase) ? potentialPathMapping.From : potentialPathMapping.From + "\\"; + var fromWithDirectorySuffix = AddDirectorySuffixIfMissing(potentialPathMapping.From); if (unmappedPath.StartsWith(fromWithDirectorySuffix, StringComparison.OrdinalIgnoreCase)) { @@ -142,12 +142,17 @@ private static Func GetPathMapper(CompilerInvocationInfo invocat // mapping C:\Directory somewhere. string relativePath = unmappedPath.Substring(fromWithDirectorySuffix.Length).TrimStart('\\'); - return Path.Combine(potentialPathMapping.To, relativePath); + return Path.Combine(AddDirectorySuffixIfMissing(potentialPathMapping.To), relativePath); } } return unmappedPath; }; + + static string AddDirectorySuffixIfMissing(string path) + { + return path.EndsWith("\\", StringComparison.OrdinalIgnoreCase) ? path : path + "\\"; + } } /// diff --git a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb index 1c951f4680538..f63af4f5f74d5 100644 --- a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb +++ b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb @@ -57,8 +57,9 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Assert.Equal(referencePath, DirectCast(metadataReference, PortableExecutableReference).FilePath) End Sub - - Public Async Sub TestSourceFilePathMapping() + + + Public Async Sub TestSourceFilePathMappingWithDriveLetters( from As String, [to] As String) Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", @@ -77,6 +78,26 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Assert.Equal("T:\SourceFile.cs", syntaxTree.FilePath) End Sub + + Public Async Sub TestSourceFilePathMappingWithDriveLetterOnly() + Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + { + ""tool"": ""csc"", + ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\SourceFile.cs /target:library /out:F:\\Output.dll"", + ""projectFilePath"": ""F:\\Project.csproj"", + ""sourceRootPath"": ""F:\\"", + ""pathMappings"": [ + { + ""from"": ""F:\\"", + ""to"": ""T:"" + }] + }") + + Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) + + Assert.Equal("T:\SourceFile.cs", syntaxTree.FilePath) + End Sub + Public Async Sub TestSourceFilePathMappingWithSubdirectoriesWithoutTrailingSlashes() Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" diff --git a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj index 249510315f32b..2923570a674ed 100644 --- a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj +++ b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj @@ -12,6 +12,9 @@ + + + From 304fb23a872e0cf2d23aba9922706f68c88253fa Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 13:32:59 +0000 Subject: [PATCH 032/222] Failing test for incorrect simplification --- .../InitializerSimplificationTests.vb | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb diff --git a/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb new file mode 100644 index 0000000000000..ed14156bc5667 --- /dev/null +++ b/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb @@ -0,0 +1,52 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Simplification +Imports Microsoft.CodeAnalysis.Text + +Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification + Public Class InitializerSimplificationTests + Inherits AbstractSimplificationTests + +#Region "VB tests" + + ' + + Public Async Function TestVisualBasic_DontRemoveParensAroundConditionalAccessExpressionIfParentIsMemberAccessExpression() As Task + Dim input = + + + +Imports System.Drawing + +Friend Class CommentTestClass + Public Function WidthOnly(r As Rectangle) As Rectangle + Return New Rectangle With { + {|SimplifyExtension:.Y = r.Y|} + } + End Function +End Class + + + + + Dim expected = + +Imports System.Drawing + +Friend Class CommentTestClass + Public Function WidthOnly(r As Rectangle) As Rectangle + Return New Rectangle With { + .Y = r.Y + } + End Function +End Class + + + Dim simplifiedDoc = Await TestAsync(input, expected) + Dim semanticModel = Await simplifiedDoc.GetSemanticModelAsync() + End Function +#End Region + End Class + + +End Namespace From 6da8b0e09910745618e8a03ba2fcb3e83bc94590 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 13:42:53 +0000 Subject: [PATCH 033/222] Extract composable functions --- .../Simplification/AbstractSimplificationTests.vb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb index f8ac90bbcd304..d8efe7c4eaf41 100644 --- a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb @@ -58,6 +58,14 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification explicitSpansToSimplifyWithin As ImmutableArray(Of TextSpan), expected As XElement, options As Dictionary(Of OptionKey, Object)) As System.Threading.Tasks.Task + Dim simplifiedDocument As Document = Await Simplify(workspace, listOfLabelToAddSimplifierAnnotationSpans, explicitSpansToSimplifyWithin, options) + Await AssertCodeEqual(expected, simplifiedDocument) + End Function + + Private Async Function Simplify(workspace As Workspace, + listOfLabelToAddSimplifierAnnotationSpans As IEnumerable(Of KeyValuePair(Of String, ImmutableArray(Of TextSpan))), + explicitSpansToSimplifyWithin As ImmutableArray(Of TextSpan), + options As Dictionary(Of OptionKey, Object)) As Task(Of Document) Dim document = workspace.CurrentSolution.Projects.Single().Documents.Single() Dim root = Await document.GetSyntaxRootAsync() @@ -115,6 +123,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification simplifiedDocument = Await Simplifier.ReduceAsync(document, Simplifier.Annotation, optionSet) End If + Return simplifiedDocument + End Function + + Private Shared Async Function AssertCodeEqual(expected As XElement, simplifiedDocument As Document) As Task Dim actualText = (Await simplifiedDocument.GetTextAsync()).ToString() Assert.Equal(expected.NormalizedValue.Trim(), actualText.Trim()) End Function From 3a8a08e5a6492b8ae3f60300401976550ba1b2c1 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 13:52:50 +0000 Subject: [PATCH 034/222] Pull assertion up to top level --- .../AbstractSimplificationTests.vb | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb index d8efe7c4eaf41..06c89373a3bbb 100644 --- a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb @@ -26,11 +26,12 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification Next End If - Await TestAsync(finalWorkspace, expected, options).ConfigureAwait(False) + Dim simplifiedDocument = Await SimplifyAsync(finalWorkspace, options).ConfigureAwait(False) + Await AssertCodeEqual(expected, simplifiedDocument) End Using End Function - Protected Async Function TestAsync(workspace As TestWorkspace, expected As XElement, Optional options As Dictionary(Of OptionKey, Object) = Nothing) As System.Threading.Tasks.Task + Private Async Function SimplifyAsync(workspace As TestWorkspace, Optional options As Dictionary(Of OptionKey, Object) = Nothing) As System.Threading.Tasks.Task(Of Document) Dim hostDocument = workspace.Documents.Single() Dim spansToAddSimplifierAnnotation = hostDocument.AnnotatedSpans.Where(Function(kvp) kvp.Key.StartsWith("Simplify", StringComparison.Ordinal)) @@ -48,21 +49,10 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification explicitSpanToSimplifyAnnotatedSpans.Single().Value, Nothing) - Await TestAsync( - workspace, spansToAddSimplifierAnnotation, - explicitSpansToSimplifyWithin, expected, options) + Return Await SimplifyAsync(workspace, spansToAddSimplifierAnnotation, explicitSpansToSimplifyWithin, options) End Function - Private Async Function TestAsync(workspace As Workspace, - listOfLabelToAddSimplifierAnnotationSpans As IEnumerable(Of KeyValuePair(Of String, ImmutableArray(Of TextSpan))), - explicitSpansToSimplifyWithin As ImmutableArray(Of TextSpan), - expected As XElement, - options As Dictionary(Of OptionKey, Object)) As System.Threading.Tasks.Task - Dim simplifiedDocument As Document = Await Simplify(workspace, listOfLabelToAddSimplifierAnnotationSpans, explicitSpansToSimplifyWithin, options) - Await AssertCodeEqual(expected, simplifiedDocument) - End Function - - Private Async Function Simplify(workspace As Workspace, + Private Async Function SimplifyAsync(workspace As Workspace, listOfLabelToAddSimplifierAnnotationSpans As IEnumerable(Of KeyValuePair(Of String, ImmutableArray(Of TextSpan))), explicitSpansToSimplifyWithin As ImmutableArray(Of TextSpan), options As Dictionary(Of OptionKey, Object)) As Task(Of Document) From faedc002a305a445ea3bd56c0119f92925796a28 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 13:57:01 +0000 Subject: [PATCH 035/222] Extract function --- .../AbstractSimplificationTests.vb | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb index 06c89373a3bbb..54dee75f8a7a0 100644 --- a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb @@ -17,20 +17,23 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification Public MustInherit Class AbstractSimplificationTests Protected Async Function TestAsync(definition As XElement, expected As XElement, Optional options As Dictionary(Of OptionKey, Object) = Nothing, Optional csharpParseOptions As CSharpParseOptions = Nothing) As System.Threading.Tasks.Task - Using workspace = TestWorkspace.Create(definition) - Dim finalWorkspace = workspace - - If csharpParseOptions IsNot Nothing Then - For Each project In workspace.CurrentSolution.Projects - finalWorkspace.ChangeSolution(finalWorkspace.CurrentSolution.WithProjectParseOptions(project.Id, csharpParseOptions)) - Next - End If - - Dim simplifiedDocument = Await SimplifyAsync(finalWorkspace, options).ConfigureAwait(False) + Using workspace = CreateTestWorkspace(definition, csharpParseOptions) + Dim simplifiedDocument = Await SimplifyAsync(workspace, options).ConfigureAwait(False) Await AssertCodeEqual(expected, simplifiedDocument) End Using End Function + Private Shared Function CreateTestWorkspace(definition As XElement, Optional csharpParseOptions As CSharpParseOptions = Nothing) As TestWorkspace + Dim workspace = TestWorkspace.Create(definition) + + If csharpParseOptions IsNot Nothing Then + For Each project In workspace.CurrentSolution.Projects + workspace.ChangeSolution(workspace.CurrentSolution.WithProjectParseOptions(project.Id, csharpParseOptions)) + Next + End If + Return workspace + End Function + Private Async Function SimplifyAsync(workspace As TestWorkspace, Optional options As Dictionary(Of OptionKey, Object) = Nothing) As System.Threading.Tasks.Task(Of Document) Dim hostDocument = workspace.Documents.Single() From e3594d8ca3240fe9bd39ed1c4367f6de19851b0b Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 14:00:30 +0000 Subject: [PATCH 036/222] Test that the simplification didn't introduce compile errors first This allows us to see the bug more clearly since BindObjectInitializer throws --- .../Simplification/AbstractSimplificationTests.vb | 6 +++--- .../Simplification/InitializerSimplificationTests.vb | 11 ++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb index 54dee75f8a7a0..31e623733cf56 100644 --- a/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/AbstractSimplificationTests.vb @@ -23,7 +23,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification End Using End Function - Private Shared Function CreateTestWorkspace(definition As XElement, Optional csharpParseOptions As CSharpParseOptions = Nothing) As TestWorkspace + Protected Shared Function CreateTestWorkspace(definition As XElement, Optional csharpParseOptions As CSharpParseOptions = Nothing) As TestWorkspace Dim workspace = TestWorkspace.Create(definition) If csharpParseOptions IsNot Nothing Then @@ -34,7 +34,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification Return workspace End Function - Private Async Function SimplifyAsync(workspace As TestWorkspace, Optional options As Dictionary(Of OptionKey, Object) = Nothing) As System.Threading.Tasks.Task(Of Document) + Protected Async Function SimplifyAsync(workspace As TestWorkspace, Optional options As Dictionary(Of OptionKey, Object) = Nothing) As System.Threading.Tasks.Task(Of Document) Dim hostDocument = workspace.Documents.Single() Dim spansToAddSimplifierAnnotation = hostDocument.AnnotatedSpans.Where(Function(kvp) kvp.Key.StartsWith("Simplify", StringComparison.Ordinal)) @@ -119,7 +119,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification Return simplifiedDocument End Function - Private Shared Async Function AssertCodeEqual(expected As XElement, simplifiedDocument As Document) As Task + Protected Shared Async Function AssertCodeEqual(expected As XElement, simplifiedDocument As Document) As Task Dim actualText = (Await simplifiedDocument.GetTextAsync()).ToString() Assert.Equal(expected.NormalizedValue.Trim(), actualText.Trim()) End Function diff --git a/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb index ed14156bc5667..d11d8a940fe8e 100644 --- a/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb @@ -9,7 +9,6 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification #Region "VB tests" - ' Public Async Function TestVisualBasic_DontRemoveParensAroundConditionalAccessExpressionIfParentIsMemberAccessExpression() As Task Dim input = @@ -41,9 +40,15 @@ Friend Class CommentTestClass End Function End Class + Using workspace = CreateTestWorkspace(input) + Dim simplifiedDocument = Await SimplifyAsync(workspace).ConfigureAwait(False) - Dim simplifiedDoc = Await TestAsync(input, expected) - Dim semanticModel = Await simplifiedDoc.GetSemanticModelAsync() + Dim semanticModel = Await simplifiedDocument.GetSemanticModelAsync() + Dim diagnosticsFromSimplifiedDocument = semanticModel.Compilation.GetDiagnostics() + Assert.Empty(diagnosticsFromSimplifiedDocument) + + Await AssertCodeEqual(expected, simplifiedDocument) + End Using End Function #End Region End Class From c9e70e6c96506a9eb1587501b45670f42fa37d97 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 14:07:33 +0000 Subject: [PATCH 037/222] Refine tests cases We may need a test for the "From" syntax too --- .../InitializerSimplificationTests.vb | 66 +++++++++++++++---- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb b/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb index d11d8a940fe8e..38ba8f0902720 100644 --- a/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb +++ b/src/EditorFeatures/Test2/Simplification/InitializerSimplificationTests.vb @@ -10,17 +10,17 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Simplification #Region "VB tests" - Public Async Function TestVisualBasic_DontRemoveParensAroundConditionalAccessExpressionIfParentIsMemberAccessExpression() As Task + Public Async Function TestVisualBasic_DontRemovePropertyNameForObjectCreationInitializer() As Task Dim input = -Imports System.Drawing +Imports System.Text -Friend Class CommentTestClass - Public Function WidthOnly(r As Rectangle) As Rectangle - Return New Rectangle With { - {|SimplifyExtension:.Y = r.Y|} +Friend Class InitializerTestClass + Public Function CopyLength(sb As StringBuilder) As Object + Return New StringBuilder With { + {|SimplifyExtension:.Length = sb.Length|} } End Function End Class @@ -30,16 +30,59 @@ End Class Dim expected = -Imports System.Drawing +Imports System.Text -Friend Class CommentTestClass - Public Function WidthOnly(r As Rectangle) As Rectangle - Return New Rectangle With { - .Y = r.Y +Friend Class InitializerTestClass + Public Function CopyLength(sb As StringBuilder) As Object + Return New StringBuilder With { + .Length = sb.Length + } + End Function +End Class + + + + Await AssertCompilesAndEqual(input, expected).ConfigureAwait(False) + End Function + + + Public Async Function TestVisualBasic_RemoveInferrablePropertyNameForAnonymousObjectCreationInitializer() As Task + Dim input = + + + +Imports System.Text + +Friend Class InitializerTestClass + Public Function CopyLength(sb As StringBuilder) As Object + Return New With { + {|SimplifyExtension:.Length = sb.Length|} + } + End Function +End Class + + + + + Dim expected = + +Imports System.Text + +Friend Class InitializerTestClass + Public Function CopyLength(sb As StringBuilder) As Object + Return New With { + sb.Length } End Function End Class + Await AssertCompilesAndEqual(input, expected).ConfigureAwait(False) + End Function +#End Region + + + + Private Async Function AssertCompilesAndEqual(input As XElement, expected As XElement) As Task Using workspace = CreateTestWorkspace(input) Dim simplifiedDocument = Await SimplifyAsync(workspace).ConfigureAwait(False) @@ -50,7 +93,6 @@ End Class Await AssertCodeEqual(expected, simplifiedDocument) End Using End Function -#End Region End Class From d39bed2c932b94f752220dc840c2184800f73553 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Feb 2020 14:28:07 +0000 Subject: [PATCH 038/222] Stop simplifying object creation expression initializers only I'm not familiar with the full set of syntax available (e.g. From clause) so I'll just fix the one I know and have a test showing is problematic --- .../Reducers/VisualBasicInferredMemberNameReducer.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicInferredMemberNameReducer.vb b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicInferredMemberNameReducer.vb index 441f0dfabab31..234340f50c22b 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicInferredMemberNameReducer.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicInferredMemberNameReducer.vb @@ -60,7 +60,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification End Function Friend Shared Function CanSimplifyNamedFieldInitializer(node As NamedFieldInitializerSyntax) As Boolean - If RemovalCausesAmbiguity(DirectCast(node.Parent, ObjectMemberInitializerSyntax).Initializers, node) Then + If node.Parent.IsParentKind(SyntaxKind.ObjectCreationExpression) OrElse RemovalCausesAmbiguity(DirectCast(node.Parent, ObjectMemberInitializerSyntax).Initializers, node) Then Return False End If From bf819a7240b86f1f0520499eb87718ea2d1382bd Mon Sep 17 00:00:00 2001 From: Alexander Gayko Date: Tue, 31 Mar 2020 05:51:51 +0200 Subject: [PATCH 039/222] squashed files from all commits into one --- .../IntellisenseQuickInfoBuilderTests.vb | 109 +++++++++++++++++- ...ctDocumentationCommentFormattingService.cs | 98 +++++++++++++++- .../IDocumentationCommentFormattingService.cs | 2 +- .../CommonSemanticQuickInfoProvider.cs | 2 +- .../Shared/Extensions/ISymbolExtensions_2.cs | 38 ++---- 5 files changed, 211 insertions(+), 38 deletions(-) diff --git a/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb b/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb index fc64fc240c2e3..af408e44382ad 100644 --- a/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb +++ b/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb @@ -954,6 +954,58 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense Public Async Sub QuickInfoForTypeParameterReference() + Dim workspace = + + + + using System.Threading; + class MyClass { + /// <summary> + /// The type parameter is <typeparamref name="T"/>. + /// </summary> + void MyM$$ethod<T>() { + MyMethod<int>(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + Assert.NotNull(intellisenseQuickInfo) + + Dim container = Assert.IsType(Of ContainerElement)(intellisenseQuickInfo.Item) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass", navigationAction:=Sub() Return, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod", navigationAction:=Sub() Return, "void MyClass.MyMethod()"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "<"), + New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "T", navigationAction:=Sub() Return, "T"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ">"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "The type parameter is"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "T", navigationAction:=Sub() Return, "T"), + New ClassifiedTextRun(ClassificationTypeNames.Text, ".")))) + + AssertEqualAdornments(expected, container) + End Sub + + + + Public Async Sub QuickInfoForTypeParameterReferenceClosedGeneric() Dim workspace = @@ -997,7 +1049,62 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense New ClassifiedTextElement( New ClassifiedTextRun(ClassificationTypeNames.Text, "The type parameter is"), New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), - New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "T"), + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "int", navigationAction:=Sub() Return, "int"), + New ClassifiedTextRun(ClassificationTypeNames.Text, ".")))) + + AssertEqualAdornments(expected, container) + End Sub + + + + Public Async Sub QuickInfoForTypeParameterReferenceBoundGeneric() + Dim workspace = + + + + using System.Threading; + class MyClass<K> { + /// <summary> + /// The type parameter is <typeparamref name="T"/>. + /// </summary> + void MyMethod<T>() { + MyM$$ethod<K>(); + } + } + + + + + Dim intellisenseQuickInfo = Await GetQuickInfoItemAsync(workspace, LanguageNames.CSharp) + Assert.NotNull(intellisenseQuickInfo) + + Dim container = Assert.IsType(Of ContainerElement)(intellisenseQuickInfo.Item) + + Dim expected = New ContainerElement( + ContainerElementStyle.Stacked Or ContainerElementStyle.VerticalPadding, + New ContainerElement( + ContainerElementStyle.Stacked, + New ContainerElement( + ContainerElementStyle.Wrapped, + New ImageElement(New ImageId(KnownImageIds.ImageCatalogGuid, KnownImageIds.MethodPrivate)), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Keyword, "void"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.ClassName, "MyClass", navigationAction:=Sub() Return, "MyClass"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "<"), + New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "K", navigationAction:=Sub() Return, "K"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ">"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "."), + New ClassifiedTextRun(ClassificationTypeNames.MethodName, "MyMethod", navigationAction:=Sub() Return, "void MyClass.MyMethod()"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "<"), + New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "K", navigationAction:=Sub() Return, "K"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ">"), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, "("), + New ClassifiedTextRun(ClassificationTypeNames.Punctuation, ")"))), + New ClassifiedTextElement( + New ClassifiedTextRun(ClassificationTypeNames.Text, "The type parameter is"), + New ClassifiedTextRun(ClassificationTypeNames.WhiteSpace, " "), + New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "K", navigationAction:=Sub() Return, "K"), New ClassifiedTextRun(ClassificationTypeNames.Text, ".")))) AssertEqualAdornments(expected, container) diff --git a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs index 49e0bc45b3f52..81ef18a3f7e9c 100644 --- a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs @@ -3,7 +3,9 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Linq; using System.Text; +using System.Threading; using System.Xml; using System.Xml.Linq; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -76,6 +78,7 @@ public FormatterState() } internal SemanticModel SemanticModel { get; set; } + internal ISymbol TypeResolutionSymbol { get; set; } internal int Position { get; set; } public bool AtBeginning @@ -257,6 +260,59 @@ private void EmitPendingChars() } } + private static string GetDocumentation(ISymbol symbol, Compilation compilation, CancellationToken cancellationToken) + => symbol switch + { + IParameterSymbol parameter => GetParameterDocumentation(parameter, compilation, cancellationToken), + ITypeParameterSymbol typeParam => typeParam.ContainingSymbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).GetTypeParameterText(symbol.Name), + IMethodSymbol method => GetMethodDocumentation(method, compilation, cancellationToken), + IAliasSymbol alias => alias.Target.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText, + _ => symbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText, + }; + + private static string GetParameterDocumentation(IParameterSymbol parameter, Compilation compilation, CancellationToken cancellationToken) + { + var containingSymbol = parameter.ContainingSymbol; + if (containingSymbol.ContainingSymbol.IsDelegateType() && containingSymbol is IMethodSymbol methodSymbol) + { + // There are two ways to invoke a delegate that we care about here: the Invoke()/BeginInvoke() methods. (Direct invocation is equivalent to an Invoke() call.) + // DynamicInvoke() takes an object array, and EndInvoke() takes a System.IAsyncResult, so we can (and should) ignore those here. + + var symbolName = methodSymbol.Name; + if (symbolName == WellKnownMemberNames.DelegateBeginInvokeName && parameter.Ordinal >= (methodSymbol.Parameters.Length - 2)) + { + // Return null (similar to DocumentationComment.GetParameterText()) for the last two implicit parameters (usually called "callback" and "@object"). + // We can't rely on those names because they might be renamed to avoid collision with a user-defined delegate parameter of the same name, + // and we have to treat them separately, because a user might add e.g. a '' tag to the delegate, which would be displayed in Signature Help for that implicit parameter. + return null; + } + + if (symbolName == WellKnownMemberNames.DelegateInvokeName || symbolName == WellKnownMemberNames.DelegateBeginInvokeName) + { + // We know that containingSymbol is the [Begin]Invoke() method of a delegate type, so we need to go up a level and take the method's containing symbol (i.e. the delegate), which contains the documentation. + containingSymbol = containingSymbol.ContainingSymbol; + } + } + + // Get the comments from the original definition of the containing symbol. + return containingSymbol.OriginalDefinition.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).GetParameterText(parameter.Name); + } + + private static string GetMethodDocumentation(IMethodSymbol method, Compilation compilation, CancellationToken cancellationToken) + { + switch (method.MethodKind) + { + case MethodKind.EventAdd: + case MethodKind.EventRaise: + case MethodKind.EventRemove: + case MethodKind.PropertyGet: + case MethodKind.PropertySet: + return method.AssociatedSymbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText; + default: + return method.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText; + } + } + public string Format(string rawXmlText, Compilation compilation = null) { if (rawXmlText == null) @@ -277,14 +333,15 @@ public string Format(string rawXmlText, Compilation compilation = null) return state.GetText(); } - public IEnumerable Format(string rawXmlText, SemanticModel semanticModel, int position, SymbolDisplayFormat format = null) + public IEnumerable Format(string rawXmlText, ISymbol symbol, SemanticModel semanticModel, int position, SymbolDisplayFormat format, CancellationToken cancellationToken) { - if (rawXmlText == null) + if (rawXmlText is null) { - return null; + return SpecializedCollections.EmptyEnumerable(); } + //symbol = symbol.OriginalDefinition; - var state = new FormatterState() { SemanticModel = semanticModel, Position = position, Format = format }; + var state = new FormatterState() { SemanticModel = semanticModel, Position = position, Format = format, TypeResolutionSymbol = symbol }; // In case the XML is a fragment (that is, a series of elements without a parent) // wrap it up in a single tag. This makes parsing it much, much easier. @@ -460,8 +517,16 @@ private static void AppendTextFromAttribute(FormatterState state, XElement eleme var attributeName = attribute.Name.LocalName; if (attributeNameToParse == attributeName) { - state.AppendParts( - CrefToSymbolDisplayParts(attribute.Value, state.Position, state.SemanticModel, state.Format, kind).ToTaggedText(state.Style)); + if (kind == SymbolDisplayPartKind.TypeParameterName) + { + state.AppendParts( + TypeParameterRefToSymbolDisplayParts(attribute.Value, state.TypeResolutionSymbol, state.Position, state.SemanticModel, state.Format).ToTaggedText(state.Style)); + } + else + { + state.AppendParts( + CrefToSymbolDisplayParts(attribute.Value, state.Position, state.SemanticModel, state.Format, kind).ToTaggedText(state.Style)); + } } else { @@ -502,6 +567,27 @@ internal static IEnumerable CrefToSymbolDisplayParts( new SymbolDisplayPart(kind, symbol: null, text: TrimCrefPrefix(crefValue))); } + internal static IEnumerable TypeParameterRefToSymbolDisplayParts( + string crefValue, ISymbol typeResolutionSymbol, int position, SemanticModel semanticModel, SymbolDisplayFormat format) + { + if (semanticModel != null) + { + var typeParameterIndex = typeResolutionSymbol.OriginalDefinition.GetAllTypeParameters().IndexOf(tp => tp.Name == crefValue); + if (typeParameterIndex >= 0) + { + var typeArgs = typeResolutionSymbol.GetAllTypeArguments(); + if (typeArgs.Length > typeParameterIndex) + { + return typeArgs[typeParameterIndex].ToMinimalDisplayParts(semanticModel, position, format); + } + } + } + + // if any of that fails fall back to just displaying the raw text + return SpecializedCollections.SingletonEnumerable( + new SymbolDisplayPart(SymbolDisplayPartKind.TypeParameterName, symbol: null, text: TrimCrefPrefix(crefValue))); + } + private static string TrimCrefPrefix(string value) { if (value.Length >= 2 && value[1] == ':') diff --git a/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs index c8c1194282554..8f05e8b2d0670 100644 --- a/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs @@ -10,6 +10,6 @@ namespace Microsoft.CodeAnalysis.DocumentationComments internal interface IDocumentationCommentFormattingService : ILanguageService { string Format(string rawXmlText, Compilation compilation = null); - IEnumerable Format(string rawXmlText, SemanticModel semanticModel, int position, SymbolDisplayFormat format = null); + IEnumerable Format(string rawXmlText, ISymbol symbol, SemanticModel semanticModel, int position, SymbolDisplayFormat format, CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs b/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs index b982636b4d473..5215d947c44cd 100644 --- a/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs +++ b/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs @@ -178,7 +178,7 @@ void AddSection(string kind, ImmutableArray taggedParts) AddSection(QuickInfoSectionKinds.Description, mainDescriptionTaggedParts); } - var documentedSymbol = symbols.FirstOrDefault()?.OriginalDefinition; + var documentedSymbol = symbols.FirstOrDefault(); // if generating quick info for an attribute, bind to the class instead of the constructor if (syntaxFactsService.IsAttributeName(token.Parent) && diff --git a/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs b/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs index 358b2eb184139..c9957ea9c5baf 100644 --- a/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs +++ b/src/Features/Core/Portable/Shared/Extensions/ISymbolExtensions_2.cs @@ -9,7 +9,6 @@ using System.Threading; using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.Shared.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Shared.Extensions { @@ -177,37 +176,20 @@ public static Glyph GetGlyph(this ISymbol symbol) } public static IEnumerable GetDocumentationParts(this ISymbol symbol, SemanticModel semanticModel, int position, IDocumentationCommentFormattingService formatter, CancellationToken cancellationToken) - { - var documentation = GetDocumentation(symbol, semanticModel.Compilation, cancellationToken); - - return documentation != null - ? formatter.Format(documentation, semanticModel, position, CrefFormat) - : SpecializedCollections.EmptyEnumerable(); - } + => formatter.Format(GetDocumentation(symbol.OriginalDefinition, semanticModel.Compilation, cancellationToken), + symbol, semanticModel, position, CrefFormat, cancellationToken); public static IEnumerable GetRemarksDocumentationParts(this ISymbol symbol, SemanticModel semanticModel, int position, IDocumentationCommentFormattingService formatter, CancellationToken cancellationToken) - { - var documentation = GetRemarksDocumentation(symbol, semanticModel.Compilation, cancellationToken); - return documentation != null - ? formatter.Format(documentation, semanticModel, position, CrefFormat) - : SpecializedCollections.EmptyEnumerable(); - } + => formatter.Format(GetRemarksDocumentation(symbol.OriginalDefinition, semanticModel.Compilation, cancellationToken), + symbol, semanticModel, position, CrefFormat, cancellationToken); public static IEnumerable GetReturnsDocumentationParts(this ISymbol symbol, SemanticModel semanticModel, int position, IDocumentationCommentFormattingService formatter, CancellationToken cancellationToken) - { - var documentation = GetReturnsDocumentation(symbol, semanticModel.Compilation, cancellationToken); - return documentation != null - ? formatter.Format(documentation, semanticModel, position, CrefFormat) - : SpecializedCollections.EmptyEnumerable(); - } + => formatter.Format(GetReturnsDocumentation(symbol.OriginalDefinition, semanticModel.Compilation, cancellationToken), + symbol, semanticModel, position, CrefFormat, cancellationToken); public static IEnumerable GetValueDocumentationParts(this ISymbol symbol, SemanticModel semanticModel, int position, IDocumentationCommentFormattingService formatter, CancellationToken cancellationToken) - { - var documentation = GetValueDocumentation(symbol, semanticModel.Compilation, cancellationToken); - return documentation != null - ? formatter.Format(documentation, semanticModel, position, CrefFormat) - : SpecializedCollections.EmptyEnumerable(); - } + => formatter.Format(GetValueDocumentation(symbol.OriginalDefinition, semanticModel.Compilation, cancellationToken), + symbol, semanticModel, position, CrefFormat, cancellationToken); private static string? GetDocumentation(ISymbol symbol, Compilation compilation, CancellationToken cancellationToken) => symbol switch @@ -270,9 +252,7 @@ public static IEnumerable GetValueDocumentationParts(this ISymbol sy public static Func> GetDocumentationPartsFactory( this ISymbol symbol, SemanticModel semanticModel, int position, IDocumentationCommentFormattingService formatter) - { - return c => symbol.GetDocumentationParts(semanticModel, position, formatter, cancellationToken: c); - } + => c => symbol.GetDocumentationParts(semanticModel, position, formatter, cancellationToken: c); public static readonly SymbolDisplayFormat CrefFormat = new SymbolDisplayFormat( From 507f8f20a6d6815b83b97f8426f56e2a00d39239 Mon Sep 17 00:00:00 2001 From: Alexander Gayko Date: Tue, 31 Mar 2020 20:00:09 +0200 Subject: [PATCH 040/222] added missing using clause. Tests pass now. --- .../IDocumentationCommentFormattingService.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs index 8f05e8b2d0670..330d5ca333e27 100644 --- a/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/IDocumentationCommentFormattingService.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Threading; using Microsoft.CodeAnalysis.Host; namespace Microsoft.CodeAnalysis.DocumentationComments From ab7753c1715bc48d10c744c54c37a82c5d745b83 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Tue, 14 Apr 2020 13:10:36 -0700 Subject: [PATCH 041/222] Remove "Lsif" abbreviations from namespaces This either replaces "Lsif" with Language Server Index Format or simply removes it if it was redundant. --- Roslyn.sln | 4 ++-- ...AbstractFindUsagesService.SymbolMoniker.cs | 2 +- .../IFindSymbolMonikerUsagesService.cs | 2 +- .../SymbolMoniker.cs | 2 +- .../WellKnownSymbolMonikerSchemes.cs | 2 +- .../Microsoft.CodeAnalysis.Features.csproj | 2 +- .../Lsif/Generator/CompilerInvocation.cs | 2 +- src/Features/Lsif/Generator/Generator.cs | 22 +++++++++---------- .../{LsifGraph => Graph}/DefinitionResult.cs | 2 +- .../{LsifGraph => Graph}/Document.cs | 2 +- .../Generator/{LsifGraph => Graph}/Edge.cs | 2 +- .../Generator/{LsifGraph => Graph}/Element.cs | 2 +- .../Generator/{LsifGraph => Graph}/Event.cs | 2 +- .../Lsif/Generator/{LsifGraph => Graph}/Id.cs | 2 +- .../Generator/{LsifGraph => Graph}/Item.cs | 2 +- .../Generator/{LsifGraph => Graph}/Moniker.cs | 2 +- .../Generator/{LsifGraph => Graph}/Project.cs | 2 +- .../Generator/{LsifGraph => Graph}/Range.cs | 2 +- .../{LsifGraph => Graph}/ReferenceResult.cs | 2 +- .../{LsifGraph => Graph}/ResultSet.cs | 2 +- .../Generator/{LsifGraph => Graph}/Vertex.cs | 2 +- ...anguageServerIndexFormat.Generator.csproj} | 4 ++-- src/Features/Lsif/Generator/Program.cs | 4 ++-- .../DelegatingResultSetTracker.cs | 4 ++-- .../ResultSetTracking/IResultSetTracker.cs | 4 ++-- .../SymbolHoldingResultSetTracker.cs | 7 +++--- src/Features/Lsif/Generator/Utilities.cs | 2 +- .../Lsif/Generator/Writing/ILsifJsonWriter.cs | 4 ++-- .../Writing/InMemoryLsifJsonWriter.cs | 4 ++-- .../Lsif/Generator/Writing/LsifFormat.cs | 2 +- .../Generator/Writing/TextLsifJsonWriter.cs | 4 ++-- .../GeneratorTest/CompilerInvocationTests.vb | 16 +++++++------- ...verIndexFormat.Generator.UnitTests.vbproj} | 4 ++-- .../GeneratorTest/ProjectStructureTests.vb | 6 ++--- .../Lsif/GeneratorTest/RangeResultSetTests.vb | 18 +++++++-------- .../Utilities/TestLsifJsonWriter.vb | 8 +++---- .../GeneratorTest/Utilities/TestLsifOutput.vb | 10 ++++----- .../FindUsages/MonikerWrapper.cs | 2 +- ...ualStudioFindSymbolMonikerUsagesService.cs | 2 +- .../Microsoft.CodeAnalysis.Workspaces.csproj | 2 +- 40 files changed, 85 insertions(+), 86 deletions(-) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/DefinitionResult.cs (83%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Document.cs (89%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Edge.cs (96%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Element.cs (89%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Event.cs (94%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Id.cs (96%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Item.cs (92%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Moniker.cs (89%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Project.cs (91%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Range.cs (93%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/ReferenceResult.cs (83%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/ResultSet.cs (88%) rename src/Features/Lsif/Generator/{LsifGraph => Graph}/Vertex.cs (85%) rename src/Features/Lsif/Generator/{Microsoft.CodeAnalysis.Lsif.Generator.csproj => Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj} (95%) rename src/Features/Lsif/GeneratorTest/{Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj => Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj} (85%) diff --git a/Roslyn.sln b/Roslyn.sln index c77ca2ab45528..9c94112131b9a 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -422,9 +422,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompilersIOperationGenerator", "src\Tools\Source\CompilerGeneratorTools\Source\IOperationGenerator\CompilersIOperationGenerator.csproj", "{D55FB2BD-CC9E-454B-9654-94AF5D910BF7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Lsif.Generator", "src\Features\Lsif\Generator\Microsoft.CodeAnalysis.Lsif.Generator.csproj", "{B9899CF1-E0EB-4599-9E24-6939A04B4979}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator", "src\Features\Lsif\Generator\Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj", "{B9899CF1-E0EB-4599-9E24-6939A04B4979}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.CodeAnalysis.Lsif.Generator.UnitTests", "src\Features\Lsif\GeneratorTest\Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj", "{D15BF03E-04ED-4BEE-A72B-7620F541F4E2}" +Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests", "src\Features\Lsif\GeneratorTest\Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj", "{D15BF03E-04ED-4BEE-A72B-7620F541F4E2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analyzers", "Analyzers", "{4A49D526-1644-4819-AA4F-95B348D447D4}" EndProject diff --git a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.SymbolMoniker.cs b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.SymbolMoniker.cs index d3fabdb738ccd..aba0e48b3a635 100644 --- a/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.SymbolMoniker.cs +++ b/src/EditorFeatures/Core/FindUsages/AbstractFindUsagesService.SymbolMoniker.cs @@ -7,7 +7,7 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.LanguageServiceIndexFormat; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; diff --git a/src/EditorFeatures/Core/FindUsages/IFindSymbolMonikerUsagesService.cs b/src/EditorFeatures/Core/FindUsages/IFindSymbolMonikerUsagesService.cs index b4fa5298856ba..bb7ccbd2d8d3f 100644 --- a/src/EditorFeatures/Core/FindUsages/IFindSymbolMonikerUsagesService.cs +++ b/src/EditorFeatures/Core/FindUsages/IFindSymbolMonikerUsagesService.cs @@ -7,7 +7,7 @@ using System.Collections.Immutable; using System.Composition; using System.Threading; -using Microsoft.CodeAnalysis.LanguageServiceIndexFormat; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; diff --git a/src/Features/Core/Portable/LanguageServiceIndexFormat/SymbolMoniker.cs b/src/Features/Core/Portable/LanguageServiceIndexFormat/SymbolMoniker.cs index 41f1f36fee4c9..719584a0a4d40 100644 --- a/src/Features/Core/Portable/LanguageServiceIndexFormat/SymbolMoniker.cs +++ b/src/Features/Core/Portable/LanguageServiceIndexFormat/SymbolMoniker.cs @@ -6,7 +6,7 @@ using System; -namespace Microsoft.CodeAnalysis.LanguageServiceIndexFormat +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat { internal sealed class SymbolMoniker { diff --git a/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs b/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs index 45afc332b7e87..a0380faa114f7 100644 --- a/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs +++ b/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs @@ -4,7 +4,7 @@ #nullable enable -namespace Microsoft.CodeAnalysis.LanguageServiceIndexFormat +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat { internal static class WellKnownSymbolMonikerSchemes { diff --git a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj index 174076f6768c8..db98934567454 100644 --- a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj +++ b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj @@ -40,7 +40,7 @@ - + diff --git a/src/Features/Lsif/Generator/CompilerInvocation.cs b/src/Features/Lsif/Generator/CompilerInvocation.cs index 111c8efc89955..cf7fd09f118ab 100644 --- a/src/Features/Lsif/Generator/CompilerInvocation.cs +++ b/src/Features/Lsif/Generator/CompilerInvocation.cs @@ -12,7 +12,7 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Newtonsoft.Json; -namespace Microsoft.CodeAnalysis.Lsif.Generator +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator { internal class CompilerInvocation { diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 674d41c3ad101..26ec94054e008 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -8,12 +8,12 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageServices; -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; -using Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking; -using Microsoft.CodeAnalysis.Lsif.Generator.Writing; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.ResultSetTracking; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing; using Methods = Microsoft.VisualStudio.LanguageServer.Protocol.Methods; -namespace Microsoft.CodeAnalysis.Lsif.Generator +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator { internal sealed class Generator { @@ -26,11 +26,11 @@ public Generator(ILsifJsonWriter lsifJsonWriter) public async Task GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) { - var projectVertex = new LsifGraph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath)); + var projectVertex = new Graph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath)); _lsifJsonWriter.Write(projectVertex); _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, projectVertex.GetId())); - var documentIds = new List>(); + var documentIds = new List>(); // We create a ResultSetTracker to track all top-level symbols in the project. We don't want all writes to immediately go to // the JSON file once we support parallel processing, so we'll accumulate them and then apply at once. @@ -58,7 +58,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); } - private static Task> GenerateForDocument( + private static Task> GenerateForDocument( SemanticModel semanticModel, HostLanguageServices languageServices, IResultSetTracker topLevelSymbolsResultSetTracker, @@ -69,7 +69,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project var syntaxFactsService = languageServices.GetRequiredService(); var semanticFactsService = languageServices.GetRequiredService(); - var documentVertex = new LsifGraph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); + var documentVertex = new Graph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); lsifJsonWriter.Write(documentVertex); lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); @@ -100,15 +100,15 @@ public async Task GenerateForCompilation(Compilation compilation, string project }); // We will walk the file token-by-token, making a range for each one and then attaching information for it - var rangeVertices = new List>(); + var rangeVertices = new List>(); foreach (var syntaxToken in syntaxTree.GetRoot().DescendantTokens(descendIntoTrivia: true)) { // We'll only create the Range vertex once it's needed, but any number of bits of code might create it first, // so we'll just make it Lazy. - var lazyRangeVertex = new Lazy(() => + var lazyRangeVertex = new Lazy(() => { - var rangeVertex = LsifGraph.Range.FromTextSpan(syntaxToken.Span, sourceText); + var rangeVertex = Graph.Range.FromTextSpan(syntaxToken.Span, sourceText); lsifJsonWriter.Write(rangeVertex); rangeVertices.Add(rangeVertex.GetId()); diff --git a/src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs b/src/Features/Lsif/Generator/Graph/DefinitionResult.cs similarity index 83% rename from src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs rename to src/Features/Lsif/Generator/Graph/DefinitionResult.cs index d12806e19ed90..f85c5fbd2b683 100644 --- a/src/Features/Lsif/Generator/LsifGraph/DefinitionResult.cs +++ b/src/Features/Lsif/Generator/Graph/DefinitionResult.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { internal sealed class DefinitionResult : Vertex { diff --git a/src/Features/Lsif/Generator/LsifGraph/Document.cs b/src/Features/Lsif/Generator/Graph/Document.cs similarity index 89% rename from src/Features/Lsif/Generator/LsifGraph/Document.cs rename to src/Features/Lsif/Generator/Graph/Document.cs index 33662f37d13b1..9a0274534e5bd 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Document.cs +++ b/src/Features/Lsif/Generator/Graph/Document.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { internal sealed class Document : Vertex { diff --git a/src/Features/Lsif/Generator/LsifGraph/Edge.cs b/src/Features/Lsif/Generator/Graph/Edge.cs similarity index 96% rename from src/Features/Lsif/Generator/LsifGraph/Edge.cs rename to src/Features/Lsif/Generator/Graph/Edge.cs index c2370da9fcbb3..d11fb950e1105 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Edge.cs +++ b/src/Features/Lsif/Generator/Graph/Edge.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// Represents an edge from one vertex to another. diff --git a/src/Features/Lsif/Generator/LsifGraph/Element.cs b/src/Features/Lsif/Generator/Graph/Element.cs similarity index 89% rename from src/Features/Lsif/Generator/LsifGraph/Element.cs rename to src/Features/Lsif/Generator/Graph/Element.cs index b7ad61ec494eb..1b573fa728324 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Element.cs +++ b/src/Features/Lsif/Generator/Graph/Element.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// The base class of an element in the LSIF format. diff --git a/src/Features/Lsif/Generator/LsifGraph/Event.cs b/src/Features/Lsif/Generator/Graph/Event.cs similarity index 94% rename from src/Features/Lsif/Generator/LsifGraph/Event.cs rename to src/Features/Lsif/Generator/Graph/Event.cs index 54510e12a6e15..de1e669c59cd5 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Event.cs +++ b/src/Features/Lsif/Generator/Graph/Event.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// Represents an event. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#events for further details. diff --git a/src/Features/Lsif/Generator/LsifGraph/Id.cs b/src/Features/Lsif/Generator/Graph/Id.cs similarity index 96% rename from src/Features/Lsif/Generator/LsifGraph/Id.cs rename to src/Features/Lsif/Generator/Graph/Id.cs index f7eace6ae2ba1..b2d7365490fbe 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Id.cs +++ b/src/Features/Lsif/Generator/Graph/Id.cs @@ -5,7 +5,7 @@ using System; using System.Threading; -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// Represents an ID of a vertex or edge. diff --git a/src/Features/Lsif/Generator/LsifGraph/Item.cs b/src/Features/Lsif/Generator/Graph/Item.cs similarity index 92% rename from src/Features/Lsif/Generator/LsifGraph/Item.cs rename to src/Features/Lsif/Generator/Graph/Item.cs index 2904e7ac3c171..567018db97c42 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Item.cs +++ b/src/Features/Lsif/Generator/Graph/Item.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// Represents a single item that points to a range from a result. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#request-textdocumentreferences diff --git a/src/Features/Lsif/Generator/LsifGraph/Moniker.cs b/src/Features/Lsif/Generator/Graph/Moniker.cs similarity index 89% rename from src/Features/Lsif/Generator/LsifGraph/Moniker.cs rename to src/Features/Lsif/Generator/Graph/Moniker.cs index 186ba85cd908f..ddd8a0fbcc7b8 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Moniker.cs +++ b/src/Features/Lsif/Generator/Graph/Moniker.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { internal sealed class Moniker : Vertex { diff --git a/src/Features/Lsif/Generator/LsifGraph/Project.cs b/src/Features/Lsif/Generator/Graph/Project.cs similarity index 91% rename from src/Features/Lsif/Generator/LsifGraph/Project.cs rename to src/Features/Lsif/Generator/Graph/Project.cs index 25f4cbf60ef3f..c77224669b387 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Project.cs +++ b/src/Features/Lsif/Generator/Graph/Project.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// Represents a top-level project. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex for further details. diff --git a/src/Features/Lsif/Generator/LsifGraph/Range.cs b/src/Features/Lsif/Generator/Graph/Range.cs similarity index 93% rename from src/Features/Lsif/Generator/LsifGraph/Range.cs rename to src/Features/Lsif/Generator/Graph/Range.cs index e2005bf308db0..6696662873af5 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Range.cs +++ b/src/Features/Lsif/Generator/Graph/Range.cs @@ -5,7 +5,7 @@ using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LanguageServer.Protocol; -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { internal sealed class Range : Vertex { diff --git a/src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs b/src/Features/Lsif/Generator/Graph/ReferenceResult.cs similarity index 83% rename from src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs rename to src/Features/Lsif/Generator/Graph/ReferenceResult.cs index 80a1d1e45ac3f..a0fe200f9f18a 100644 --- a/src/Features/Lsif/Generator/LsifGraph/ReferenceResult.cs +++ b/src/Features/Lsif/Generator/Graph/ReferenceResult.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { internal sealed class ReferenceResult : Vertex { diff --git a/src/Features/Lsif/Generator/LsifGraph/ResultSet.cs b/src/Features/Lsif/Generator/Graph/ResultSet.cs similarity index 88% rename from src/Features/Lsif/Generator/LsifGraph/ResultSet.cs rename to src/Features/Lsif/Generator/Graph/ResultSet.cs index 9786e802bdfbc..63e5a80ef7396 100644 --- a/src/Features/Lsif/Generator/LsifGraph/ResultSet.cs +++ b/src/Features/Lsif/Generator/Graph/ResultSet.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// Represents a single ResultSet in the LSIF file. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set for further details. diff --git a/src/Features/Lsif/Generator/LsifGraph/Vertex.cs b/src/Features/Lsif/Generator/Graph/Vertex.cs similarity index 85% rename from src/Features/Lsif/Generator/LsifGraph/Vertex.cs rename to src/Features/Lsif/Generator/Graph/Vertex.cs index 3ae050d750273..d28d28465c180 100644 --- a/src/Features/Lsif/Generator/LsifGraph/Vertex.cs +++ b/src/Features/Lsif/Generator/Graph/Vertex.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// /// The base class of any vertex in the graph. diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj similarity index 95% rename from src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj rename to src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj index ed23b2b8d03cf..7e7b88d73d2c6 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.Lsif.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj @@ -4,7 +4,7 @@ AnyCPU Exe - Microsoft.CodeAnalysis.Lsif.Generator + Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator true net472 AnyCPU @@ -69,6 +69,6 @@ - + \ No newline at end of file diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index e64cb867f2f6e..7c6d9d3259dc6 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -12,10 +12,10 @@ using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.Build.Locator; -using Microsoft.CodeAnalysis.Lsif.Generator.Writing; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing; using Microsoft.CodeAnalysis.MSBuild; -namespace Microsoft.CodeAnalysis.Lsif.Generator +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator { internal static class Program { diff --git a/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs index 28d18d0f707e5..43dd0c313970c 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/DelegatingResultSetTracker.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; -namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.ResultSetTracking { internal sealed class DelegatingResultSetTracker : IResultSetTracker { diff --git a/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs index 917449123cdcc..dd0d3acf04169 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/IResultSetTracker.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using System; -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; -namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.ResultSetTracking { /// /// An object that tracks a mapping from symbols to the result sets that have information about those symbols. diff --git a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 0360472e750d9..0b276a30450ea 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -4,11 +4,10 @@ using System; using System.Collections.Generic; -using Microsoft.CodeAnalysis.LanguageServiceIndexFormat; -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; -using Microsoft.CodeAnalysis.Lsif.Generator.Writing; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing; -namespace Microsoft.CodeAnalysis.Lsif.Generator.ResultSetTracking +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.ResultSetTracking { internal sealed class SymbolHoldingResultSetTracker : IResultSetTracker { diff --git a/src/Features/Lsif/Generator/Utilities.cs b/src/Features/Lsif/Generator/Utilities.cs index 027cd4adb45db..8f586949525af 100644 --- a/src/Features/Lsif/Generator/Utilities.cs +++ b/src/Features/Lsif/Generator/Utilities.cs @@ -4,7 +4,7 @@ using System; -namespace Microsoft.CodeAnalysis.Lsif.Generator +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator { internal static class Utilities { diff --git a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs index 793785b638e2e..0020828d1041a 100644 --- a/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/ILsifJsonWriter.cs @@ -2,9 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; -namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing { internal interface ILsifJsonWriter { diff --git a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs index 1c778f2ce2c8c..faccd0cc113f1 100644 --- a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; -namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing { internal sealed class InMemoryLsifJsonWriter : ILsifJsonWriter { diff --git a/src/Features/Lsif/Generator/Writing/LsifFormat.cs b/src/Features/Lsif/Generator/Writing/LsifFormat.cs index 50e5f9c0a5da1..fc4a499cc6d5f 100644 --- a/src/Features/Lsif/Generator/Writing/LsifFormat.cs +++ b/src/Features/Lsif/Generator/Writing/LsifFormat.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing { internal enum LsifFormat { diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs index eb507a159c002..b99d58807709c 100644 --- a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs @@ -4,11 +4,11 @@ using System; using System.IO; -using Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -namespace Microsoft.CodeAnalysis.Lsif.Generator.Writing +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing { internal sealed class TextLsifJsonWriter : ILsifJsonWriter, IDisposable { diff --git a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb index 2299ef7b107e6..70bb06b3f9af2 100644 --- a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb +++ b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb @@ -4,7 +4,7 @@ Imports Microsoft.CodeAnalysis.Test.Utilities -Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests +Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Public Class CompilerInvocationTests @@ -12,7 +12,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests ' PortableExecutableReference.CreateFromFile implicitly reads the file so the file must exist. Dim referencePath = GetType(Object).Assembly.Location - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG /reference:" + referencePath.Replace("\", "\\") + " Z:\\SourceFile.cs /target:library /out:Z:\\Output.dll"", @@ -38,7 +38,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests ' PortableExecutableReference.CreateFromFile implicitly reads the file so the file must exist. Dim referencePath = GetType(Object).Assembly.Location - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""vbc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG /reference:" + referencePath.Replace("\", "\\") + " Z:\\SourceFile.vb /target:library /out:Z:\\Output.dll"", @@ -62,7 +62,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Public Async Sub TestSourceFilePathMappingWithDriveLetters( from As String, [to] As String) - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\SourceFile.cs /target:library /out:F:\\Output.dll"", @@ -82,7 +82,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Public Async Sub TestSourceFilePathMappingWithDriveLetterOnly() - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\SourceFile.cs /target:library /out:F:\\Output.dll"", @@ -102,7 +102,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Public Async Sub TestSourceFilePathMappingWithSubdirectoriesWithoutTrailingSlashes() - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\Directory\\SourceFile.cs /target:library /out:F:\\Output.dll"", @@ -122,7 +122,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests Public Async Sub TestSourceFilePathMappingWithSubdirectoriesWithDoubleSlashesInFilePath() - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\Directory\\\\SourceFile.cs /target:library /out:F:\\Output.dll"", @@ -153,7 +153,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests ruleSet.WriteAllText(RuleSetContents) ' We will test that if we redirect the ruleset to the temporary file that we wrote that the values are still read. - Dim compilerInvocation = Await Microsoft.CodeAnalysis.Lsif.Generator.CompilerInvocation.CreateFromJsonAsync(" + Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG /ruleset:F:\\Ruleset.ruleset /out:Output.dll"", diff --git a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj similarity index 85% rename from src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj rename to src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj index 2923570a674ed..83a7f74a2b989 100644 --- a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.vbproj +++ b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj @@ -10,13 +10,13 @@ - + - + \ No newline at end of file diff --git a/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb b/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb index 14017094c6671..23f49a58edd30 100644 --- a/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb +++ b/src/Features/Lsif/GeneratorTest/ProjectStructureTests.vb @@ -5,7 +5,7 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Test.Utilities -Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests +Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Public NotInheritable Class ProjectStructureTests @@ -19,8 +19,8 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests )) - Dim projectVertex = Assert.Single(lsif.Vertices.OfType(Of LsifGraph.Project)) - Dim documentVertices = lsif.GetLinkedVertices(Of LsifGraph.Document)(projectVertex, "contains") + Dim projectVertex = Assert.Single(lsif.Vertices.OfType(Of Graph.Project)) + Dim documentVertices = lsif.GetLinkedVertices(Of Graph.Document)(projectVertex, "contains") Assert.Single(documentVertices, Function(d) d.Uri.LocalPath = "Z:\A.cs") Assert.Single(documentVertices, Function(d) d.Uri.LocalPath = "Z:\B.cs") diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb index a1f5afa7093ad..9c0810f141c5e 100644 --- a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -6,7 +6,7 @@ Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.VisualStudio.LanguageServer.Protocol -Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests +Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Public NotInheritable Class RangeResultSetTests Private Const TestProjectAssemblyName As String = "TestProject" @@ -30,8 +30,8 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests )) Dim rangeVertex = Await lsif.GetSelectedRangeAsync() - Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() - Dim monikerVertex = lsif.GetLinkedVertices(Of LsifGraph.Moniker)(resultSetVertex, "moniker").SingleOrDefault() + Dim resultSetVertex = lsif.GetLinkedVertices(Of Graph.ResultSet)(rangeVertex, "next").Single() + Dim monikerVertex = lsif.GetLinkedVertices(Of Graph.Moniker)(resultSetVertex, "moniker").SingleOrDefault() Assert.Equal(expectedMoniker, monikerVertex?.Identifier) End Sub @@ -49,11 +49,11 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests )) Dim rangeVertex = Await lsif.GetSelectedRangeAsync() - Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() - Dim definitionsVertex = lsif.GetLinkedVertices(Of LsifGraph.DefinitionResult)(resultSetVertex, Methods.TextDocumentDefinitionName).Single() + Dim resultSetVertex = lsif.GetLinkedVertices(Of Graph.ResultSet)(rangeVertex, "next").Single() + Dim definitionsVertex = lsif.GetLinkedVertices(Of Graph.DefinitionResult)(resultSetVertex, Methods.TextDocumentDefinitionName).Single() ' The definition vertex should point back to our range - Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of LsifGraph.Range)(definitionsVertex, "item")) + Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of Graph.Range)(definitionsVertex, "item")) Assert.Same(rangeVertex, referencedRange) End Sub @@ -70,11 +70,11 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests )) Dim rangeVertex = Await lsif.GetSelectedRangeAsync() - Dim resultSetVertex = lsif.GetLinkedVertices(Of LsifGraph.ResultSet)(rangeVertex, "next").Single() - Dim referencesVertex = lsif.GetLinkedVertices(Of LsifGraph.ReferenceResult)(resultSetVertex, Methods.TextDocumentReferencesName).Single() + Dim resultSetVertex = lsif.GetLinkedVertices(Of Graph.ResultSet)(rangeVertex, "next").Single() + Dim referencesVertex = lsif.GetLinkedVertices(Of Graph.ReferenceResult)(resultSetVertex, Methods.TextDocumentReferencesName).Single() ' The references vertex should point back to our range - Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of LsifGraph.Range)(referencesVertex, "item")) + Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of Graph.Range)(referencesVertex, "item")) Assert.Same(rangeVertex, referencedRange) End Sub End Class diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb index a9c2dbc8c5827..ad17df898df11 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb @@ -3,10 +3,10 @@ ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable -Imports Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph -Imports Microsoft.CodeAnalysis.Lsif.Generator.Writing +Imports Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph +Imports Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing -Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities +Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.Utilities ''' ''' A implementation of for use in unit tests. It does additional validation of the ''' correctness of the output, And stores the entire output And offers useful helpers to inspect the result. @@ -56,7 +56,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities ''' ''' Returns all the vertices linked to the given vertex by the edge type. ''' - Public Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As ImmutableArray(Of T) + Public Function GetLinkedVertices(Of T As Vertex)(vertex As Graph.Vertex, edgeLabel As String) As ImmutableArray(Of T) Dim builder = ImmutableArray.CreateBuilder(Of T) Dim edges As List(Of Edge) = Nothing diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index bbaaf1354b574..ce089292660d6 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -4,9 +4,9 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces -Imports Microsoft.CodeAnalysis.Lsif.Generator.LsifGraph +Imports Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph -Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities +Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.Utilities Friend Class TestLsifOutput Private ReadOnly _testLsifJsonWriter As TestLsifJsonWriter Private ReadOnly _workspace As TestWorkspace @@ -35,7 +35,7 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities ''' ''' Returns all the vertices linked to the given vertex by the edge type. ''' - Public Function GetLinkedVertices(Of T As Vertex)(vertex As LsifGraph.Vertex, edgeLabel As String) As ImmutableArray(Of T) + Public Function GetLinkedVertices(Of T As Vertex)(vertex As Graph.Vertex, edgeLabel As String) As ImmutableArray(Of T) Return _testLsifJsonWriter.GetLinkedVertices(Of T)(vertex, edgeLabel) End Function @@ -48,14 +48,14 @@ Namespace Microsoft.CodeAnalysis.Lsif.Generator.UnitTests.Utilities ''' ''' Returns the vertex in the output that corresponds to the selected range in the . ''' - Public Async Function GetSelectedRangeAsync() As Task(Of LsifGraph.Range) + Public Async Function GetSelectedRangeAsync() As Task(Of Graph.Range) Dim selectedTestDocument = _workspace.Documents.Single(Function(d) d.SelectedSpans.Any()) Dim selectedDocument = _workspace.CurrentSolution.GetDocument(selectedTestDocument.Id) Dim selectionTextSpan = selectedTestDocument.SelectedSpans.Single() Dim selectionRange = Range.FromTextSpan(selectionTextSpan, Await selectedDocument.GetTextAsync()) Dim documentVertex = _testLsifJsonWriter.Vertices _ - .OfType(Of LsifGraph.Document) _ + .OfType(Of Graph.Document) _ .Where(Function(d) d.Uri.LocalPath = selectedDocument.FilePath) _ .Single() diff --git a/src/VisualStudio/Core/Def/Implementation/FindUsages/MonikerWrapper.cs b/src/VisualStudio/Core/Def/Implementation/FindUsages/MonikerWrapper.cs index 3f8e689d6938e..43cf3fbdf0416 100644 --- a/src/VisualStudio/Core/Def/Implementation/FindUsages/MonikerWrapper.cs +++ b/src/VisualStudio/Core/Def/Implementation/FindUsages/MonikerWrapper.cs @@ -4,7 +4,7 @@ #nullable enable -using Microsoft.CodeAnalysis.LanguageServiceIndexFormat; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat; using VS.IntelliNav.Contracts; namespace Microsoft.VisualStudio.LanguageServices.Implementation.FindUsages diff --git a/src/VisualStudio/Core/Def/Implementation/FindUsages/VisualStudioFindSymbolMonikerUsagesService.cs b/src/VisualStudio/Core/Def/Implementation/FindUsages/VisualStudioFindSymbolMonikerUsagesService.cs index f58c8c98186f0..93caeb7189d04 100644 --- a/src/VisualStudio/Core/Def/Implementation/FindUsages/VisualStudioFindSymbolMonikerUsagesService.cs +++ b/src/VisualStudio/Core/Def/Implementation/FindUsages/VisualStudioFindSymbolMonikerUsagesService.cs @@ -13,7 +13,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.FindUsages; -using Microsoft.CodeAnalysis.LanguageServiceIndexFormat; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; diff --git a/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj b/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj index 4f0e02848d0ff..8e2791a08a1f9 100644 --- a/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Microsoft.CodeAnalysis.Workspaces.csproj @@ -52,8 +52,8 @@ - + From 08e5929020c9946b8d5b9954c01de7324b2eec72 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 16 Apr 2020 17:40:12 -0700 Subject: [PATCH 042/222] Switch to server GC This shaves around 20% off the total run time. --- src/Features/Lsif/Generator/App.config | 5 +++++ ...t.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj | 1 + 2 files changed, 6 insertions(+) create mode 100644 src/Features/Lsif/Generator/App.config diff --git a/src/Features/Lsif/Generator/App.config b/src/Features/Lsif/Generator/App.config new file mode 100644 index 0000000000000..807677b3b6af2 --- /dev/null +++ b/src/Features/Lsif/Generator/App.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj index 7e7b88d73d2c6..35363d239832a 100644 --- a/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj +++ b/src/Features/Lsif/Generator/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.csproj @@ -51,6 +51,7 @@ + From b58470da8b470e5df02809530fe95624078811f0 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 17 Apr 2020 11:52:23 -0700 Subject: [PATCH 043/222] Fix up BuildBoss errors by adding the transitive closure of references --- ...rverIndexFormat.Generator.UnitTests.vbproj | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj index 83a7f74a2b989..829438449db77 100644 --- a/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj +++ b/src/Features/Lsif/GeneratorTest/Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.vbproj @@ -11,6 +11,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f1ae49aa53e7771d980fdea63e9b1eef3770aec1 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 17 Apr 2020 15:50:32 -0700 Subject: [PATCH 044/222] Parallelize analysis of syntax trees This now analyzes syntax trees in parallel; we are still fetching each Compilation one at a time and only processing a single Project if you're processing an entire solution. --- src/Features/Lsif/Generator/Generator.cs | 24 ++-- src/Features/Lsif/Generator/Program.cs | 4 +- .../SymbolHoldingResultSetTracker.cs | 103 ++++++++++++------ .../Writing/InMemoryLsifJsonWriter.cs | 20 +++- .../Generator/Writing/TextLsifJsonWriter.cs | 12 +- .../GeneratorTest/Utilities/TestLsifOutput.vb | 2 +- 6 files changed, 109 insertions(+), 56 deletions(-) diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 26ec94054e008..207dec5bac698 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.ResultSetTracking; using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing; using Methods = Microsoft.VisualStudio.LanguageServer.Protocol.Methods; +using System.Collections.Concurrent; namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator { @@ -24,41 +25,44 @@ public Generator(ILsifJsonWriter lsifJsonWriter) _lsifJsonWriter = lsifJsonWriter; } - public async Task GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) + public void GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) { var projectVertex = new Graph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath)); _lsifJsonWriter.Write(projectVertex); _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, projectVertex.GetId())); - var documentIds = new List>(); + var documentIds = new ConcurrentBag>(); // We create a ResultSetTracker to track all top-level symbols in the project. We don't want all writes to immediately go to - // the JSON file once we support parallel processing, so we'll accumulate them and then apply at once. + // the JSON file -- we support parallel processing, so we'll accumulate them and then apply at once to avoid a lot + // of contention on shared locks. var topLevelSymbolsWriter = new InMemoryLsifJsonWriter(); var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter, compilation); - foreach (var syntaxTree in compilation.SyntaxTrees) + Parallel.ForEach(compilation.SyntaxTrees, syntaxTree => { var semanticModel = compilation.GetSemanticModel(syntaxTree); // We generate the document contents into an in-memory copy, and then write that out at once at the end. This // allows us to collect everything and avoid a lot of fine-grained contention on the write to the single // LSIF file. Becasue of the rule that vertices must be written before they're used by an edge, we'll flush any top- - // level symbol result sets made first, since the document contents will point to that. + // level symbol result sets made first, since the document contents will point to that. Parallel calls to CopyAndEmpty + // are allowed and might flush other unrelated stuff at the same time, but there's no harm -- the "causality" ordering + // is preserved. var documentWriter = new InMemoryLsifJsonWriter(); - var documentId = await GenerateForDocument(semanticModel, languageServices, topLevelSymbolsResultSetTracker, documentWriter); + var documentId = GenerateForDocument(semanticModel, languageServices, topLevelSymbolsResultSetTracker, documentWriter); topLevelSymbolsWriter.CopyToAndEmpty(_lsifJsonWriter); documentWriter.CopyToAndEmpty(_lsifJsonWriter); documentIds.Add(documentId); - } + }); - _lsifJsonWriter.Write(Edge.Create("contains", projectVertex.GetId(), documentIds)); + _lsifJsonWriter.Write(Edge.Create("contains", projectVertex.GetId(), documentIds.ToArray())); _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); } - private static Task> GenerateForDocument( + private static Id GenerateForDocument( SemanticModel semanticModel, HostLanguageServices languageServices, IResultSetTracker topLevelSymbolsResultSetTracker, @@ -165,7 +169,7 @@ public async Task GenerateForCompilation(Compilation compilation, string project lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices)); lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId())); - return Task.FromResult(documentVertex.GetId()); + return documentVertex.GetId(); } private static bool IncludeSymbolInReferences(ISymbol symbol) diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index 7c6d9d3259dc6..e142307d4d6bf 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -118,7 +118,7 @@ private static async Task GenerateFromSolutionWithMSBuildLocatedAsync(FileInfo s await logFile.WriteLineAsync($"Fetch of compilation for {project.FilePath} completed in {compilationCreationStopwatch.Elapsed.ToDisplayString()}."); var generationForProjectStopwatch = Stopwatch.StartNew(); - await lsifGenerator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices); + lsifGenerator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices); generationForProjectStopwatch.Stop(); totalTimeInGenerationPhase += generationForProjectStopwatch.Elapsed; @@ -143,7 +143,7 @@ private static async Task GenerateFromCompilerInvocationAsync(FileInfo compilerI using var lsifWriter = new TextLsifJsonWriter(outputWriter, outputFormat); var lsifGenerator = new Generator(lsifWriter); - await lsifGenerator.GenerateForCompilation(compilerInvocation.Compilation, compilerInvocation.ProjectFilePath, compilerInvocation.LanguageServices); + lsifGenerator.GenerateForCompilation(compilerInvocation.Compilation, compilerInvocation.ProjectFilePath, compilerInvocation.LanguageServices); await logFile.WriteLineAsync($"Generation for {compilerInvocation.ProjectFilePath} completed in {generationStopwatch.Elapsed.ToDisplayString()}."); } } diff --git a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 0b276a30450ea..6cab4a31a07b1 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -4,14 +4,17 @@ using System; using System.Collections.Generic; +using System.Threading; using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.ResultSetTracking { internal sealed class SymbolHoldingResultSetTracker : IResultSetTracker { private readonly Dictionary _symbolToResultSetId = new Dictionary(); + private readonly ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); private readonly ILsifJsonWriter _lsifJsonWriter; /// @@ -30,26 +33,51 @@ public SymbolHoldingResultSetTracker(ILsifJsonWriter lsifJsonWriter, Compilation private TrackedResultSet GetTrackedResultSet(ISymbol symbol) { - if (!_symbolToResultSetId.TryGetValue(symbol, out var trackedResultSet)) + TrackedResultSet trackedResultSet; + + // First acquire a simple read lock to see if we already have a result set; we do this with + // just a read lock to ensure we aren't contending a lot if the symbol already exists which + // is the most common case. + using (_readerWriterLock.DisposableRead()) + { + if (_symbolToResultSetId.TryGetValue(symbol, out trackedResultSet)) + { + return trackedResultSet; + } + } + + using (var upgradeableReadLock = _readerWriterLock.DisposableUpgradeableRead()) { + // Check a second for the result set since a request could have gotten between us + if (_symbolToResultSetId.TryGetValue(symbol, out trackedResultSet)) + { + return trackedResultSet; + } + + // We still don't have it, so we have to start writing now + upgradeableReadLock.EnterWrite(); + var resultSet = new ResultSet(); _lsifJsonWriter.Write(resultSet); trackedResultSet = new TrackedResultSet(resultSet.GetId()); _symbolToResultSetId.Add(symbol, trackedResultSet); + } - // Since we're creating a ResultSet for a symbol for the first time, let's also attach the moniker. We only generate - // monikers for original definitions as we don't have a moniker system for those, but also because the place where - // monikers are needed -- cross-solution find references and go to definition -- only operates on original definitions - // anyways. - if (symbol.OriginalDefinition.Equals(symbol)) - { - var monikerVertex = TryCreateMonikerVertexForSymbol(symbol); + // Since we're creating a ResultSet for a symbol for the first time, let's also attach the moniker. We only generate + // monikers for original definitions as we don't have a moniker system for those, but also because the place where + // monikers are needed -- cross-solution find references and go to definition -- only operates on original definitions + // anyways. + // + // This we do outside the lock -- whichever thread was the one to create this was the one that + // gets to write out the moniker, but others can use the ResultSet Id at this point. + if (symbol.OriginalDefinition.Equals(symbol)) + { + var monikerVertex = TryCreateMonikerVertexForSymbol(symbol); - if (monikerVertex != null) - { - _lsifJsonWriter.Write(monikerVertex); - _lsifJsonWriter.Write(Edge.Create("moniker", trackedResultSet.Id, monikerVertex.GetId())); - } + if (monikerVertex != null) + { + _lsifJsonWriter.Write(monikerVertex); + _lsifJsonWriter.Write(Edge.Create("moniker", trackedResultSet.Id, monikerVertex.GetId())); } } @@ -104,7 +132,8 @@ private class TrackedResultSet /// /// A map which holds the per-symbol results that are linked from the resultSet. The value will be null if the entry was - /// added via . + /// added via . Concurrent acecss is guarded with a monitor lock + /// on this field itself, with the belief that concurrent access for a single symbol is relatively rare. /// /// /// This class assumes that we more or less have two kinds of edges in the LSIF world: @@ -126,41 +155,47 @@ public TrackedResultSet(Id id) public Id GetResultId(string edgeKind, Func vertexCreator, ILsifJsonWriter lsifJsonWriter) where T : Vertex { - if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) + lock (_edgeKindToVertexId) { - if (!existingId.HasValue) + if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) { - throw new Exception($"This ResultSet already has an edge of {edgeKind} as {nameof(ResultSetNeedsInformationalEdgeAdded)} was called with this edge kind."); + if (!existingId.HasValue) + { + throw new Exception($"This ResultSet already has an edge of {edgeKind} as {nameof(ResultSetNeedsInformationalEdgeAdded)} was called with this edge kind."); + } + + // TODO: this is a violation of the type system here, really: we're assuming that all calls to this function with the same edge kind + // will have the same type parameter. If that's violated, the Id returned here isn't really the right type. + return new Id(existingId.Value.NumericId); } - // TODO: this is a violation of the type system here, really: we're assuming that all calls to this function with the same edge kind - // will have the same type parameter. If that's violated, the Id returned here isn't really the right type. - return new Id(existingId.Value.NumericId); - } - - T vertex = vertexCreator(); - _edgeKindToVertexId.Add(edgeKind, vertex.GetId().As()); + T vertex = vertexCreator(); + _edgeKindToVertexId.Add(edgeKind, vertex.GetId().As()); - lsifJsonWriter.Write(vertex); - lsifJsonWriter.Write(Edge.Create(edgeKind, Id, vertex.GetId())); + lsifJsonWriter.Write(vertex); + lsifJsonWriter.Write(Edge.Create(edgeKind, Id, vertex.GetId())); - return vertex.GetId(); + return vertex.GetId(); + } } public bool ResultSetNeedsInformationalEdgeAdded(string edgeKind) { - if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) + lock (_edgeKindToVertexId) { - if (existingId.HasValue) + if (_edgeKindToVertexId.TryGetValue(edgeKind, out var existingId)) { - throw new InvalidOperationException($"This edge kind was already called with a call to {nameof(GetResultId)} which would imply we are mixing edge types incorrectly."); + if (existingId.HasValue) + { + throw new InvalidOperationException($"This edge kind was already called with a call to {nameof(GetResultId)} which would imply we are mixing edge types incorrectly."); + } + + return false; } - return false; + _edgeKindToVertexId.Add(edgeKind, null); + return true; } - - _edgeKindToVertexId.Add(edgeKind, null); - return true; } } } diff --git a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs index faccd0cc113f1..2af0ed7fc9ac9 100644 --- a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs @@ -9,21 +9,31 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing { internal sealed class InMemoryLsifJsonWriter : ILsifJsonWriter { - private readonly List _elements = new List(); + private readonly object _gate = new object(); + private List _elements = new List(); public void Write(Element element) { - _elements.Add(element); + lock (_gate) + { + _elements.Add(element); + } } public void CopyToAndEmpty(ILsifJsonWriter writer) { - foreach (var element in _elements) + List localElements; + + lock (_gate) { - writer.Write(element); + localElements = _elements; + _elements = new List(); } - _elements.Clear(); + foreach (var element in localElements) + { + writer.Write(element); + } } } } diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs index b99d58807709c..9ec3e5a3afd01 100644 --- a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs @@ -15,6 +15,7 @@ internal sealed class TextLsifJsonWriter : ILsifJsonWriter, IDisposable private readonly JsonTextWriter _jsonTextWriter; private readonly JsonSerializer _jsonSerializer; private readonly LsifFormat _format; + private readonly object _writeGate = new object(); public TextLsifJsonWriter(TextWriter outputWriter, LsifFormat format) { @@ -40,11 +41,14 @@ public TextLsifJsonWriter(TextWriter outputWriter, LsifFormat format) public void Write(Element element) { - _jsonSerializer.Serialize(_jsonTextWriter, element); - - if (_format == LsifFormat.Line) + lock (_writeGate) { - _jsonTextWriter.WriteWhitespace("\r\n"); + _jsonSerializer.Serialize(_jsonTextWriter, element); + + if (_format == LsifFormat.Line) + { + _jsonTextWriter.WriteWhitespace("\r\n"); + } } } diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index ce089292660d6..b5e59b28d54ad 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -22,7 +22,7 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U For Each project In workspace.CurrentSolution.Projects Dim compilation = Await project.GetCompilationAsync() - Await generator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices) + generator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices) Next Return New TestLsifOutput(testLsifJsonWriter, workspace) From 7a8a17b8e0a7663a07c333fbfd49d15717e3737a Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 17 Apr 2020 17:22:54 -0700 Subject: [PATCH 045/222] Split apart the ILsifJsonWriter that writes to an actual text stream Two separate implementations are easier than one, as it also allows more stuff to be moved outside of the write lock in the case of line mode. --- src/Features/Lsif/Generator/Program.cs | 21 ++-- .../Writing/JsonModeLsifJsonWriter.cs | 54 ++++++++++ .../Writing/LineModeLsifJsonWriter.cs | 44 +++++++++ .../Lsif/Generator/Writing/LsifConverter.cs | 44 +++++++++ .../Generator/Writing/TextLsifJsonWriter.cs | 99 ------------------- 5 files changed, 155 insertions(+), 107 deletions(-) create mode 100644 src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs create mode 100644 src/Features/Lsif/Generator/Writing/LineModeLsifJsonWriter.cs create mode 100644 src/Features/Lsif/Generator/Writing/LsifConverter.cs delete mode 100644 src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs diff --git a/src/Features/Lsif/Generator/Program.cs b/src/Features/Lsif/Generator/Program.cs index e142307d4d6bf..502c05636c641 100644 --- a/src/Features/Lsif/Generator/Program.cs +++ b/src/Features/Lsif/Generator/Program.cs @@ -42,17 +42,23 @@ private static async Task GenerateAsync(FileInfo? solution, FileInfo? compilerIn TextWriter outputWriter = outputFile ?? Console.Out; using TextWriter logFile = log != null ? new StreamWriter(log) : TextWriter.Null; + ILsifJsonWriter lsifWriter = outputFormat switch + { + LsifFormat.Json => new JsonModeLsifJsonWriter(outputWriter), + LsifFormat.Line => new LineModeLsifJsonWriter(outputWriter), + _ => throw new NotImplementedException() + }; try { // Exactly one of "solution" or "compilerInvocation" should be specified if (solution != null && compilerInvocation == null) { - await GenerateFromSolutionAsync(solution, outputWriter, outputFormat, logFile); + await GenerateFromSolutionAsync(solution, lsifWriter, logFile); } else if (compilerInvocation != null && solution == null) { - await GenerateFromCompilerInvocationAsync(compilerInvocation, outputWriter, outputFormat, logFile); + await GenerateFromCompilerInvocationAsync(compilerInvocation, lsifWriter, logFile); } else { @@ -68,10 +74,11 @@ private static async Task GenerateAsync(FileInfo? solution, FileInfo? compilerIn throw; } + (lsifWriter as IDisposable)?.Dispose(); await logFile.WriteLineAsync("Generation complete."); } - private static async Task GenerateFromSolutionAsync(FileInfo solutionFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) + private static async Task GenerateFromSolutionAsync(FileInfo solutionFile, ILsifJsonWriter lsifWriter, TextWriter logFile) { // Make sure we pick the highest version var msbuildInstance = MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(i => i.Version).FirstOrDefault(); @@ -86,13 +93,13 @@ private static async Task GenerateFromSolutionAsync(FileInfo solutionFile, TextW MSBuildLocator.RegisterInstance(msbuildInstance); - await GenerateFromSolutionWithMSBuildLocatedAsync(solutionFile, outputWriter, outputFormat, logFile); + await GenerateFromSolutionWithMSBuildLocatedAsync(solutionFile, lsifWriter, logFile); } // This method can't be loaded until we've registered MSBuild with MSBuildLocator, as otherwise // we load ILogger prematurely which breaks MSBuildLocator. [MethodImpl(MethodImplOptions.NoInlining)] - private static async Task GenerateFromSolutionWithMSBuildLocatedAsync(FileInfo solutionFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) + private static async Task GenerateFromSolutionWithMSBuildLocatedAsync(FileInfo solutionFile, ILsifJsonWriter lsifWriter, TextWriter logFile) { await logFile.WriteLineAsync($"Loading {solutionFile.FullName}..."); @@ -102,7 +109,6 @@ private static async Task GenerateFromSolutionWithMSBuildLocatedAsync(FileInfo s var solution = await msbuildWorkspace.OpenSolutionAsync(solutionFile.FullName); await logFile.WriteLineAsync($"Load of the solution completed in {solutionLoadStopwatch.Elapsed.ToDisplayString()}."); - var lsifWriter = new TextLsifJsonWriter(outputWriter, outputFormat); var lsifGenerator = new Generator(lsifWriter); Stopwatch totalTimeInGenerationAndCompilationFetchStopwatch = Stopwatch.StartNew(); @@ -131,7 +137,7 @@ private static async Task GenerateFromSolutionWithMSBuildLocatedAsync(FileInfo s await logFile.WriteLineAsync($"Total time spent in the generation phase for all projects, including compilation fetch time: {totalTimeInGenerationAndCompilationFetchStopwatch.Elapsed.ToDisplayString()}"); } - private static async Task GenerateFromCompilerInvocationAsync(FileInfo compilerInvocationFile, TextWriter outputWriter, LsifFormat outputFormat, TextWriter logFile) + private static async Task GenerateFromCompilerInvocationAsync(FileInfo compilerInvocationFile, ILsifJsonWriter lsifWriter, TextWriter logFile) { await logFile.WriteLineAsync($"Processing compiler invocation from {compilerInvocationFile.FullName}..."); @@ -140,7 +146,6 @@ private static async Task GenerateFromCompilerInvocationAsync(FileInfo compilerI await logFile.WriteLineAsync($"Load of the project completed in {compilerInvocationLoadStopwatch.Elapsed.ToDisplayString()}."); var generationStopwatch = Stopwatch.StartNew(); - using var lsifWriter = new TextLsifJsonWriter(outputWriter, outputFormat); var lsifGenerator = new Generator(lsifWriter); lsifGenerator.GenerateForCompilation(compilerInvocation.Compilation, compilerInvocation.ProjectFilePath, compilerInvocation.LanguageServices); diff --git a/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs new file mode 100644 index 0000000000000..4724caae0acdc --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing +{ + /// + /// An that writes in . + /// + internal sealed class JsonModeLsifJsonWriter : ILsifJsonWriter, IDisposable + { + private readonly JsonTextWriter _jsonTextWriter; + private readonly JsonSerializer _jsonSerializer; + private readonly object _writeGate = new object(); + + public JsonModeLsifJsonWriter(TextWriter outputWriter) + { + var settings = new JsonSerializerSettings + { + Formatting = Newtonsoft.Json.Formatting.Indented, + NullValueHandling = NullValueHandling.Ignore, + ContractResolver = new CamelCasePropertyNamesContractResolver(), + TypeNameHandling = TypeNameHandling.None, + Converters = new[] { new LsifConverter() } + }; + + _jsonSerializer = JsonSerializer.Create(settings); + + _jsonTextWriter = new JsonTextWriter(outputWriter); + _jsonTextWriter.WriteStartArray(); + } + + public void Write(Element element) + { + lock (_writeGate) + { + _jsonSerializer.Serialize(_jsonTextWriter, element); + _jsonTextWriter.WriteWhitespace("\r\n"); + } + } + + public void Dispose() + { + _jsonTextWriter.WriteEndArray(); + _jsonTextWriter.Close(); + } + } +} diff --git a/src/Features/Lsif/Generator/Writing/LineModeLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/LineModeLsifJsonWriter.cs new file mode 100644 index 0000000000000..826e372a09644 --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/LineModeLsifJsonWriter.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.IO; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing +{ + /// + /// An that writes in . + /// + internal sealed partial class LineModeLsifJsonWriter : ILsifJsonWriter + { + private readonly object _writeGate = new object(); + private readonly TextWriter _outputWriter; + private readonly JsonSerializerSettings _settings; + + public LineModeLsifJsonWriter(TextWriter outputWriter) + { + _settings = new JsonSerializerSettings + { + Formatting = Newtonsoft.Json.Formatting.None, + NullValueHandling = NullValueHandling.Ignore, + ContractResolver = new CamelCasePropertyNamesContractResolver(), + TypeNameHandling = TypeNameHandling.None, + Converters = new[] { new LsifConverter() } + }; + _outputWriter = outputWriter; + } + + public void Write(Element element) + { + string line = JsonConvert.SerializeObject(element, _settings); + + lock (_writeGate) + { + _outputWriter.WriteLine(line); + } + } + } +} diff --git a/src/Features/Lsif/Generator/Writing/LsifConverter.cs b/src/Features/Lsif/Generator/Writing/LsifConverter.cs new file mode 100644 index 0000000000000..f4b23caa37385 --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/LsifConverter.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; +using Newtonsoft.Json; + +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing +{ + internal sealed class LsifConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return typeof(ISerializableId).IsAssignableFrom(objectType) || + objectType == typeof(Uri); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + switch (value) + { + case ISerializableId id: + + writer.WriteValue(id.NumericId); + break; + + case Uri uri: + + writer.WriteValue(uri.AbsoluteUri); + break; + + default: + + throw new NotSupportedException(); + } + } + } +} diff --git a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs deleted file mode 100644 index 9ec3e5a3afd01..0000000000000 --- a/src/Features/Lsif/Generator/Writing/TextLsifJsonWriter.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing -{ - internal sealed class TextLsifJsonWriter : ILsifJsonWriter, IDisposable - { - private readonly JsonTextWriter _jsonTextWriter; - private readonly JsonSerializer _jsonSerializer; - private readonly LsifFormat _format; - private readonly object _writeGate = new object(); - - public TextLsifJsonWriter(TextWriter outputWriter, LsifFormat format) - { - _format = format; - _jsonTextWriter = new JsonTextWriter(outputWriter); - - var settings = new JsonSerializerSettings - { - Formatting = _format == LsifFormat.Json ? Newtonsoft.Json.Formatting.Indented : Newtonsoft.Json.Formatting.None, - NullValueHandling = NullValueHandling.Ignore, - ContractResolver = new CamelCasePropertyNamesContractResolver(), - TypeNameHandling = TypeNameHandling.None, - Converters = new[] { new LsifConverter() } - }; - - _jsonSerializer = JsonSerializer.Create(settings); - - if (_format == LsifFormat.Json) - { - _jsonTextWriter.WriteStartArray(); - } - } - - public void Write(Element element) - { - lock (_writeGate) - { - _jsonSerializer.Serialize(_jsonTextWriter, element); - - if (_format == LsifFormat.Line) - { - _jsonTextWriter.WriteWhitespace("\r\n"); - } - } - } - - public void Dispose() - { - if (_format == LsifFormat.Json) - { - _jsonTextWriter.WriteEndArray(); - } - - _jsonTextWriter.Close(); - } - - internal class LsifConverter : JsonConverter - { - public override bool CanConvert(Type objectType) - { - return typeof(ISerializableId).IsAssignableFrom(objectType) || - objectType == typeof(Uri); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - switch (value) - { - case ISerializableId id: - - writer.WriteValue(id.NumericId); - break; - - case Uri uri: - - writer.WriteValue(uri.AbsoluteUri); - break; - - default: - - throw new NotSupportedException(); - } - } - } - } -} From 59bdd3358b2385e4e65f852c1c57ac3faf128553 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 18 Apr 2020 16:56:35 +0100 Subject: [PATCH 046/222] Refix the bug in its new location (after merging a refactor) Use different condition to the one used in https://github.com/dotnet/roslyn/pull/23817/files#diff-aad522f9b1eb080adef996187a2a1b28R65 I think this should still be valid for tuples --- .../Simplification/VisualBasicInferredMemberNameSimplifier.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb index cf1fdc862261c..75ac7b412bebc 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb @@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification End Function Friend Function CanSimplifyNamedFieldInitializer(node As NamedFieldInitializerSyntax) As Boolean - If RemovalCausesAmbiguity(DirectCast(node.Parent, ObjectMemberInitializerSyntax).Initializers, node) Then + If node.Parent.IsParentKind(SyntaxKind.ObjectCreationExpression) OrElse RemovalCausesAmbiguity(DirectCast(node.Parent, ObjectMemberInitializerSyntax).Initializers, node) Then Return False End If From 1b5e19f1dd728f720982888c03521e9b66ff9ed3 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Sat, 25 Apr 2020 14:07:22 -0700 Subject: [PATCH 047/222] Ensure PackageInstallerService does not require the UI thread during GetSuggestedActions --- .../AddUsing/AddUsingTests_NuGet.cs | 18 +++---- .../AddImport/AddImportTests_NuGet.vb | 18 +++---- .../AbstractAddImportCodeFixProvider.cs | 2 +- .../AbstractAddPackageCodeFixProvider.cs | 2 +- .../PackageInstallerServiceFactory.cs | 53 ++++++++++++++----- .../Packaging/IPackageInstallerService.cs | 3 +- 6 files changed, 63 insertions(+), 33 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs index 2e45f70efea3e..d8279b59eeef9 100644 --- a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs +++ b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs @@ -28,8 +28,8 @@ public class AddUsingNuGetTests : AbstractAddUsingTests { const string NugetOrgSource = "nuget.org"; - private static readonly ImmutableArray NugetPackageSources = - ImmutableArray.Create(new PackageSource(NugetOrgSource, "http://nuget.org/")); + private static readonly ValueTask> NugetPackageSources = + new ValueTask>(ImmutableArray.Create(new PackageSource(NugetOrgSource, "http://nuget.org/"))); protected override TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters) { @@ -57,7 +57,7 @@ public async Task TestSearchPackageSingleName() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); @@ -88,7 +88,7 @@ public async Task TestSearchPackageMultipleNames() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); @@ -117,7 +117,7 @@ public async Task TestMissingIfPackageAlreadyInstalled() { var installerServiceMock = new Mock(MockBehavior.Strict); installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")) .Returns(true); @@ -143,7 +143,7 @@ public async Task TestOptionsOffered() installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(Enumerable.Empty()); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "2.0")).Returns(Enumerable.Empty()); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) .Returns(ImmutableArray.Create("1.0", "2.0")); @@ -187,7 +187,7 @@ public async Task TestInstallGetsCalledNoVersion() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", /*versionOpt*/ null, It.IsAny(), It.IsAny())) .Returns(true); @@ -219,7 +219,7 @@ public async Task TestInstallGetsCalledWithVersion() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(Enumerable.Empty()); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) .Returns(ImmutableArray.Create("1.0")); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny())) @@ -253,7 +253,7 @@ public async Task TestFailedInstallRollsBackFile() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(Enumerable.Empty()); - installerServiceMock.Setup(i => i.GetPackageSources()).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) .Returns(ImmutableArray.Create("1.0")); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny())) diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb index f2a97b8b942ab..8d74c6a5fe846 100644 --- a/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb +++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb @@ -20,8 +20,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeActions.AddImp Const NugetOrgSource = "nuget.org" - Private Shared ReadOnly NugetPackageSources As ImmutableArray(Of PackageSource) = - ImmutableArray.Create(New PackageSource(NugetOrgSource, "http://nuget.org")) + Private Shared ReadOnly NugetPackageSources As ValueTask(Of ImmutableArray(Of PackageSource)) = + New ValueTask(Of ImmutableArray(Of PackageSource))(ImmutableArray.Create(New PackageSource(NugetOrgSource, "http://nuget.org"))) Protected Overrides Function CreateWorkspaceFromFile(initialMarkup As String, parameters As TestParameters) As TestWorkspace Dim workspace = MyBase.CreateWorkspaceFromFile(initialMarkup, parameters) @@ -52,7 +52,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeActions.AddImp installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", It.IsAny(Of String), It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(True) @@ -81,7 +81,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", It.IsAny(Of String), It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(True) @@ -110,7 +110,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", It.IsAny(Of String), It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(False) @@ -135,7 +135,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa Public Async Function TestMissingIfPackageAlreadyInstalled() As Task Dim installerServiceMock = New Mock(Of IPackageInstallerService)(MockBehavior.Strict) installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.IsInstalled(It.IsAny(Of Workspace)(), It.IsAny(Of ProjectId)(), "NuGetPackage")). Returns(True) @@ -160,7 +160,7 @@ New TestParameters(fixProviderData:=New ProviderData(installerServiceMock.Object installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetProjectsWithInstalledPackage(It.IsAny(Of Solution), "NuGetPackage", "1.0")).Returns(Enumerable.Empty(Of Project)) installerServiceMock.Setup(Function(i) i.GetProjectsWithInstalledPackage(It.IsAny(Of Solution), "NuGetPackage", "2.0")).Returns(Enumerable.Empty(Of Project)) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.GetInstalledVersions("NuGetPackage")). Returns(ImmutableArray.Create("1.0", "2.0")) @@ -202,7 +202,7 @@ parameters:=New TestParameters(index:=2, fixProviderData:=data)) installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", Nothing, It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(True) @@ -232,7 +232,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetProjectsWithInstalledPackage(It.IsAny(Of Solution), "NuGetPackage", "1.0")).Returns(Enumerable.Empty(Of Project)) - installerServiceMock.Setup(Function(i) i.GetPackageSources()).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.GetInstalledVersions("NuGetPackage")). Returns(ImmutableArray.Create("1.0")) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", "1.0", It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). diff --git a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs index d581823a15a0b..53f89eeb0f941 100644 --- a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs @@ -57,7 +57,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) var installerService = GetPackageInstallerService(document); var packageSources = searchNuGetPackages && symbolSearchService != null && installerService?.IsEnabled(document.Project.Id) == true - ? installerService.GetPackageSources() + ? await installerService.GetPackageSourcesAsync(allowSwitchToMainThread: false, context.CancellationToken).ConfigureAwait(false) : ImmutableArray.Empty; var fixesForDiagnostic = await addImportService.GetFixesForDiagnosticsAsync( diff --git a/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs b/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs index 5a7f3b02492cf..bb9b190e663f4 100644 --- a/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs @@ -58,7 +58,7 @@ protected async Task> GetAddPackagesCodeActionsAsync( searchNugetPackages && installerService.IsEnabled(document.Project.Id)) { - foreach (var packageSource in installerService.GetPackageSources()) + foreach (var packageSource in await installerService.GetPackageSourcesAsync(allowSwitchToMainThread: false, cancellationToken).ConfigureAwait(false)) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 57a2b4ecf0f3b..ce924103d5ac9 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -19,12 +19,12 @@ using Microsoft.CodeAnalysis.Packaging; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.SymbolSearch; -using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; using Microsoft.VisualStudio.LanguageServices.SymbolSearch; using Microsoft.VisualStudio.LanguageServices.Utilities; using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Threading; using NuGet.VisualStudio; using Roslyn.Utilities; using SVsServiceProvider = Microsoft.VisualStudio.Shell.SVsServiceProvider; @@ -56,6 +56,7 @@ internal partial class PackageInstallerService : AbstractDelayStartedService, IP private readonly Lazy _packageSourceProvider; private ImmutableArray _packageSources; + private JoinableTask> _packageSourcesAsync; private IVsPackage _nugetPackageManager; private CancellationTokenSource _tokenSource = new CancellationTokenSource(); @@ -93,7 +94,7 @@ public PackageInstallerService( _packageSourceProvider = packageSourceProvider; } - public ImmutableArray GetPackageSources() + public async ValueTask> GetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken) { // Only read from _packageSources once, since OnSourceProviderSourcesChanged could reset it to default at // any time while this method is running. @@ -103,21 +104,27 @@ public ImmutableArray GetPackageSources() return packageSources; } - try + lock (_gate) { - packageSources = _packageSourceProvider.Value.GetSources(includeUnOfficial: true, includeDisabled: false) - .SelectAsArray(r => new PackageSource(r.Key, r.Value)); + if (_packageSourcesAsync is null) + { + _packageSourcesAsync = ThreadingContext.JoinableTaskFactory.RunAsync(() => GetPackageSourcesImplAsync()); + } } - catch (Exception ex) when (ex is InvalidDataException || ex is InvalidOperationException) + + if (allowSwitchToMainThread) { - // These exceptions can happen when the nuget.config file is broken. - packageSources = ImmutableArray.Empty; + using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); + packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); } - catch (ArgumentException ae) when (FatalError.ReportWithoutCrash(ae)) + else if (_packageSourcesAsync.IsCompleted) { - // This exception can happen when the nuget.config file is broken, e.g. invalid credentials. - // https://github.com/dotnet/roslyn/issues/40857 - packageSources = ImmutableArray.Empty; + packageSources = _packageSourcesAsync.GetAwaiter().GetResult(); + } + else + { + // Return without caching a result + return ImmutableArray.Empty; } var previousPackageSources = ImmutableInterlocked.InterlockedCompareExchange(ref _packageSources, packageSources, default); @@ -130,6 +137,28 @@ public ImmutableArray GetPackageSources() return packageSources; } + private async Task> GetPackageSourcesImplAsync() + { + await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_tokenSource.Token); + + try + { + return _packageSourceProvider.Value.GetSources(includeUnOfficial: true, includeDisabled: false) + .SelectAsArray(r => new PackageSource(r.Key, r.Value)); + } + catch (Exception ex) when (ex is InvalidDataException || ex is InvalidOperationException) + { + // These exceptions can happen when the nuget.config file is broken. + return ImmutableArray.Empty; + } + catch (ArgumentException ae) when (FatalError.ReportWithoutCrash(ae)) + { + // This exception can happen when the nuget.config file is broken, e.g. invalid credentials. + // https://github.com/dotnet/roslyn/issues/40857 + return ImmutableArray.Empty; + } + } + public event EventHandler PackageSourcesChanged; private bool IsEnabled diff --git a/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs b/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs index 4037175c6055f..3b68aae36c079 100644 --- a/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs +++ b/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; using Roslyn.Utilities; @@ -28,7 +29,7 @@ bool TryInstallPackage(Workspace workspace, DocumentId documentId, bool CanShowManagePackagesDialog(); void ShowManagePackagesDialog(string packageName); - ImmutableArray GetPackageSources(); + ValueTask> GetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken); event EventHandler PackageSourcesChanged; } From 03994ce1172c67f577705c3221a48be34361d750 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 27 Apr 2020 12:17:41 -0700 Subject: [PATCH 048/222] Clarify results when packages are not available --- .../CSharpTest/AddUsing/AddUsingTests_NuGet.cs | 18 +++++++++--------- .../AddImport/AddImportTests_NuGet.vb | 18 +++++++++--------- .../AbstractAddImportCodeFixProvider.cs | 12 ++++++++++-- .../AbstractAddPackageCodeFixProvider.cs | 6 +++++- .../PackageInstallerServiceFactory.cs | 7 ++++--- .../Packaging/IPackageInstallerService.cs | 13 ++++++++++++- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs index d8279b59eeef9..a084f12a94917 100644 --- a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs +++ b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingTests_NuGet.cs @@ -28,8 +28,8 @@ public class AddUsingNuGetTests : AbstractAddUsingTests { const string NugetOrgSource = "nuget.org"; - private static readonly ValueTask> NugetPackageSources = - new ValueTask>(ImmutableArray.Create(new PackageSource(NugetOrgSource, "http://nuget.org/"))); + private static readonly ValueTask?> NugetPackageSources = + new ValueTask?>(ImmutableArray.Create(new PackageSource(NugetOrgSource, "http://nuget.org/"))); protected override TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters) { @@ -57,7 +57,7 @@ public async Task TestSearchPackageSingleName() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); @@ -88,7 +88,7 @@ public async Task TestSearchPackageMultipleNames() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", It.IsAny(), It.IsAny(), It.IsAny())) .Returns(true); @@ -117,7 +117,7 @@ public async Task TestMissingIfPackageAlreadyInstalled() { var installerServiceMock = new Mock(MockBehavior.Strict); installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")) .Returns(true); @@ -143,7 +143,7 @@ public async Task TestOptionsOffered() installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(Enumerable.Empty()); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "2.0")).Returns(Enumerable.Empty()); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) .Returns(ImmutableArray.Create("1.0", "2.0")); @@ -187,7 +187,7 @@ public async Task TestInstallGetsCalledNoVersion() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray.Empty); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", /*versionOpt*/ null, It.IsAny(), It.IsAny())) .Returns(true); @@ -219,7 +219,7 @@ public async Task TestInstallGetsCalledWithVersion() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(Enumerable.Empty()); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) .Returns(ImmutableArray.Create("1.0")); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny())) @@ -253,7 +253,7 @@ public async Task TestFailedInstallRollsBackFile() installerServiceMock.Setup(i => i.IsEnabled(It.IsAny())).Returns(true); installerServiceMock.Setup(i => i.IsInstalled(It.IsAny(), It.IsAny(), "NuGetPackage")).Returns(false); installerServiceMock.Setup(i => i.GetProjectsWithInstalledPackage(It.IsAny(), "NuGetPackage", "1.0")).Returns(Enumerable.Empty()); - installerServiceMock.Setup(i => i.GetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); + installerServiceMock.Setup(i => i.TryGetPackageSourcesAsync(It.IsAny(), It.IsAny())).Returns(NugetPackageSources); installerServiceMock.Setup(s => s.GetInstalledVersions("NuGetPackage")) .Returns(ImmutableArray.Create("1.0")); installerServiceMock.Setup(s => s.TryInstallPackage(It.IsAny(), It.IsAny(), It.IsAny(), "NuGetPackage", "1.0", It.IsAny(), It.IsAny())) diff --git a/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb b/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb index 8d74c6a5fe846..50caf5f3d78d1 100644 --- a/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb +++ b/src/EditorFeatures/VisualBasicTest/Diagnostics/AddImport/AddImportTests_NuGet.vb @@ -20,8 +20,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeActions.AddImp Const NugetOrgSource = "nuget.org" - Private Shared ReadOnly NugetPackageSources As ValueTask(Of ImmutableArray(Of PackageSource)) = - New ValueTask(Of ImmutableArray(Of PackageSource))(ImmutableArray.Create(New PackageSource(NugetOrgSource, "http://nuget.org"))) + Private Shared ReadOnly NugetPackageSources As ValueTask(Of ImmutableArray(Of PackageSource)?) = + New ValueTask(Of ImmutableArray(Of PackageSource)?)(ImmutableArray.Create(New PackageSource(NugetOrgSource, "http://nuget.org"))) Protected Overrides Function CreateWorkspaceFromFile(initialMarkup As String, parameters As TestParameters) As TestWorkspace Dim workspace = MyBase.CreateWorkspaceFromFile(initialMarkup, parameters) @@ -52,7 +52,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeActions.AddImp installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", It.IsAny(Of String), It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(True) @@ -81,7 +81,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", It.IsAny(Of String), It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(True) @@ -110,7 +110,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", It.IsAny(Of String), It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(False) @@ -135,7 +135,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa Public Async Function TestMissingIfPackageAlreadyInstalled() As Task Dim installerServiceMock = New Mock(Of IPackageInstallerService)(MockBehavior.Strict) installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.IsInstalled(It.IsAny(Of Workspace)(), It.IsAny(Of ProjectId)(), "NuGetPackage")). Returns(True) @@ -160,7 +160,7 @@ New TestParameters(fixProviderData:=New ProviderData(installerServiceMock.Object installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetProjectsWithInstalledPackage(It.IsAny(Of Solution), "NuGetPackage", "1.0")).Returns(Enumerable.Empty(Of Project)) installerServiceMock.Setup(Function(i) i.GetProjectsWithInstalledPackage(It.IsAny(Of Solution), "NuGetPackage", "2.0")).Returns(Enumerable.Empty(Of Project)) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.GetInstalledVersions("NuGetPackage")). Returns(ImmutableArray.Create("1.0", "2.0")) @@ -202,7 +202,7 @@ parameters:=New TestParameters(index:=2, fixProviderData:=data)) installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetInstalledVersions("NuGetPackage")).Returns(ImmutableArray(Of String).Empty) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", Nothing, It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). Returns(True) @@ -232,7 +232,7 @@ End Class", fixProviderData:=New ProviderData(installerServiceMock.Object, packa installerServiceMock.Setup(Function(i) i.IsEnabled(It.IsAny(Of ProjectId))).Returns(True) installerServiceMock.Setup(Function(i) i.IsInstalled(It.IsAny(Of Workspace), It.IsAny(Of ProjectId), "NuGetPackage")).Returns(False) installerServiceMock.Setup(Function(i) i.GetProjectsWithInstalledPackage(It.IsAny(Of Solution), "NuGetPackage", "1.0")).Returns(Enumerable.Empty(Of Project)) - installerServiceMock.Setup(Function(i) i.GetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) + installerServiceMock.Setup(Function(i) i.TryGetPackageSourcesAsync(It.IsAny(Of Boolean)(), It.IsAny(Of CancellationToken)())).Returns(NugetPackageSources) installerServiceMock.Setup(Function(s) s.GetInstalledVersions("NuGetPackage")). Returns(ImmutableArray.Create("1.0")) installerServiceMock.Setup(Function(s) s.TryInstallPackage(It.IsAny(Of Workspace), It.IsAny(Of DocumentId), It.IsAny(Of String), "NuGetPackage", "1.0", It.IsAny(Of Boolean), It.IsAny(Of CancellationToken))). diff --git a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs index 53f89eeb0f941..98d3ac7196516 100644 --- a/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs @@ -57,11 +57,19 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) var installerService = GetPackageInstallerService(document); var packageSources = searchNuGetPackages && symbolSearchService != null && installerService?.IsEnabled(document.Project.Id) == true - ? await installerService.GetPackageSourcesAsync(allowSwitchToMainThread: false, context.CancellationToken).ConfigureAwait(false) + ? await installerService.TryGetPackageSourcesAsync(allowSwitchToMainThread: false, context.CancellationToken).ConfigureAwait(false) : ImmutableArray.Empty; + if (packageSources is null) + { + // Information about package sources is not available. This code fix cannot provide results for NuGet + // packages at this time, but future invocations of the code fix will work. For the current code fix + // operation, just treat the package sources as empty. + packageSources = ImmutableArray.Empty; + } + var fixesForDiagnostic = await addImportService.GetFixesForDiagnosticsAsync( - document, span, diagnostics, MaxResults, symbolSearchService, searchReferenceAssemblies, packageSources, cancellationToken).ConfigureAwait(false); + document, span, diagnostics, MaxResults, symbolSearchService, searchReferenceAssemblies, packageSources.Value, cancellationToken).ConfigureAwait(false); foreach (var (diagnostic, fixes) in fixesForDiagnostic) { diff --git a/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs b/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs index bb9b190e663f4..5cb014cbeeac5 100644 --- a/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddPackage/AbstractAddPackageCodeFixProvider.cs @@ -58,7 +58,11 @@ protected async Task> GetAddPackagesCodeActionsAsync( searchNugetPackages && installerService.IsEnabled(document.Project.Id)) { - foreach (var packageSource in await installerService.GetPackageSourcesAsync(allowSwitchToMainThread: false, cancellationToken).ConfigureAwait(false)) + var packageSources = + await installerService.TryGetPackageSourcesAsync(allowSwitchToMainThread: false, cancellationToken).ConfigureAwait(false) + ?? ImmutableArray.Empty; + + foreach (var packageSource in packageSources) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index ce924103d5ac9..a4a9533d1ae84 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -94,7 +94,7 @@ public PackageInstallerService( _packageSourceProvider = packageSourceProvider; } - public async ValueTask> GetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken) + public async ValueTask?> TryGetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken) { // Only read from _packageSources once, since OnSourceProviderSourcesChanged could reset it to default at // any time while this method is running. @@ -123,8 +123,9 @@ public async ValueTask> GetPackageSourcesAsync(boo } else { - // Return without caching a result - return ImmutableArray.Empty; + // The result was not available and switching to the main thread is not allowed. Return without caching + // a result. + return null; } var previousPackageSources = ImmutableInterlocked.InterlockedCompareExchange(ref _packageSources, packageSources, default); diff --git a/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs b/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs index 3b68aae36c079..c81314cf1aca7 100644 --- a/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs +++ b/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs @@ -29,7 +29,18 @@ bool TryInstallPackage(Workspace workspace, DocumentId documentId, bool CanShowManagePackagesDialog(); void ShowManagePackagesDialog(string packageName); - ValueTask> GetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken); + /// + /// Gets the package sources applicable to the workspace. + /// + /// to allow the implementation to switch to the + /// main thread (if necessary) to compute the result; otherwise to return without an + /// answer if such a switch would be required. + /// The cancellation token that the asynchronous operation will observe. + /// + /// A collection of package sources, or if is + /// and the package sources could not be computed without switching to the main thread. + /// + ValueTask?> TryGetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken); event EventHandler PackageSourcesChanged; } From 34e4c3d1fe2c1c44ee93c71f70f2f13acb7fabe2 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 29 Apr 2020 12:57:29 -0700 Subject: [PATCH 049/222] Use project.Name as the display name for Class View Fixes #43712 --- .../Library/ObjectBrowser/Extensions.cs | 24 ------------------- .../ObjectBrowser/Lists/ProjectListItem.cs | 2 +- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs index 6fac4efee5198..753d561be8bac 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs @@ -5,7 +5,6 @@ using System.Text; using Microsoft.CodeAnalysis; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; -using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.ObjectBrowser @@ -49,29 +48,6 @@ public static string GetTypeNavInfoNameOrEmpty(this ITypeSymbol typeSymbol) : string.Empty; } - public static string GetProjectDisplayName(this Project project) - { - if (project.Solution.Workspace is VisualStudioWorkspaceImpl workspace) - { - var hierarchy = workspace.GetHierarchy(project.Id); - if (hierarchy != null) - { - var solution = (IVsSolution3)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)); - if (solution != null) - { - if (ErrorHandler.Succeeded(solution.GetUniqueUINameOfProject(hierarchy, out var name)) && name != null) - { - return name; - } - } - } - - return project.Name; - } - - return project.Name; - } - public static bool IsVenus(this Project project) { if (!(project.Solution.Workspace is VisualStudioWorkspaceImpl workspace)) diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs index aa0d5a5fe25d9..ecda675720498 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs @@ -15,7 +15,7 @@ internal class ProjectListItem : ObjectListItem public ProjectListItem(Project project) : base(project.Id, GetProjectGlyph(project)) { - _displayText = project.GetProjectDisplayName(); + _displayText = project.Name; } private static StandardGlyphGroup GetProjectGlyph(Project project) From d079234f37886f5de96d2f57140870da4c978c8c Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Thu, 30 Apr 2020 16:10:55 -0700 Subject: [PATCH 050/222] exclude csc.exe from optprof profling --- eng/config/OptProf.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eng/config/OptProf.json b/eng/config/OptProf.json index c7c45bfa4dcbf..9e96917507cb8 100644 --- a/eng/config/OptProf.json +++ b/eng/config/OptProf.json @@ -602,10 +602,6 @@ "filename": "/Contents/MSBuild/Current/Bin/Roslyn/System.Collections.Immutable.dll", "testCases":[ "ManagedLangs.OptProfTests.DDRIT_RPS_ManagedLangs" ] }, - { - "filename": "/Contents/MSBuild/Current/Bin/Roslyn/csc.exe", - "testCases":[ "ManagedLangs.OptProfTests.DDRIT_RPS_ManagedLangs" ] - }, { "filename": "/Contents/MSBuild/Current/Bin/Roslyn/VBCSCompiler.exe", "testCases":[ "ManagedLangs.OptProfTests.DDRIT_RPS_ManagedLangs" ] From f139652ff801160f6de8570bada25b1dab68e95e Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 30 Apr 2020 17:46:57 -0700 Subject: [PATCH 051/222] Only use Project.Name in class view when the name is unambiguous within the Roslyn solution --- .../Library/ObjectBrowser/Extensions.cs | 46 +++++++++++++++++++ .../ObjectBrowser/Lists/ProjectListItem.cs | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs index 753d561be8bac..1e2de6a05079c 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs @@ -5,6 +5,7 @@ using System.Text; using Microsoft.CodeAnalysis; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.ObjectBrowser @@ -48,6 +49,51 @@ public static string GetTypeNavInfoNameOrEmpty(this ITypeSymbol typeSymbol) : string.Empty; } + public static string GetProjectDisplayName(this Project project) + { + // If the project name is unambiguous within the solution, use that name. Otherwise, use the unique name + // provided by IVsSolution3.GetUniqueUINameOfProject. This covers all cases except for a single solution + // with two or more multi-targeted projects with the same name and same targets. + // + // https://github.com/dotnet/roslyn/pull/43800 + // http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/949113 + + if (IsUnambiguousProjectNameInSolution(project)) + { + return project.Name; + } + else if (project.Solution.Workspace is VisualStudioWorkspaceImpl workspace + && workspace.GetHierarchy(project.Id) is { } hierarchy + && (IVsSolution3)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)) is { } solution) + { + if (ErrorHandler.Succeeded(solution.GetUniqueUINameOfProject(hierarchy, out var name)) && name != null) + { + return name; + } + } + + return project.Name; + + // Local functions + static bool IsUnambiguousProjectNameInSolution(Project project) + { + foreach (var other in project.Solution.Projects) + { + if (other.Id == project.Id) + continue; + + if (other.Name == project.Name) + { + // Another project with the same name was found in the solution. This project name is _not_ + // unambiguous. + return false; + } + } + + return true; + } + } + public static bool IsVenus(this Project project) { if (!(project.Solution.Workspace is VisualStudioWorkspaceImpl workspace)) diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs index ecda675720498..aa0d5a5fe25d9 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Lists/ProjectListItem.cs @@ -15,7 +15,7 @@ internal class ProjectListItem : ObjectListItem public ProjectListItem(Project project) : base(project.Id, GetProjectGlyph(project)) { - _displayText = project.Name; + _displayText = project.GetProjectDisplayName(); } private static StandardGlyphGroup GetProjectGlyph(Project project) From 58b3b5dfa6d01e94bdc0ce5c703b715ceb77d128 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 30 Apr 2020 21:35:06 -0700 Subject: [PATCH 052/222] Update PackageInstallerServiceFactory to handle workspace changes --- .../PackageInstallerServiceFactory.cs | 83 ++++++++++++++----- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index a4a9533d1ae84..faaa9c34f2f60 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -104,21 +104,39 @@ public PackageInstallerService( return packageSources; } - lock (_gate) + if (_packageSourcesAsync is null) { - if (_packageSourcesAsync is null) + lock (_gate) { - _packageSourcesAsync = ThreadingContext.JoinableTaskFactory.RunAsync(() => GetPackageSourcesImplAsync()); + if (_packageSourcesAsync is null) + { + _packageSourcesAsync = ThreadingContext.JoinableTaskFactory.RunAsync(() => GetPackageSourcesImplAsync()); + } } } if (allowSwitchToMainThread) { - using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); - packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); + try + { + using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); + packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); + } + catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested) + { + // The operation did not complete successfully due to a change in the workspace. Return but do not + // cache this result. + return null; + } } else if (_packageSourcesAsync.IsCompleted) { + if (_packageSourcesAsync.Task.Status != TaskStatus.RanToCompletion) + { + // The operation did not complete successfully + return null; + } + packageSources = _packageSourcesAsync.GetAwaiter().GetResult(); } else @@ -140,23 +158,50 @@ public PackageInstallerService( private async Task> GetPackageSourcesImplAsync() { - await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(_tokenSource.Token); - - try + // Automatically retry the operation if it gets cancelled due to a change in the workspace. + while (true) { - return _packageSourceProvider.Value.GetSources(includeUnOfficial: true, includeDisabled: false) - .SelectAsArray(r => new PackageSource(r.Key, r.Value)); - } - catch (Exception ex) when (ex is InvalidDataException || ex is InvalidOperationException) - { - // These exceptions can happen when the nuget.config file is broken. - return ImmutableArray.Empty; + var cancellationToken = _tokenSource.Token; + try + { + var result = await GetPackageSourcesImplAsync(cancellationToken).ConfigureAwait(false); + if (result.IsEmpty && cancellationToken.IsCancellationRequested) + { + // The failure may have been caused by a workspace change; try again after a short delay + await Task.Delay(TimeSpan.FromMilliseconds(250)).ConfigureAwait(false); + continue; + } + + return result; + } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + // The failure may have been caused by a workspace change; try again after a short delay + await Task.Delay(TimeSpan.FromMilliseconds(250)).ConfigureAwait(false); + } } - catch (ArgumentException ae) when (FatalError.ReportWithoutCrash(ae)) + + // Local function + async Task> GetPackageSourcesImplAsync(CancellationToken cancellationToken) { - // This exception can happen when the nuget.config file is broken, e.g. invalid credentials. - // https://github.com/dotnet/roslyn/issues/40857 - return ImmutableArray.Empty; + await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); + + try + { + return _packageSourceProvider.Value.GetSources(includeUnOfficial: true, includeDisabled: false) + .SelectAsArray(r => new PackageSource(r.Key, r.Value)); + } + catch (Exception ex) when (ex is InvalidDataException || ex is InvalidOperationException) + { + // These exceptions can happen when the nuget.config file is broken. + return ImmutableArray.Empty; + } + catch (ArgumentException ae) when (FatalError.ReportWithoutCrash(ae)) + { + // This exception can happen when the nuget.config file is broken, e.g. invalid credentials. + // https://github.com/dotnet/roslyn/issues/40857 + return ImmutableArray.Empty; + } } } From f165e5226f536c8d04c91097551190b02ca6958b Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Fri, 1 May 2020 17:21:50 +0300 Subject: [PATCH 053/222] WIP: Code fix for CS0109 --- .../Diagnostics/HideBase/HideBaseTests.cs | 95 +++++++++++++++++++ ...eCodeFixProvider.RemoveNewKeywordAction.cs | 69 ++++++++++++++ .../HideBase/HideBaseCodeFixProvider.cs | 8 +- src/Test/Utilities/Portable/Traits/Traits.cs | 1 + 4 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs index f12f54725c676..72c60aac1b51d 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs @@ -178,5 +178,100 @@ class App : Application { /* start */ public /* middle */ new readonly /* end */ int Test; }"); + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + public async Task TestRemoveNewFromProperty() + { + await TestInRegularAndScriptAsync( + @"class App +{ + [|public static new App Current|] { get; set; } +}", + @"class App +{ + public static App Current { get; set; } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + public async Task TestRemoveNewFromMethod() + { + await TestInRegularAndScriptAsync( +@"class App +{ + [|public static new void Method() + { + }|] +}", +@"class App +{ + public static void Method() + { + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + public async Task TestRemoveNewFromField() + { + await TestInRegularAndScriptAsync( +@"class App +{ + [|public new int Test;|] +}", +@"class App +{ + public int Test; +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + public async Task TestRemoveNewFromConstant() + { + await TestInRegularAndScriptAsync( +@"class App +{ + [|public const new int Test = 1;|] +}", +@"class App +{ + public const int Test = 1; +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + public async Task TestRemoveNewFromConstantInternalFields() + { + await TestInRegularAndScriptAsync( +@"class A { [|internal const new int i = 1;|] }", +@"class A { internal const int i = 1; }"); + } + + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + [InlineData( + "/* start */ public /* middle */ new /* end */ int Test;", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */ new /* end */ int Test;", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */new /* end */ int Test;", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "new /* end */ int Test;", + "/* end */ int Test;")] + [InlineData( + "/* start */ new /* end */ int Test;", + "/* start */ /* end */ int Test;")] + public async Task TestRemoveNewFromModifiersWithTrivia(string original, string expected) => + await TestInRegularAndScript1Async( +$@"class App +{{ + [|{original}|] +}}", +$@"class App +{{ + {expected} +}}"); } } diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs new file mode 100644 index 0000000000000..1ab0ff81303a5 --- /dev/null +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -0,0 +1,69 @@ +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.LanguageServices; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase +{ + internal partial class HideBaseCodeFixProvider + { + private class RemoveNewKeywordAction : CodeActions.CodeAction + { + private readonly Document _document; + private readonly MemberDeclarationSyntax _node; + + //TODO: use resources + public override string Title => "Remove 'new' keyword"; + + public RemoveNewKeywordAction(Document document, MemberDeclarationSyntax node) + { + _document = document; + _node = node; + } + + protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) + { + var syntaxFacts = CSharpSyntaxFacts.Instance; + var modifiers = syntaxFacts.GetModifiers(_node); + + var newModifiers = modifiers; + int i; + SyntaxToken modifier = default; + for (i = 0; i < modifiers.Count; i++) + { + modifier = modifiers[i]; + if (modifier.Kind() == SyntaxKind.NewKeyword) + { + break; + } + } + Debug.Assert(modifier != default, $"'new' keyword was not found, but diagnostic was triggered"); + + newModifiers = modifiers.RemoveAt(i); + + var trivia = modifier.TrailingTrivia; + if (trivia.Any()) + { + var previousModifier = newModifiers[i - 1]; + + if (trivia[0].IsWhitespace() && previousModifier.TrailingTrivia.Last().IsWhitespace()) + { + trivia = trivia.RemoveAt(0); + } + + var previousModifierWithMovedTrivia = previousModifier.WithAppendedTrailingTrivia(trivia); + newModifiers = newModifiers.Replace(previousModifier, previousModifierWithMovedTrivia); + } + + var newNode = syntaxFacts.WithModifiers(_node, newModifiers); + var root = await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var newRoot = root.ReplaceNode(_node, newNode); + + return _document.WithSyntaxRoot(newRoot); + } + } + } +} diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs index 5e309618f1183..ecd6f857e7271 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs @@ -17,6 +17,7 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase internal partial class HideBaseCodeFixProvider : CodeFixProvider { internal const string CS0108 = nameof(CS0108); // 'SomeClass.SomeMember' hides inherited member 'SomeClass.SomeMember'. Use the new keyword if hiding was intended. + internal const string CS0109 = nameof(CS0109); // The member 'SomeClass.SomeMember' does not hide an accessible member. The new keyword is not required. [ImportingConstructor] [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] @@ -24,7 +25,7 @@ public HideBaseCodeFixProvider() { } - public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0108); + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0108, CS0109); public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; @@ -54,7 +55,10 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) return; } - context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics); + if (diagnostic.Id == CS0108) + context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics); + else if (diagnostic.Id == CS0109) + context.RegisterCodeFix(new RemoveNewKeywordAction(context.Document, originalNode), context.Diagnostics); } } } diff --git a/src/Test/Utilities/Portable/Traits/Traits.cs b/src/Test/Utilities/Portable/Traits/Traits.cs index 53ea718e847a7..af35a8bd285d9 100644 --- a/src/Test/Utilities/Portable/Traits/Traits.cs +++ b/src/Test/Utilities/Portable/Traits/Traits.cs @@ -46,6 +46,7 @@ public static class Features public const string CodeActionsAddImport = "CodeActions.AddImport"; public const string CodeActionsAddMissingReference = "CodeActions.AddMissingReference"; public const string CodeActionsAddNew = "CodeActions.AddNew"; + public const string CodeActionsRemoveNew = "CodeActions.RemoveNew"; public const string CodeActionsAddObsoleteAttribute = "CodeActions.AddObsoleteAttribute"; public const string CodeActionsAddOverload = "CodeActions.AddOverloads"; public const string CodeActionsAddParameter = "CodeActions.AddParameter"; From a1cb5f3a5f84d3887e79371e16fcfe450bd02ddc Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 16:48:50 +0300 Subject: [PATCH 054/222] Handle trivia --- .../Diagnostics/HideBase/HideBaseTests.cs | 23 +++++++ ...eCodeFixProvider.RemoveNewKeywordAction.cs | 61 +++++++++++-------- .../Extensions/SyntaxTriviaListExtensions.cs | 14 +++++ 3 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs index 72c60aac1b51d..d889ccd8ded3a 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs @@ -239,6 +239,20 @@ await TestInRegularAndScriptAsync( }"); } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] + public async Task TestRemoveNewFirstModifier() + { + await TestInRegularAndScriptAsync( + @"class App +{ + [|new App Current|] { get; set; } +}", + @"class App +{ + App Current { get; set; } +}"); + } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] public async Task TestRemoveNewFromConstantInternalFields() { @@ -257,9 +271,18 @@ await TestInRegularAndScriptAsync( [InlineData( "/* start */ public /* middle */new /* end */ int Test;", "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */ new/* end */ int Test;", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */new/* end */ int Test;", + "/* start */ public /* middle *//* end */ int Test;")] [InlineData( "new /* end */ int Test;", "/* end */ int Test;")] + [InlineData( + "new int Test;", + "int Test;")] [InlineData( "/* start */ new /* end */ int Test;", "/* start */ /* end */ int Test;")] diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 1ab0ff81303a5..469d7560189e4 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -1,10 +1,9 @@ using System.Diagnostics; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.LanguageServices; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase { @@ -13,12 +12,12 @@ internal partial class HideBaseCodeFixProvider private class RemoveNewKeywordAction : CodeActions.CodeAction { private readonly Document _document; - private readonly MemberDeclarationSyntax _node; + private readonly SyntaxNode _node; //TODO: use resources public override string Title => "Remove 'new' keyword"; - public RemoveNewKeywordAction(Document document, MemberDeclarationSyntax node) + public RemoveNewKeywordAction(Document document, SyntaxNode node) { _document = document; _node = node; @@ -27,42 +26,52 @@ public RemoveNewKeywordAction(Document document, MemberDeclarationSyntax node) protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) { var syntaxFacts = CSharpSyntaxFacts.Instance; - var modifiers = syntaxFacts.GetModifiers(_node); - var newModifiers = modifiers; - int i; - SyntaxToken modifier = default; - for (i = 0; i < modifiers.Count; i++) - { - modifier = modifiers[i]; - if (modifier.Kind() == SyntaxKind.NewKeyword) - { - break; - } - } - Debug.Assert(modifier != default, $"'new' keyword was not found, but diagnostic was triggered"); + var newModifier = GetNewModifier(_node); + Debug.Assert(newModifier != default, $"'new' keyword was not found, but diagnostic was triggered"); - newModifiers = modifiers.RemoveAt(i); + var newNode = _node; - var trivia = modifier.TrailingTrivia; - if (trivia.Any()) + if (newModifier.HasTrailingTrivia || newModifier.HasLeadingTrivia) { - var previousModifier = newModifiers[i - 1]; + var newModifierTrivia = newModifier.GetAllTrivia().ToSyntaxTriviaList(); + var previousToken = newModifier.GetPreviousToken(); + var nextToken = newModifier.GetNextToken(); + + var sourceText = _document.GetTextSynchronously(cancellationToken); + var isFirstTokenOnLine = newModifier.IsFirstTokenOnLine(sourceText); - if (trivia[0].IsWhitespace() && previousModifier.TrailingTrivia.Last().IsWhitespace()) + var newTrivia = new SyntaxTriviaList(); + if (!isFirstTokenOnLine) { - trivia = trivia.RemoveAt(0); + newTrivia = newTrivia.AddRange(previousToken.TrailingTrivia); } + newTrivia = newTrivia + .AddRange(newModifierTrivia) + .AddRange(nextToken.LeadingTrivia) + .CollapseSequentialWhitespaces(); - var previousModifierWithMovedTrivia = previousModifier.WithAppendedTrailingTrivia(trivia); - newModifiers = newModifiers.Replace(previousModifier, previousModifierWithMovedTrivia); + if (isFirstTokenOnLine) + { + var nextTokenWithMovedTrivia = nextToken.WithLeadingTrivia(newTrivia); + newNode = newNode.ReplaceToken(nextToken, nextTokenWithMovedTrivia); + } + else + { + var previousTokenWithMovedTrivia = previousToken.WithTrailingTrivia(newTrivia); + newNode = newNode.ReplaceToken(previousToken, previousTokenWithMovedTrivia); + } } - var newNode = syntaxFacts.WithModifiers(_node, newModifiers); + newNode = newNode.ReplaceToken(GetNewModifier(newNode), SyntaxFactory.Token(SyntaxKind.None)); + var root = await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = root.ReplaceNode(_node, newNode); return _document.WithSyntaxRoot(newRoot); + + SyntaxToken GetNewModifier(SyntaxNode node) => + syntaxFacts.GetModifierTokens(node).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs index 67a73fe7a6527..c29983486fc77 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs @@ -90,5 +90,19 @@ public static IEnumerable TakeRange(this SyntaxTriviaList triviaLi yield return triviaList[start++]; } } + + public static SyntaxTriviaList CollapseSequentialWhitespaces(this SyntaxTriviaList triviaList) + { + var result = new SyntaxTriviaList(); + var previous = default(SyntaxTrivia); + foreach (var current in triviaList) + { + if (!(previous.IsWhitespace() && current.IsWhitespace())) + result = result.Add(current); + previous = current; + } + + return result; + } } } From e7317f4278858cf30dc8148de9b83975e0a221d4 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 17:14:16 +0300 Subject: [PATCH 055/222] Add resources --- src/Features/CSharp/Portable/CSharpFeaturesResources.resx | 3 +++ .../HideBaseCodeFixProvider.RemoveNewKeywordAction.cs | 3 +-- .../CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf | 5 +++++ .../CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf | 5 +++++ 15 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx index 7d3bc722a0dc6..deb4205ab95fd 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx @@ -445,6 +445,9 @@ Hide base member + + Remove 'new' keyword + Properties diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 469d7560189e4..5638894a3f807 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -14,8 +14,7 @@ private class RemoveNewKeywordAction : CodeActions.CodeAction private readonly Document _document; private readonly SyntaxNode _node; - //TODO: use resources - public override string Title => "Remove 'new' keyword"; + public override string Title => CSharpFeaturesResources.Remove_new_keyword; public RemoveNewKeywordAction(Document document, SyntaxNode node) { diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf index 126e45e237bef..2085de745534a 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf @@ -147,6 +147,11 @@ Nastavit jako ref struct {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Odebrat nepotřebná přetypování diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf index 572607c0417c3..310eabdd1ceeb 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf @@ -147,6 +147,11 @@ "ref struct" erstellen {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Nicht erforderliche Umwandlungen entfernen diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf index 47f14c8347ff8..1ba6ae5e90b74 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf @@ -147,6 +147,11 @@ Convertir "ref struct" {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Quitar conversiones innecesarias diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf index 9ba557071faed..737b0261e6d5a 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf @@ -147,6 +147,11 @@ Définir 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Supprimer les casts inutiles diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf index 7460177d8f8b0..dd7a44a9de66e 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf @@ -147,6 +147,11 @@ Imposta come 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Rimuovi i cast non necessari diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf index 7dca0f08d4e22..8bba136c9b93d 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf @@ -147,6 +147,11 @@ 'ref struct' を作成します {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts 不要なキャストを削除する diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf index a0e2f7938f0e3..897a7388fea93 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf @@ -147,6 +147,11 @@ 'ref struct'로 지정 {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts 불필요한 캐스트 제거 diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf index 84a1f07ee04f3..4227b0512e746 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf @@ -147,6 +147,11 @@ Ustaw jako „ref struct” {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Usuń niepotrzebne rzutowania diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf index 2e162cfdd40c7..bc8c8fa5a7ae8 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf @@ -147,6 +147,11 @@ Alterar 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Remover conversões desnecessárias diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf index 6dbc3afc2a72c..eb464efa68578 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf @@ -147,6 +147,11 @@ Сделать ref struct {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Удалить ненужные приведения diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf index b97caffe1e911..eeff0431185e6 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf @@ -147,6 +147,11 @@ 'ref struct' yap {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts Gereksiz atamaları kaldır diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf index 85ce1696e6e9b..98c5cc7349ae2 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf @@ -147,6 +147,11 @@ 生成 "ref struct" {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts 删除不必要的转换 diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf index 4cff5b4555a1a..6ffdfd391b7af 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf @@ -147,6 +147,11 @@ 設為 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. + + Remove 'new' keyword + Remove 'new' keyword + + Remove unnecessary casts 移除不必要的 Cast From 23388157a8a9ad319abed4355366c169821c620f Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 17:14:28 +0300 Subject: [PATCH 056/222] Add missing file header --- .../HideBaseCodeFixProvider.RemoveNewKeywordAction.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 5638894a3f807..926ba63226888 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System.Diagnostics; using System.Linq; using System.Threading; From 235709294d989436d019c4e44d57654b6eb6e332 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 17:14:44 +0300 Subject: [PATCH 057/222] Renaming: CollapseSequentialWhitespaces -> CollapseSequentialWhitespaceTrivia --- .../HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs | 2 +- .../Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 926ba63226888..60c327abcb3e4 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -52,7 +52,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke newTrivia = newTrivia .AddRange(newModifierTrivia) .AddRange(nextToken.LeadingTrivia) - .CollapseSequentialWhitespaces(); + .CollapseSequentialWhitespaceTrivia(); if (isFirstTokenOnLine) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs index c29983486fc77..c6e338892393d 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs @@ -91,7 +91,7 @@ public static IEnumerable TakeRange(this SyntaxTriviaList triviaLi } } - public static SyntaxTriviaList CollapseSequentialWhitespaces(this SyntaxTriviaList triviaList) + public static SyntaxTriviaList CollapseSequentialWhitespaceTrivia(this SyntaxTriviaList triviaList) { var result = new SyntaxTriviaList(); var previous = default(SyntaxTrivia); From 0e1e241864cea8916965d38bfcae246e648042d7 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 21:08:52 +0300 Subject: [PATCH 058/222] Minor --- .../HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 60c327abcb3e4..7c71d231d704d 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -46,9 +46,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke var newTrivia = new SyntaxTriviaList(); if (!isFirstTokenOnLine) - { newTrivia = newTrivia.AddRange(previousToken.TrailingTrivia); - } newTrivia = newTrivia .AddRange(newModifierTrivia) .AddRange(nextToken.LeadingTrivia) From b4fa7200451d874cd3d9697e3b4ae8e2e6a6803a Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 21:21:29 +0300 Subject: [PATCH 059/222] Add comment for CollapseSequentialWhitespaceTrivia --- .../Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs index c6e338892393d..a5ad42c097951 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs @@ -91,6 +91,11 @@ public static IEnumerable TakeRange(this SyntaxTriviaList triviaLi } } + /// + /// Removes multiple with kind + /// arranged in a sequence from the + /// preserving only the first one: [space1][space2][space3] -> [space1]. + /// public static SyntaxTriviaList CollapseSequentialWhitespaceTrivia(this SyntaxTriviaList triviaList) { var result = new SyntaxTriviaList(); From b983adee83b580522a6f1598af8319f660427039 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 21:29:50 +0300 Subject: [PATCH 060/222] Indentation in tests --- .../CSharpTest/Diagnostics/HideBase/HideBaseTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs index d889ccd8ded3a..9bcb4823025fe 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs @@ -183,11 +183,11 @@ class App : Application public async Task TestRemoveNewFromProperty() { await TestInRegularAndScriptAsync( - @"class App +@"class App { [|public static new App Current|] { get; set; } }", - @"class App +@"class App { public static App Current { get; set; } }"); @@ -243,11 +243,11 @@ await TestInRegularAndScriptAsync( public async Task TestRemoveNewFirstModifier() { await TestInRegularAndScriptAsync( - @"class App +@"class App { [|new App Current|] { get; set; } }", - @"class App +@"class App { App Current { get; set; } }"); From 489a63541175b11ae5547e3230b2c8717b7cbd97 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 21:30:45 +0300 Subject: [PATCH 061/222] Update CollapseSequentialWhitespaceTrivia comment --- .../Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs index a5ad42c097951..12419635ac09b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs @@ -92,8 +92,8 @@ public static IEnumerable TakeRange(this SyntaxTriviaList triviaLi } /// - /// Removes multiple with kind - /// arranged in a sequence from the + /// Returns modified with removed multiple + /// with kind arranged in a sequence /// preserving only the first one: [space1][space2][space3] -> [space1]. /// public static SyntaxTriviaList CollapseSequentialWhitespaceTrivia(this SyntaxTriviaList triviaList) From c52f0192225693ef143fbf9ebc53835857a197b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sharma?= Date: Sat, 2 May 2020 11:33:11 -0700 Subject: [PATCH 062/222] Fix link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 274df2d101eef..b7b4a37824d62 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Want to start developing in C# and Visual Basic? Download [Visual Studio 2019](h also [prebuilt Azure VM images](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/category/compute?search=visual%20studio%202019) available with Visual Studio 2019 already installed. -To install the latest release without Visual Studio, download the [].NET SDK nightlies](https://github.com/dotnet/installer/blob/master/README.md#installers-and-binaries). +To install the latest release without Visual Studio, download the [.NET SDK nightlies](https://github.com/dotnet/installer/blob/master/README.md#installers-and-binaries). See [what's new with the C# and VB compilers](https://github.com/dotnet/roslyn/wiki/Changelog-for-C%23-and-VB-compilers). From 794cb236ea147ab24e1b3d6bf003072a8b7e654c Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 22:15:38 +0300 Subject: [PATCH 063/222] Update span in tests --- .../Diagnostics/HideBase/HideBaseTests.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs index 9bcb4823025fe..dfced5db44b71 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs @@ -185,7 +185,7 @@ public async Task TestRemoveNewFromProperty() await TestInRegularAndScriptAsync( @"class App { - [|public static new App Current|] { get; set; } + public static new App [|Current|] { get; set; } }", @"class App { @@ -199,9 +199,9 @@ public async Task TestRemoveNewFromMethod() await TestInRegularAndScriptAsync( @"class App { - [|public static new void Method() + public static new void [|Method()|] { - }|] + } }", @"class App { @@ -217,7 +217,7 @@ public async Task TestRemoveNewFromField() await TestInRegularAndScriptAsync( @"class App { - [|public new int Test;|] + public new int [|Test|]; }", @"class App { @@ -231,7 +231,7 @@ public async Task TestRemoveNewFromConstant() await TestInRegularAndScriptAsync( @"class App { - [|public const new int Test = 1;|] + public const new int [|Test|] = 1; }", @"class App { @@ -245,7 +245,7 @@ public async Task TestRemoveNewFirstModifier() await TestInRegularAndScriptAsync( @"class App { - [|new App Current|] { get; set; } + new App [|Current|] { get; set; } }", @"class App { @@ -257,40 +257,40 @@ await TestInRegularAndScriptAsync( public async Task TestRemoveNewFromConstantInternalFields() { await TestInRegularAndScriptAsync( -@"class A { [|internal const new int i = 1;|] }", -@"class A { internal const int i = 1; }"); +@"class A { internal const new int [|i|] = 1; }", +@"class A { internal const int [|i|] = 1; }"); } [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] [InlineData( - "/* start */ public /* middle */ new /* end */ int Test;", + "/* start */ public /* middle */ new /* end */ int [|Test|];", "/* start */ public /* middle */ /* end */ int Test;")] [InlineData( - "/* start */ public /* middle */ new /* end */ int Test;", + "/* start */ public /* middle */ new /* end */ int [|Test|];", "/* start */ public /* middle */ /* end */ int Test;")] [InlineData( - "/* start */ public /* middle */new /* end */ int Test;", + "/* start */ public /* middle */new /* end */ int [|Test|];", "/* start */ public /* middle */ /* end */ int Test;")] [InlineData( - "/* start */ public /* middle */ new/* end */ int Test;", + "/* start */ public /* middle */ new/* end */ int [|Test|];", "/* start */ public /* middle */ /* end */ int Test;")] [InlineData( - "/* start */ public /* middle */new/* end */ int Test;", + "/* start */ public /* middle */new/* end */ int [|Test|];", "/* start */ public /* middle *//* end */ int Test;")] [InlineData( - "new /* end */ int Test;", + "new /* end */ int [|Test|];", "/* end */ int Test;")] [InlineData( - "new int Test;", + "new int [|Test|];", "int Test;")] [InlineData( - "/* start */ new /* end */ int Test;", - "/* start */ /* end */ int Test;")] + "/* start */ new /* end */ int [|Test|];", + "/* start */ /* end */ int [|Test|];")] public async Task TestRemoveNewFromModifiersWithTrivia(string original, string expected) => await TestInRegularAndScript1Async( $@"class App {{ - [|{original}|] + {original} }}", $@"class App {{ From b7723ce97a23063e553ad8e1ef5c7854ad47707c Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 22:40:39 +0300 Subject: [PATCH 064/222] Remove new keyword -> remove new modifier --- src/Features/CSharp/Portable/CSharpFeaturesResources.resx | 4 ++-- .../HideBaseCodeFixProvider.RemoveNewKeywordAction.cs | 6 +++--- .../Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs | 4 ++-- .../CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf | 6 +++--- .../CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf | 6 +++--- 16 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx index deb4205ab95fd..7d3ac77c6a2ed 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx @@ -445,8 +445,8 @@ Hide base member - - Remove 'new' keyword + + Remove 'new' modifier Properties diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 7c71d231d704d..65575b4b0c1bf 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -13,14 +13,14 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase { internal partial class HideBaseCodeFixProvider { - private class RemoveNewKeywordAction : CodeActions.CodeAction + private class RemoveNewModifierAction : CodeActions.CodeAction { private readonly Document _document; private readonly SyntaxNode _node; - public override string Title => CSharpFeaturesResources.Remove_new_keyword; + public override string Title => CSharpFeaturesResources.Remove_new_modifier; - public RemoveNewKeywordAction(Document document, SyntaxNode node) + public RemoveNewModifierAction(Document document, SyntaxNode node) { _document = document; _node = node; diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs index ecd6f857e7271..e027b9a8e8d5e 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -58,7 +58,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) if (diagnostic.Id == CS0108) context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics); else if (diagnostic.Id == CS0109) - context.RegisterCodeFix(new RemoveNewKeywordAction(context.Document, originalNode), context.Diagnostics); + context.RegisterCodeFix(new RemoveNewModifierAction(context.Document, originalNode), context.Diagnostics); } } } diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf index 2085de745534a..f6959d8c6f2b1 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf @@ -147,9 +147,9 @@ Nastavit jako ref struct {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf index 310eabdd1ceeb..2c3dfb4bf1bce 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf @@ -147,9 +147,9 @@ "ref struct" erstellen {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf index 1ba6ae5e90b74..c93bbfe4d7cc8 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf @@ -147,9 +147,9 @@ Convertir "ref struct" {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf index 737b0261e6d5a..e83ba5abaed1e 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf @@ -147,9 +147,9 @@ Définir 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf index dd7a44a9de66e..e005813854377 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf @@ -147,9 +147,9 @@ Imposta come 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf index 8bba136c9b93d..c145adda1086f 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf @@ -147,9 +147,9 @@ 'ref struct' を作成します {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf index 897a7388fea93..d31d16bea04f6 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf @@ -147,9 +147,9 @@ 'ref struct'로 지정 {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf index 4227b0512e746..1e0454fa86d4f 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf @@ -147,9 +147,9 @@ Ustaw jako „ref struct” {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf index bc8c8fa5a7ae8..9fe9a0131c988 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf @@ -147,9 +147,9 @@ Alterar 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf index eb464efa68578..378c6bb7b08c1 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf @@ -147,9 +147,9 @@ Сделать ref struct {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf index eeff0431185e6..64cd925c85dc9 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf @@ -147,9 +147,9 @@ 'ref struct' yap {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf index 98c5cc7349ae2..1b6286ade71e8 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf @@ -147,9 +147,9 @@ 生成 "ref struct" {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf index 6ffdfd391b7af..84707508ff290 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf @@ -147,9 +147,9 @@ 設為 'ref struct' {Locked="ref"}{Locked="struct"} "ref" and "struct" are C# keywords and should not be localized. - - Remove 'new' keyword - Remove 'new' keyword + + Remove 'new' modifier + Remove 'new' modifier From 7f6c8cd9f140271a0f3eff27c99425a52c7bde18 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sat, 2 May 2020 22:42:41 +0300 Subject: [PATCH 065/222] GetTextAsync --- .../HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs index 65575b4b0c1bf..fb62c3cd2d6b3 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs @@ -41,7 +41,7 @@ protected override async Task GetChangedDocumentAsync(CancellationToke var previousToken = newModifier.GetPreviousToken(); var nextToken = newModifier.GetNextToken(); - var sourceText = _document.GetTextSynchronously(cancellationToken); + var sourceText = await _document.GetTextAsync(cancellationToken).ConfigureAwait(false); var isFirstTokenOnLine = newModifier.IsFirstTokenOnLine(sourceText); var newTrivia = new SyntaxTriviaList(); From afe9fcb50f76fc54962ffb76143e408e93461c85 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 10:27:26 +0300 Subject: [PATCH 066/222] Move code fix to a separate class --- .../PredefinedCodeFixProviderNames.cs | 1 + .../Diagnostics/HideBase/HideBaseTests.cs | 120 +----------- .../RemoveNewModifierCodeFixProviderTests.cs | 181 ++++++++++++++++++ ...eCodeFixProvider.RemoveNewKeywordAction.cs | 79 -------- .../HideBase/HideBaseCodeFixProvider.cs | 10 +- .../RemoveNewModifierCodeFixProvider.cs | 110 +++++++++++ src/Test/Utilities/Portable/Traits/Traits.cs | 2 +- 7 files changed, 297 insertions(+), 206 deletions(-) create mode 100644 src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs delete mode 100644 src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs create mode 100644 src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs diff --git a/src/Analyzers/Core/CodeFixes/PredefinedCodeFixProviderNames.cs b/src/Analyzers/Core/CodeFixes/PredefinedCodeFixProviderNames.cs index 21fc8fa64514c..673c42890d782 100644 --- a/src/Analyzers/Core/CodeFixes/PredefinedCodeFixProviderNames.cs +++ b/src/Analyzers/Core/CodeFixes/PredefinedCodeFixProviderNames.cs @@ -63,6 +63,7 @@ internal static class PredefinedCodeFixProviderNames public const string Suppression = nameof(Suppression); public const string AddOverloads = nameof(AddOverloads); public const string AddNew = nameof(AddNew); + public const string RemoveNew = nameof(RemoveNew); public const string UnsealClass = nameof(UnsealClass); public const string UseImplicitType = nameof(UseImplicitType); public const string UseExplicitType = nameof(UseExplicitType); diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs index dfced5db44b71..c3151d8f12e91 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -178,123 +178,5 @@ class App : Application { /* start */ public /* middle */ new readonly /* end */ int Test; }"); - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - public async Task TestRemoveNewFromProperty() - { - await TestInRegularAndScriptAsync( -@"class App -{ - public static new App [|Current|] { get; set; } -}", -@"class App -{ - public static App Current { get; set; } -}"); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - public async Task TestRemoveNewFromMethod() - { - await TestInRegularAndScriptAsync( -@"class App -{ - public static new void [|Method()|] - { - } -}", -@"class App -{ - public static void Method() - { - } -}"); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - public async Task TestRemoveNewFromField() - { - await TestInRegularAndScriptAsync( -@"class App -{ - public new int [|Test|]; -}", -@"class App -{ - public int Test; -}"); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - public async Task TestRemoveNewFromConstant() - { - await TestInRegularAndScriptAsync( -@"class App -{ - public const new int [|Test|] = 1; -}", -@"class App -{ - public const int Test = 1; -}"); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - public async Task TestRemoveNewFirstModifier() - { - await TestInRegularAndScriptAsync( -@"class App -{ - new App [|Current|] { get; set; } -}", -@"class App -{ - App Current { get; set; } -}"); - } - - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - public async Task TestRemoveNewFromConstantInternalFields() - { - await TestInRegularAndScriptAsync( -@"class A { internal const new int [|i|] = 1; }", -@"class A { internal const int [|i|] = 1; }"); - } - - [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNew)] - [InlineData( - "/* start */ public /* middle */ new /* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] - [InlineData( - "/* start */ public /* middle */ new /* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] - [InlineData( - "/* start */ public /* middle */new /* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] - [InlineData( - "/* start */ public /* middle */ new/* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] - [InlineData( - "/* start */ public /* middle */new/* end */ int [|Test|];", - "/* start */ public /* middle *//* end */ int Test;")] - [InlineData( - "new /* end */ int [|Test|];", - "/* end */ int Test;")] - [InlineData( - "new int [|Test|];", - "int Test;")] - [InlineData( - "/* start */ new /* end */ int [|Test|];", - "/* start */ /* end */ int [|Test|];")] - public async Task TestRemoveNewFromModifiersWithTrivia(string original, string expected) => - await TestInRegularAndScript1Async( -$@"class App -{{ - {original} -}}", -$@"class App -{{ - {expected} -}}"); } } diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs new file mode 100644 index 0000000000000..2b7e353ebd118 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs @@ -0,0 +1,181 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.CodeFixes.RemoveNewModifier; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.RemoveNewModifier +{ + [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNewModifier)] + public class RemoveNewModifierCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + { + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => + (null, new RemoveNewModifierCodeFixProvider()); + + [Fact] + public async Task TestRemoveNewFromProperty() + { + await TestInRegularAndScriptAsync( + @"class App +{ + public static new App [|Current|] { get; set; } +}", + @"class App +{ + public static App Current { get; set; } +}"); + } + + [Fact] + public async Task TestRemoveNewFromMethod() + { + await TestInRegularAndScriptAsync( + @"class App +{ + public static new void [|Method()|] + { + } +}", + @"class App +{ + public static void Method() + { + } +}"); + } + + [Fact] + public async Task TestRemoveNewFromField() + { + await TestInRegularAndScriptAsync( + @"class App +{ + public new int [|Test|]; +}", + @"class App +{ + public int Test; +}"); + } + + [Fact] + public async Task TestRemoveNewFromConstant() + { + await TestInRegularAndScriptAsync( + @"class App +{ + public const new int [|Test|] = 1; +}", + @"class App +{ + public const int Test = 1; +}"); + } + + [Fact] + public async Task TestRemoveNewFirstModifier() + { + await TestInRegularAndScriptAsync( + @"class App +{ + new App [|Current|] { get; set; } +}", + @"class App +{ + App Current { get; set; } +}"); + } + + [Fact] + public async Task TestRemoveNewFromConstantInternalFields() + { + await TestInRegularAndScriptAsync( + @"class A { internal const new int [|i|] = 1; }", + @"class A { internal const int [|i|] = 1; }"); + } + + [Fact] + public async Task TestRemoveNewWithNoTrivia() + { + await TestInRegularAndScriptAsync( + @"class C +{ +new(int a, int b) [|x|]; +}", + @"class C +{ +(int a, int b) x; +}"); + } + + [Theory] + [InlineData( + "public new event Action [|E|];", + "public event Action E;")] + [InlineData( + "public new int [|this[int p]|] => p;", + "public int this[int p] => p;")] + [InlineData( + "new class [|Test|] { }", + "class Test { }")] + [InlineData( + "new struct [|Test|] { }", + "struct Test { }")] + [InlineData( + "new interface [|Test|] { }", + "interface Test { }")] + public async Task Test(string original, string expected) + { + await TestInRegularAndScriptAsync( + $@"class App +{{ + {original} +}}", + $@"class App +{{ + {expected} +}}"); + } + + [Theory] + [InlineData( + "/* start */ public /* middle */ new /* end */ int [|Test|];", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */ new /* end */ int [|Test|];", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */new /* end */ int [|Test|];", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */ new/* end */ int [|Test|];", + "/* start */ public /* middle */ /* end */ int Test;")] + [InlineData( + "/* start */ public /* middle */new/* end */ int [|Test|];", + "/* start */ public /* middle *//* end */ int Test;")] + [InlineData( + "new /* end */ int [|Test|];", + "/* end */ int Test;")] + [InlineData( + "new int [|Test|];", + "int Test;")] + [InlineData( + "/* start */ new /* end */ int [|Test|];", + "/* start */ /* end */ int [|Test|];")] + public async Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) => + await TestInRegularAndScript1Async( + $@"class App +{{ + {original} +}}", + $@"class App +{{ + {expected} +}}"); + } +} diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs deleted file mode 100644 index fb62c3cd2d6b3..0000000000000 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.RemoveNewKeywordAction.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CSharp.Extensions; -using Microsoft.CodeAnalysis.CSharp.LanguageServices; - -namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase -{ - internal partial class HideBaseCodeFixProvider - { - private class RemoveNewModifierAction : CodeActions.CodeAction - { - private readonly Document _document; - private readonly SyntaxNode _node; - - public override string Title => CSharpFeaturesResources.Remove_new_modifier; - - public RemoveNewModifierAction(Document document, SyntaxNode node) - { - _document = document; - _node = node; - } - - protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) - { - var syntaxFacts = CSharpSyntaxFacts.Instance; - - var newModifier = GetNewModifier(_node); - Debug.Assert(newModifier != default, $"'new' keyword was not found, but diagnostic was triggered"); - - var newNode = _node; - - if (newModifier.HasTrailingTrivia || newModifier.HasLeadingTrivia) - { - var newModifierTrivia = newModifier.GetAllTrivia().ToSyntaxTriviaList(); - var previousToken = newModifier.GetPreviousToken(); - var nextToken = newModifier.GetNextToken(); - - var sourceText = await _document.GetTextAsync(cancellationToken).ConfigureAwait(false); - var isFirstTokenOnLine = newModifier.IsFirstTokenOnLine(sourceText); - - var newTrivia = new SyntaxTriviaList(); - if (!isFirstTokenOnLine) - newTrivia = newTrivia.AddRange(previousToken.TrailingTrivia); - newTrivia = newTrivia - .AddRange(newModifierTrivia) - .AddRange(nextToken.LeadingTrivia) - .CollapseSequentialWhitespaceTrivia(); - - if (isFirstTokenOnLine) - { - var nextTokenWithMovedTrivia = nextToken.WithLeadingTrivia(newTrivia); - newNode = newNode.ReplaceToken(nextToken, nextTokenWithMovedTrivia); - } - else - { - var previousTokenWithMovedTrivia = previousToken.WithTrailingTrivia(newTrivia); - newNode = newNode.ReplaceToken(previousToken, previousTokenWithMovedTrivia); - } - } - - newNode = newNode.ReplaceToken(GetNewModifier(newNode), SyntaxFactory.Token(SyntaxKind.None)); - - var root = await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var newRoot = root.ReplaceNode(_node, newNode); - - return _document.WithSyntaxRoot(newRoot); - - SyntaxToken GetNewModifier(SyntaxNode node) => - syntaxFacts.GetModifierTokens(node).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); - } - } - } -} diff --git a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs index e027b9a8e8d5e..5e309618f1183 100644 --- a/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/HideBase/HideBaseCodeFixProvider.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -17,7 +17,6 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.HideBase internal partial class HideBaseCodeFixProvider : CodeFixProvider { internal const string CS0108 = nameof(CS0108); // 'SomeClass.SomeMember' hides inherited member 'SomeClass.SomeMember'. Use the new keyword if hiding was intended. - internal const string CS0109 = nameof(CS0109); // The member 'SomeClass.SomeMember' does not hide an accessible member. The new keyword is not required. [ImportingConstructor] [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] @@ -25,7 +24,7 @@ public HideBaseCodeFixProvider() { } - public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0108, CS0109); + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0108); public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; @@ -55,10 +54,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) return; } - if (diagnostic.Id == CS0108) - context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics); - else if (diagnostic.Id == CS0109) - context.RegisterCodeFix(new RemoveNewModifierAction(context.Document, originalNode), context.Diagnostics); + context.RegisterCodeFix(new AddNewKeywordAction(context.Document, originalNode), context.Diagnostics); } } } diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs new file mode 100644 index 0000000000000..7e38d28b28800 --- /dev/null +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Immutable; +using System.Composition; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Extensions; +using Microsoft.CodeAnalysis.CSharp.LanguageServices; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.RemoveNewModifier +{ + [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.AddNew), Shared] + internal class RemoveNewModifierCodeFixProvider : CodeFixProvider + { + internal const string CS0109 = nameof(CS0109); // The member 'SomeClass.SomeMember' does not hide an accessible member. The new keyword is not required. + + [ImportingConstructor] + [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] + public RemoveNewModifierCodeFixProvider() + { + } + + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0109); + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + + var diagnostic = context.Diagnostics.First(); + var diagnosticSpan = diagnostic.Location.SourceSpan; + + var token = root.FindToken(diagnosticSpan.Start); + var memberDeclarationSyntax = token.GetAncestor(); + + var newModifier = CSharpSyntaxFacts.Instance.GetModifiers(memberDeclarationSyntax) + .FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); + + if (newModifier != default) + { + context.RegisterCodeFix( + new MyCodeAction(ct => FixAsync(context.Document, memberDeclarationSyntax, ct)), + context.Diagnostics); + } + } + + private async Task FixAsync(Document document, MemberDeclarationSyntax node, CancellationToken cancellationToken) + { + var syntaxFacts = CSharpSyntaxFacts.Instance; + + var newModifier = GetNewModifier(node); + + var newNode = node; + + if (newModifier.HasTrailingTrivia || newModifier.HasLeadingTrivia) + { + var newModifierTrivia = newModifier.GetAllTrivia().ToSyntaxTriviaList(); + var previousToken = newModifier.GetPreviousToken(); + var nextToken = newModifier.GetNextToken(); + + var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); + var isFirstTokenOnLine = newModifier.IsFirstTokenOnLine(sourceText); + + var newTrivia = new SyntaxTriviaList(); + if (!isFirstTokenOnLine) + newTrivia = newTrivia.AddRange(previousToken.TrailingTrivia); + newTrivia = newTrivia + .AddRange(newModifierTrivia) + .AddRange(nextToken.LeadingTrivia) + .CollapseSequentialWhitespaceTrivia(); + + if (isFirstTokenOnLine) + { + var nextTokenWithMovedTrivia = nextToken.WithLeadingTrivia(newTrivia); + newNode = newNode.ReplaceToken(nextToken, nextTokenWithMovedTrivia); + } + else + { + var previousTokenWithMovedTrivia = previousToken.WithTrailingTrivia(newTrivia); + newNode = newNode.ReplaceToken(previousToken, previousTokenWithMovedTrivia); + } + } + + newNode = newNode.ReplaceToken(GetNewModifier(newNode), SyntaxFactory.Token(SyntaxKind.None)); + + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var newRoot = root.ReplaceNode(node, newNode); + + return document.WithSyntaxRoot(newRoot); + + SyntaxToken GetNewModifier(SyntaxNode fromNode) => + syntaxFacts.GetModifierTokens(fromNode).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); + } + + private class MyCodeAction : CustomCodeActions.DocumentChangeAction + { + public MyCodeAction(Func> createChangedDocument) + : base(CSharpFeaturesResources.Remove_new_modifier, + createChangedDocument, + CSharpFeaturesResources.Remove_new_modifier) + { + } + } + } +} diff --git a/src/Test/Utilities/Portable/Traits/Traits.cs b/src/Test/Utilities/Portable/Traits/Traits.cs index af35a8bd285d9..9b652ba8a6527 100644 --- a/src/Test/Utilities/Portable/Traits/Traits.cs +++ b/src/Test/Utilities/Portable/Traits/Traits.cs @@ -46,7 +46,7 @@ public static class Features public const string CodeActionsAddImport = "CodeActions.AddImport"; public const string CodeActionsAddMissingReference = "CodeActions.AddMissingReference"; public const string CodeActionsAddNew = "CodeActions.AddNew"; - public const string CodeActionsRemoveNew = "CodeActions.RemoveNew"; + public const string CodeActionsRemoveNewModifier = "CodeActions.RemoveNewModifier"; public const string CodeActionsAddObsoleteAttribute = "CodeActions.AddObsoleteAttribute"; public const string CodeActionsAddOverload = "CodeActions.AddOverloads"; public const string CodeActionsAddParameter = "CodeActions.AddParameter"; From 6e06b23c52bba863ded7f0e20860c2737249dcb8 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 10:43:07 +0300 Subject: [PATCH 067/222] Restructure tests --- .../RemoveNewModifierCodeFixProviderTests.cs | 148 ++++-------------- 1 file changed, 34 insertions(+), 114 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs index 2b7e353ebd118..b37827c17cd41 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs @@ -17,106 +17,22 @@ public class RemoveNewModifierCodeFixProviderTests : AbstractCSharpDiagnosticPro internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => (null, new RemoveNewModifierCodeFixProvider()); - [Fact] - public async Task TestRemoveNewFromProperty() - { - await TestInRegularAndScriptAsync( - @"class App -{ - public static new App [|Current|] { get; set; } -}", - @"class App -{ - public static App Current { get; set; } -}"); - } - - [Fact] - public async Task TestRemoveNewFromMethod() - { - await TestInRegularAndScriptAsync( - @"class App -{ - public static new void [|Method()|] - { - } -}", - @"class App -{ - public static void Method() - { - } -}"); - } - - [Fact] - public async Task TestRemoveNewFromField() - { - await TestInRegularAndScriptAsync( - @"class App -{ - public new int [|Test|]; -}", - @"class App -{ - public int Test; -}"); - } - - [Fact] - public async Task TestRemoveNewFromConstant() - { - await TestInRegularAndScriptAsync( - @"class App -{ - public const new int [|Test|] = 1; -}", - @"class App -{ - public const int Test = 1; -}"); - } - - [Fact] - public async Task TestRemoveNewFirstModifier() - { - await TestInRegularAndScriptAsync( - @"class App -{ - new App [|Current|] { get; set; } -}", - @"class App -{ - App Current { get; set; } -}"); - } - - [Fact] - public async Task TestRemoveNewFromConstantInternalFields() - { - await TestInRegularAndScriptAsync( - @"class A { internal const new int [|i|] = 1; }", - @"class A { internal const int [|i|] = 1; }"); - } - - [Fact] - public async Task TestRemoveNewWithNoTrivia() - { - await TestInRegularAndScriptAsync( - @"class C -{ -new(int a, int b) [|x|]; -}", - @"class C -{ -(int a, int b) x; -}"); - } - [Theory] [InlineData( - "public new event Action [|E|];", - "public event Action E;")] + @"public static new void [|Method()|] { }", + @"public static void [|Method()|] { }")] + [InlineData( + "public new int [|Test|];", + "public int [|Test|];")] + [InlineData( + "public new int [|Test|] { get; set; }", + "public int [|Test|] { get; set; }")] + [InlineData( + "public const new int [|test|] = 1;", + "public const int [|test|] = 1;")] + [InlineData( + "public new event Action [|Test|];", + "public event Action Test;")] [InlineData( "public new int [|this[int p]|] => p;", "public int this[int p] => p;")] @@ -129,18 +45,17 @@ await TestInRegularAndScriptAsync( [InlineData( "new interface [|Test|] { }", "interface Test { }")] - public async Task Test(string original, string expected) - { - await TestInRegularAndScriptAsync( - $@"class App -{{ - {original} -}}", - $@"class App -{{ - {expected} -}}"); - } + [InlineData( + "new delegate [|Test|]()", + "delegate Test()")] + [InlineData( + "new enum [|Test|] { }", + "enum Test { }")] + [InlineData( + "new(int a, int b) [|test|];", + "(int a, int b) test;")] + public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string original, string expected) => + TestRemoveNewModifierCodeFixAsync(original, expected); [Theory] [InlineData( @@ -167,15 +82,20 @@ await TestInRegularAndScriptAsync( [InlineData( "/* start */ new /* end */ int [|Test|];", "/* start */ /* end */ int [|Test|];")] - public async Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) => - await TestInRegularAndScript1Async( - $@"class App + public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) => + TestRemoveNewModifierCodeFixAsync(original, expected); + + private Task TestRemoveNewModifierCodeFixAsync(string original, string expected) + { + return TestInRegularAndScript1Async( +$@"class App {{ {original} }}", - $@"class App +$@"class App {{ {expected} }}"); + } } } From 0cb53321089ad7c2cd85ef8040e43ecc16aa8dab Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 10:49:13 +0300 Subject: [PATCH 068/222] RemoveNewModifierCodeFixProvider: fix provider name in attribute declaration --- .../RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index 7e38d28b28800..75b39c2896cb4 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -10,12 +10,11 @@ using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.LanguageServices; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.RemoveNewModifier { - [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.AddNew), Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.RemoveNew), Shared] internal class RemoveNewModifierCodeFixProvider : CodeFixProvider { internal const string CS0109 = nameof(CS0109); // The member 'SomeClass.SomeMember' does not hide an accessible member. The new keyword is not required. From 1710d2b7a4a0410159b4c621ea217340429cfb31 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 11:01:46 +0300 Subject: [PATCH 069/222] RemoveNewModifierCodeFixProvider: check memberDeclarationSyntax for null --- .../RemoveNewModifierCodeFixProvider.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index 75b39c2896cb4..1bf51f37acc14 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -35,24 +35,25 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var diagnosticSpan = diagnostic.Location.SourceSpan; var token = root.FindToken(diagnosticSpan.Start); + var memberDeclarationSyntax = token.GetAncestor(); + if (memberDeclarationSyntax == null) + return; - var newModifier = CSharpSyntaxFacts.Instance.GetModifiers(memberDeclarationSyntax) - .FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); + var newModifier = GetNewModifier(memberDeclarationSyntax, CSharpSyntaxFacts.Instance); + if (newModifier == default) + return; - if (newModifier != default) - { - context.RegisterCodeFix( - new MyCodeAction(ct => FixAsync(context.Document, memberDeclarationSyntax, ct)), - context.Diagnostics); - } + context.RegisterCodeFix( + new MyCodeAction(ct => FixAsync(context.Document, memberDeclarationSyntax, ct)), + context.Diagnostics); } private async Task FixAsync(Document document, MemberDeclarationSyntax node, CancellationToken cancellationToken) { var syntaxFacts = CSharpSyntaxFacts.Instance; - var newModifier = GetNewModifier(node); + var newModifier = GetNewModifier(node, syntaxFacts); var newNode = node; @@ -85,17 +86,17 @@ private async Task FixAsync(Document document, MemberDeclarationSyntax } } - newNode = newNode.ReplaceToken(GetNewModifier(newNode), SyntaxFactory.Token(SyntaxKind.None)); + newNode = newNode.ReplaceToken(GetNewModifier(newNode, syntaxFacts), SyntaxFactory.Token(SyntaxKind.None)); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = root.ReplaceNode(node, newNode); return document.WithSyntaxRoot(newRoot); - - SyntaxToken GetNewModifier(SyntaxNode fromNode) => - syntaxFacts.GetModifierTokens(fromNode).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); } + private static SyntaxToken GetNewModifier(SyntaxNode fromNode, CSharpSyntaxFacts syntaxFacts) => + syntaxFacts.GetModifierTokens(fromNode).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); + private class MyCodeAction : CustomCodeActions.DocumentChangeAction { public MyCodeAction(Func> createChangedDocument) From 7f5021cdc5ede21b80b9d26cd6c608487a3fd7c3 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 11:18:53 +0300 Subject: [PATCH 070/222] Move whitespace collapse from extensions to private method --- .../RemoveNewModifierCodeFixProvider.cs | 18 ++++++++++++++++-- .../Extensions/SyntaxTriviaListExtensions.cs | 19 ------------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index 1bf51f37acc14..480a19193fc48 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -71,8 +71,8 @@ private async Task FixAsync(Document document, MemberDeclarationSyntax newTrivia = newTrivia.AddRange(previousToken.TrailingTrivia); newTrivia = newTrivia .AddRange(newModifierTrivia) - .AddRange(nextToken.LeadingTrivia) - .CollapseSequentialWhitespaceTrivia(); + .AddRange(nextToken.LeadingTrivia); + newTrivia = CollapseSequentialWhitespaceTrivia(newTrivia); if (isFirstTokenOnLine) { @@ -97,6 +97,20 @@ private async Task FixAsync(Document document, MemberDeclarationSyntax private static SyntaxToken GetNewModifier(SyntaxNode fromNode, CSharpSyntaxFacts syntaxFacts) => syntaxFacts.GetModifierTokens(fromNode).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); + private static SyntaxTriviaList CollapseSequentialWhitespaceTrivia(SyntaxTriviaList triviaList) + { + var result = new SyntaxTriviaList(); + var previous = default(SyntaxTrivia); + foreach (var current in triviaList) + { + if (!(previous.IsWhitespace() && current.IsWhitespace())) + result = result.Add(current); + previous = current; + } + + return result; + } + private class MyCodeAction : CustomCodeActions.DocumentChangeAction { public MyCodeAction(Func> createChangedDocument) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs index 12419635ac09b..67a73fe7a6527 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTriviaListExtensions.cs @@ -90,24 +90,5 @@ public static IEnumerable TakeRange(this SyntaxTriviaList triviaLi yield return triviaList[start++]; } } - - /// - /// Returns modified with removed multiple - /// with kind arranged in a sequence - /// preserving only the first one: [space1][space2][space3] -> [space1]. - /// - public static SyntaxTriviaList CollapseSequentialWhitespaceTrivia(this SyntaxTriviaList triviaList) - { - var result = new SyntaxTriviaList(); - var previous = default(SyntaxTrivia); - foreach (var current in triviaList) - { - if (!(previous.IsWhitespace() && current.IsWhitespace())) - result = result.Add(current); - previous = current; - } - - return result; - } } } From afcc1f4d53a55c1e17b67d5c2772a89ec4c63511 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 11:20:16 +0300 Subject: [PATCH 071/222] Revert HideBaseTests --- .../CSharpTest/Diagnostics/HideBase/HideBaseTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs index c3151d8f12e91..f12f54725c676 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/HideBase/HideBaseTests.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. From 98fea2f9d7e74090f3c860a7a170f8aefc37780b Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 11:55:37 +0300 Subject: [PATCH 072/222] RemoveNewModifierCodeFixProvider: add header --- .../RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index 480a19193fc48..d1859537f6740 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -1,3 +1,7 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using System; using System.Collections.Immutable; using System.Composition; From 84d435c95b9ec47edef156b1b27e88d955bcb6c8 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Sun, 3 May 2020 11:58:56 +0300 Subject: [PATCH 073/222] RemoveNewModifierCodeFixProvider: override GetFixAllProvider --- .../RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index d1859537f6740..83b67386c0225 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -29,6 +29,9 @@ public RemoveNewModifierCodeFixProvider() { } + public override FixAllProvider GetFixAllProvider() + => WellKnownFixAllProviders.BatchFixer; + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(CS0109); public override async Task RegisterCodeFixesAsync(CodeFixContext context) From db1f014ca838ce04c5a57ee4a21a4d5278dcd74a Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Mon, 4 May 2020 08:31:56 +0300 Subject: [PATCH 074/222] internal -> private --- .../RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index 83b67386c0225..6cda6be7004fd 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -21,7 +21,7 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.RemoveNewModifier [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.RemoveNew), Shared] internal class RemoveNewModifierCodeFixProvider : CodeFixProvider { - internal const string CS0109 = nameof(CS0109); // The member 'SomeClass.SomeMember' does not hide an accessible member. The new keyword is not required. + private const string CS0109 = nameof(CS0109); // The member 'SomeClass.SomeMember' does not hide an accessible member. The new keyword is not required. [ImportingConstructor] [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] From c966953eaec60fb4ce85057a9df06803474c509b Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Mon, 4 May 2020 08:49:02 +0300 Subject: [PATCH 075/222] Add "fix all" test --- .../RemoveNewModifierCodeFixProviderTests.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs index b37827c17cd41..1ff9822d76a02 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs @@ -85,6 +85,55 @@ public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string origina public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) => TestRemoveNewModifierCodeFixAsync(original, expected); + [Fact] + public Task TestRemoveNewFromModifiersFixAll() => + TestInRegularAndScriptAsync(@" +using System; + +class B +{ + public int ValidNew; +} + +class C : B +{ + public new int ValidNew; + + public new void {|FixAllInDocument:M|}() { } + public new int F; + public new event Action E; + public new int P { get; } + public new int this[int p] => p; + new class C2 { } + new struct S2 { } + new interface I2 { } + new delegate void D2(); + new enum E2 { } +}", + @" +using System; + +class B +{ + public int ValidNew; +} + +class C : B +{ + public new int ValidNew; + + public void M() { } + public int F; + public event Action E; + public int P { get; } + public int this[int p] => p; + class C2 { } + struct S2 { } + interface I2 { } + delegate void D2(); + enum E2 { } +}"); + private Task TestRemoveNewModifierCodeFixAsync(string original, string expected) { return TestInRegularAndScript1Async( From ec8274b2c2f6760da9a6141f400a3ecdcd0b515a Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Tue, 5 May 2020 08:54:31 +0300 Subject: [PATCH 076/222] Remove trivia handling, simplify approach --- .../RemoveNewModifierCodeFixProviderTests.cs | 75 ++++-------------- .../RemoveNewModifierCodeFixProvider.cs | 77 ++++--------------- 2 files changed, 27 insertions(+), 125 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs index 1ff9822d76a02..b233120f4ef93 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs @@ -28,8 +28,8 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider "public new int [|Test|] { get; set; }", "public int [|Test|] { get; set; }")] [InlineData( - "public const new int [|test|] = 1;", - "public const int [|test|] = 1;")] + "public new const int [|test|] = 1;", + "public const int test = 1;")] [InlineData( "public new event Action [|Test|];", "public event Action Test;")] @@ -54,85 +54,36 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider [InlineData( "new(int a, int b) [|test|];", "(int a, int b) test;")] - public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string original, string expected) => - TestRemoveNewModifierCodeFixAsync(original, expected); + public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string original, string expected) + => TestRemoveNewModifierCodeFixAsync(original, expected); [Theory] [InlineData( "/* start */ public /* middle */ new /* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] + "/* start */ public /* middle */ int Test;")] [InlineData( "/* start */ public /* middle */ new /* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] + "/* start */ public /* middle */ int Test;")] [InlineData( "/* start */ public /* middle */new /* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] + "/* start */ public /* middle */int Test;")] [InlineData( "/* start */ public /* middle */ new/* end */ int [|Test|];", - "/* start */ public /* middle */ /* end */ int Test;")] + "/* start */ public /* middle */ int Test;")] [InlineData( "/* start */ public /* middle */new/* end */ int [|Test|];", - "/* start */ public /* middle *//* end */ int Test;")] + "/* start */ public /* middle */int Test;")] [InlineData( "new /* end */ int [|Test|];", - "/* end */ int Test;")] + "int Test;")] [InlineData( "new int [|Test|];", "int Test;")] [InlineData( "/* start */ new /* end */ int [|Test|];", - "/* start */ /* end */ int [|Test|];")] - public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) => - TestRemoveNewModifierCodeFixAsync(original, expected); - - [Fact] - public Task TestRemoveNewFromModifiersFixAll() => - TestInRegularAndScriptAsync(@" -using System; - -class B -{ - public int ValidNew; -} - -class C : B -{ - public new int ValidNew; - - public new void {|FixAllInDocument:M|}() { } - public new int F; - public new event Action E; - public new int P { get; } - public new int this[int p] => p; - new class C2 { } - new struct S2 { } - new interface I2 { } - new delegate void D2(); - new enum E2 { } -}", - @" -using System; - -class B -{ - public int ValidNew; -} - -class C : B -{ - public new int ValidNew; - - public void M() { } - public int F; - public event Action E; - public int P { get; } - public int this[int p] => p; - class C2 { } - struct S2 { } - interface I2 { } - delegate void D2(); - enum E2 { } -}"); + "/* start */ int [|Test|];")] + public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) + => TestRemoveNewModifierCodeFixAsync(original, expected); private Task TestRemoveNewModifierCodeFixAsync(string original, string expected) { diff --git a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs index 6cda6be7004fd..5a2e489fa2465 100644 --- a/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/RemoveNewModifier/RemoveNewModifierCodeFixProvider.cs @@ -11,9 +11,8 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp.Extensions; -using Microsoft.CodeAnalysis.CSharp.LanguageServices; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.RemoveNewModifier @@ -47,75 +46,27 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) if (memberDeclarationSyntax == null) return; - var newModifier = GetNewModifier(memberDeclarationSyntax, CSharpSyntaxFacts.Instance); - if (newModifier == default) + var generator = context.Document.GetRequiredLanguageService(); + if (!generator.GetModifiers(memberDeclarationSyntax).IsNew) return; context.RegisterCodeFix( - new MyCodeAction(ct => FixAsync(context.Document, memberDeclarationSyntax, ct)), + new MyCodeAction(ct => FixAsync(context.Document, generator, memberDeclarationSyntax, ct)), context.Diagnostics); } - private async Task FixAsync(Document document, MemberDeclarationSyntax node, CancellationToken cancellationToken) + private static async Task FixAsync( + Document document, + SyntaxGenerator generator, + MemberDeclarationSyntax memberDeclaration, + CancellationToken cancellationToken) { - var syntaxFacts = CSharpSyntaxFacts.Instance; + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var newModifier = GetNewModifier(node, syntaxFacts); - - var newNode = node; - - if (newModifier.HasTrailingTrivia || newModifier.HasLeadingTrivia) - { - var newModifierTrivia = newModifier.GetAllTrivia().ToSyntaxTriviaList(); - var previousToken = newModifier.GetPreviousToken(); - var nextToken = newModifier.GetNextToken(); - - var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - var isFirstTokenOnLine = newModifier.IsFirstTokenOnLine(sourceText); - - var newTrivia = new SyntaxTriviaList(); - if (!isFirstTokenOnLine) - newTrivia = newTrivia.AddRange(previousToken.TrailingTrivia); - newTrivia = newTrivia - .AddRange(newModifierTrivia) - .AddRange(nextToken.LeadingTrivia); - newTrivia = CollapseSequentialWhitespaceTrivia(newTrivia); - - if (isFirstTokenOnLine) - { - var nextTokenWithMovedTrivia = nextToken.WithLeadingTrivia(newTrivia); - newNode = newNode.ReplaceToken(nextToken, nextTokenWithMovedTrivia); - } - else - { - var previousTokenWithMovedTrivia = previousToken.WithTrailingTrivia(newTrivia); - newNode = newNode.ReplaceToken(previousToken, previousTokenWithMovedTrivia); - } - } - - newNode = newNode.ReplaceToken(GetNewModifier(newNode, syntaxFacts), SyntaxFactory.Token(SyntaxKind.None)); - - var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var newRoot = root.ReplaceNode(node, newNode); - - return document.WithSyntaxRoot(newRoot); - } - - private static SyntaxToken GetNewModifier(SyntaxNode fromNode, CSharpSyntaxFacts syntaxFacts) => - syntaxFacts.GetModifierTokens(fromNode).FirstOrDefault(m => m.IsKind(SyntaxKind.NewKeyword)); - - private static SyntaxTriviaList CollapseSequentialWhitespaceTrivia(SyntaxTriviaList triviaList) - { - var result = new SyntaxTriviaList(); - var previous = default(SyntaxTrivia); - foreach (var current in triviaList) - { - if (!(previous.IsWhitespace() && current.IsWhitespace())) - result = result.Add(current); - previous = current; - } - - return result; + return document.WithSyntaxRoot(root.ReplaceNode( + memberDeclaration, + generator.WithModifiers( + memberDeclaration, generator.GetModifiers(memberDeclaration).WithIsNew(false)))); } private class MyCodeAction : CustomCodeActions.DocumentChangeAction From daa9ab6a6042cb1343aa64e84b36fdf48b4d5460 Mon Sep 17 00:00:00 2001 From: Ivan Shimko Date: Tue, 5 May 2020 09:10:08 +0300 Subject: [PATCH 077/222] Bring back "fix all" test --- .../RemoveNewModifierCodeFixProviderTests.cs | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs index b233120f4ef93..2c1355ffdb2f0 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/RemoveNewModifier/RemoveNewModifierCodeFixProviderTests.cs @@ -14,8 +14,8 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.RemoveNewMo [Trait(Traits.Feature, Traits.Features.CodeActionsRemoveNewModifier)] public class RemoveNewModifierCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest { - internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => - (null, new RemoveNewModifierCodeFixProvider()); + internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) + => (null, new RemoveNewModifierCodeFixProvider()); [Theory] [InlineData( @@ -85,6 +85,49 @@ public Task TestRemoveNewModifierFromMembersWithRegularFormatting(string origina public Task TestRemoveNewFromModifiersWithComplexTrivia(string original, string expected) => TestRemoveNewModifierCodeFixAsync(original, expected); + [Fact] + public Task TestRemoveNewFromModifiersFixAll() + => TestInRegularAndScriptAsync(@" +using System; +class B +{ + public int ValidNew; +} +class C : B +{ + public new int ValidNew; + public new void {|FixAllInDocument:M|}() { } + public new int F; + public new event Action E; + public new int P { get; } + public new int this[int p] => p; + new class C2 { } + new struct S2 { } + new interface I2 { } + new delegate void D2(); + new enum E2 { } +}", + @" +using System; +class B +{ + public int ValidNew; +} +class C : B +{ + public new int ValidNew; + public void M() { } + public int F; + public event Action E; + public int P { get; } + public int this[int p] => p; + class C2 { } + struct S2 { } + interface I2 { } + delegate void D2(); + enum E2 { } +}"); + private Task TestRemoveNewModifierCodeFixAsync(string original, string expected) { return TestInRegularAndScript1Async( From 6be19dad737f832f9befbcadd81ffd4b3cb3aec6 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 6 May 2020 07:20:42 -0700 Subject: [PATCH 078/222] Remove unnecessary exception handler --- .../Def/Packaging/PackageInstallerServiceFactory.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index faaa9c34f2f60..198196cdd8458 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -117,17 +117,8 @@ public PackageInstallerService( if (allowSwitchToMainThread) { - try - { - using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); - packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); - } - catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested) - { - // The operation did not complete successfully due to a change in the workspace. Return but do not - // cache this result. - return null; - } + using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); + packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); } else if (_packageSourcesAsync.IsCompleted) { From 3ce396c9868b2d53f2d9bb51376c4d6c9ef6d3eb Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 6 May 2020 09:50:30 -0700 Subject: [PATCH 079/222] Remove unnecessary DoEvents call --- .../AsynchronousOperationListenerExtensions.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Workspaces/CoreTestUtilities/AsynchronousOperationListenerExtensions.cs b/src/Workspaces/CoreTestUtilities/AsynchronousOperationListenerExtensions.cs index 1920b74be92d2..17e3f01232c1d 100644 --- a/src/Workspaces/CoreTestUtilities/AsynchronousOperationListenerExtensions.cs +++ b/src/Workspaces/CoreTestUtilities/AsynchronousOperationListenerExtensions.cs @@ -5,7 +5,6 @@ #nullable enable using System.Threading.Tasks; -using System.Windows.Threading; using Microsoft.CodeAnalysis.Shared.TestHooks; namespace Roslyn.Test.Utilities @@ -13,7 +12,7 @@ namespace Roslyn.Test.Utilities public static class AsynchronousOperationListenerExtensions { internal static Task WaitAllDispatcherOperationAndTasksAsync(this IAsynchronousOperationListenerProvider provider, params string[] featureNames) - => ((AsynchronousOperationListenerProvider)provider).WaitAllAsync(featureNames, eventProcessingAction: () => Dispatcher.CurrentDispatcher.DoEvents()); + => ((AsynchronousOperationListenerProvider)provider).WaitAllAsync(featureNames); internal static IAsynchronousOperationWaiter GetWaiter(this IAsynchronousOperationListenerProvider provider, string featureName) => (IAsynchronousOperationWaiter)provider.GetListener(featureName); From 0dff451f01115cc6ac2d3a39d0e26311aa26fc6a Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Wed, 6 May 2020 10:37:52 -0700 Subject: [PATCH 080/222] Add quotes into error message so it's a bit easier to understand --- src/Features/Lsif/Generator/CompilerInvocation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/Lsif/Generator/CompilerInvocation.cs b/src/Features/Lsif/Generator/CompilerInvocation.cs index cf7fd09f118ab..b0ea66156daea 100644 --- a/src/Features/Lsif/Generator/CompilerInvocation.cs +++ b/src/Features/Lsif/Generator/CompilerInvocation.cs @@ -116,7 +116,7 @@ private static string GetLanguageName(CompilerInvocationInfo invocationInfo) { "csc" => LanguageNames.CSharp, "vbc" => LanguageNames.VisualBasic, - _ => throw new NotSupportedException($"Tool {invocationInfo.Tool} is not supported."), + _ => throw new NotSupportedException($"Tool '{invocationInfo.Tool}' is not supported."), }; } From 76463da04fe64bc6ea74794c778f8232815c7b0f Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 6 May 2020 11:01:55 -0700 Subject: [PATCH 081/222] Simplify handling of completed tasks --- .../Def/Packaging/PackageInstallerServiceFactory.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 198196cdd8458..543c3fbc84698 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -115,21 +115,11 @@ public PackageInstallerService( } } - if (allowSwitchToMainThread) + if (allowSwitchToMainThread || _packageSourcesAsync.IsCompleted) { using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); } - else if (_packageSourcesAsync.IsCompleted) - { - if (_packageSourcesAsync.Task.Status != TaskStatus.RanToCompletion) - { - // The operation did not complete successfully - return null; - } - - packageSources = _packageSourcesAsync.GetAwaiter().GetResult(); - } else { // The result was not available and switching to the main thread is not allowed. Return without caching From 603c39619a8d16a490ea4beb9f0e608d4bfb21ac Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 6 May 2020 11:13:20 -0700 Subject: [PATCH 082/222] Reset cached package sources upon notification from NuGet --- .../PackageInstallerServiceFactory.cs | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 543c3fbc84698..ddee8232fb7dc 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -55,7 +55,6 @@ internal partial class PackageInstallerService : AbstractDelayStartedService, IP private readonly Lazy _packageUninstaller; private readonly Lazy _packageSourceProvider; - private ImmutableArray _packageSources; private JoinableTask> _packageSourcesAsync; private IVsPackage _nugetPackageManager; @@ -96,15 +95,10 @@ public PackageInstallerService( public async ValueTask?> TryGetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken) { - // Only read from _packageSources once, since OnSourceProviderSourcesChanged could reset it to default at - // any time while this method is running. - var packageSources = _packageSources; - if (packageSources != null) - { - return packageSources; - } - - if (_packageSourcesAsync is null) + // Only read from _packageSourcesAsync once, since OnSourceProviderSourcesChanged could reset it to default + // at any time while this method is running. + var packageSourcesAsync = _packageSourcesAsync; + if (packageSourcesAsync is null) { lock (_gate) { @@ -112,13 +106,20 @@ public PackageInstallerService( { _packageSourcesAsync = ThreadingContext.JoinableTaskFactory.RunAsync(() => GetPackageSourcesImplAsync()); } + + packageSourcesAsync = _packageSourcesAsync; } } - if (allowSwitchToMainThread || _packageSourcesAsync.IsCompleted) + if (packageSourcesAsync.IsCompleted) + { + // Since the task is already completed, we know this 'await' will complete synchronously. + return await packageSourcesAsync; + } + else if (allowSwitchToMainThread) { using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); - packageSources = await _packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); + return await packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); } else { @@ -126,15 +127,6 @@ public PackageInstallerService( // a result. return null; } - - var previousPackageSources = ImmutableInterlocked.InterlockedCompareExchange(ref _packageSources, packageSources, default); - if (previousPackageSources != null) - { - // Another thread already initialized _packageSources - packageSources = previousPackageSources; - } - - return packageSources; } private async Task> GetPackageSourcesImplAsync() @@ -242,7 +234,12 @@ protected override void StartWorking() private void OnSourceProviderSourcesChanged(object sender, EventArgs e) { - _packageSources = default; + lock (_gate) + { + // Reset the task for loading package sources. + _packageSourcesAsync = null; + } + PackageSourcesChanged?.Invoke(this, EventArgs.Empty); } From eef21abf681891fcc1f6bd1fb1b17b11c4961669 Mon Sep 17 00:00:00 2001 From: Allison Chou Date: Wed, 6 May 2020 12:51:23 -0700 Subject: [PATCH 083/222] Bring back old changes minus changes to XAML and FSharp interfaces --- .../FSharp/Editor/IFSharpEditorInlineRenameService.cs | 5 ----- .../Internal/Editor/FSharpEditorInlineRenameService.cs | 3 ++- .../Xaml/Impl/Features/InlineRename/IXamlRenameInfo.cs | 5 ----- .../Features/InlineRename/XamlEditorInlineRenameService.cs | 3 ++- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Tools/ExternalAccess/FSharp/Editor/IFSharpEditorInlineRenameService.cs b/src/Tools/ExternalAccess/FSharp/Editor/IFSharpEditorInlineRenameService.cs index 89fbf19f09dbf..790eb5932de91 100644 --- a/src/Tools/ExternalAccess/FSharp/Editor/IFSharpEditorInlineRenameService.cs +++ b/src/Tools/ExternalAccess/FSharp/Editor/IFSharpEditorInlineRenameService.cs @@ -130,11 +130,6 @@ internal interface IFSharpInlineRenameInfo /// FSharpGlyph Glyph { get; } - /// - /// The locations of the potential rename candidates for the symbol. - /// - ImmutableArray DefinitionLocations { get; } - /// /// Gets the final name of the symbol if the user has typed the provided replacement text /// in the editor. Normally, the final name will be same as the replacement text. However, diff --git a/src/Tools/ExternalAccess/FSharp/Internal/Editor/FSharpEditorInlineRenameService.cs b/src/Tools/ExternalAccess/FSharp/Internal/Editor/FSharpEditorInlineRenameService.cs index b874f0b08044d..c2099a73aaab1 100644 --- a/src/Tools/ExternalAccess/FSharp/Internal/Editor/FSharpEditorInlineRenameService.cs +++ b/src/Tools/ExternalAccess/FSharp/Internal/Editor/FSharpEditorInlineRenameService.cs @@ -131,7 +131,8 @@ public FSharpInlineRenameInfo(IFSharpInlineRenameInfo info) public Glyph Glyph => FSharpGlyphHelpers.ConvertTo(_info.Glyph); - public ImmutableArray DefinitionLocations => _info.DefinitionLocations; + // This property isn't currently supported in F# since it would involve modifying the IFSharpInlineRenameInfo interface. + public ImmutableArray DefinitionLocations => default; public async Task FindRenameLocationsAsync(OptionSet optionSet, CancellationToken cancellationToken) { diff --git a/src/VisualStudio/Xaml/Impl/Features/InlineRename/IXamlRenameInfo.cs b/src/VisualStudio/Xaml/Impl/Features/InlineRename/IXamlRenameInfo.cs index aaa7215da2f81..bef8c598dec43 100644 --- a/src/VisualStudio/Xaml/Impl/Features/InlineRename/IXamlRenameInfo.cs +++ b/src/VisualStudio/Xaml/Impl/Features/InlineRename/IXamlRenameInfo.cs @@ -43,11 +43,6 @@ internal interface IXamlRenameInfo /// SymbolKind Kind { get; } - /// - /// The locations of the potential rename candidates for the symbol. - /// - ImmutableArray DefinitionLocations { get; } - /// /// Find all locations to be renamed. /// diff --git a/src/VisualStudio/Xaml/Impl/Features/InlineRename/XamlEditorInlineRenameService.cs b/src/VisualStudio/Xaml/Impl/Features/InlineRename/XamlEditorInlineRenameService.cs index ab20bc3b94f47..44314ddc6b31b 100644 --- a/src/VisualStudio/Xaml/Impl/Features/InlineRename/XamlEditorInlineRenameService.cs +++ b/src/VisualStudio/Xaml/Impl/Features/InlineRename/XamlEditorInlineRenameService.cs @@ -67,7 +67,8 @@ public InlineRenameInfo(IXamlRenameInfoService renameService, Document document, public TextSpan TriggerSpan => _renameInfo.TriggerSpan; - public ImmutableArray DefinitionLocations => _renameInfo.DefinitionLocations; + // This property isn't currently supported in XAML since it would involve modifying the IXamlRenameInfo interface. + public ImmutableArray DefinitionLocations => default; public async Task FindRenameLocationsAsync(OptionSet optionSet, CancellationToken cancellationToken) { From 3fa58407d4827d997f9cb57ff9b52a5b8bcabed6 Mon Sep 17 00:00:00 2001 From: Allison Chou Date: Wed, 6 May 2020 13:25:31 -0700 Subject: [PATCH 084/222] remove unnecessary using --- .../AbstractEditorInlineRenameService.SymbolRenameInfo.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs index 832237b1573a5..04e7d9eb91bdb 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs @@ -11,7 +11,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; -using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Rename; From 22982fafb05efef2186751100a3101ad953dd5e0 Mon Sep 17 00:00:00 2001 From: Allison Chou Date: Wed, 6 May 2020 13:28:28 -0700 Subject: [PATCH 085/222] Formatting fixes --- .../AbstractEditorInlineRenameService.SymbolRenameInfo.cs | 1 - src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameService.cs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs index 04e7d9eb91bdb..f1c3e1bb52586 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.SymbolRenameInfo.cs @@ -121,7 +121,6 @@ public TextSpan GetReferenceEditSpan(InlineRenameLocation location, string trigg } var index = triggerText.LastIndexOf(searchName, StringComparison.Ordinal); - if (index < 0) { // Couldn't even find the search text at this reference location. This might happen diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameService.cs b/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameService.cs index e4df74b4c8680..c016810eba814 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameService.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameService.cs @@ -101,6 +101,7 @@ public InlineRenameSessionInfo StartInlineSession( { var workspace = document.Project.Solution.Workspace; var navigationService = workspace.Services.GetRequiredService(); + foreach (var documentSpan in inlineRenameInfo.DefinitionLocations) { var sourceText = documentSpan.Document.GetTextSynchronously(cancellationToken); From 137c783241d039434b6d5e839c7b7912336f4135 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Wed, 6 May 2020 15:02:23 -0700 Subject: [PATCH 086/222] Refactor AnalyzerRunner So it can be used as a library --- .../AnalyzerRunner/AnalyzerRunnerHelper.cs | 53 +++++ .../AnalyzerRunner/CodeRefactoringRunner.cs | 21 +- .../DiagnosticAnalyzerRunner.cs | 52 +++-- .../IncrementalAnalyzerRunner.cs | 40 ++-- src/Tools/AnalyzerRunner/Options.cs | 76 +++++-- src/Tools/AnalyzerRunner/Program.cs | 201 +++++++++--------- 6 files changed, 272 insertions(+), 171 deletions(-) create mode 100644 src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs diff --git a/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs b/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs new file mode 100644 index 0000000000000..02ce3865d2ed3 --- /dev/null +++ b/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Build.Locator; +using Microsoft.CodeAnalysis.MSBuild; + +namespace AnalyzerRunner +{ + public static class AnalyzerRunnerHelper + { + static AnalyzerRunnerHelper() + { + // QueryVisualStudioInstances returns Visual Studio installations on .NET Framework, and .NET Core SDK + // installations on .NET Core. We use the one with the most recent version. + var msBuildInstance = MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(x => x.Version).First(); + +#if NETCOREAPP + // Since we do not inherit msbuild.deps.json when referencing the SDK copy + // of MSBuild and because the SDK no longer ships with version matched assemblies, we + // register an assembly loader that will load assemblies from the msbuild path with + // equal or higher version numbers than requested. + LooseVersionAssemblyLoader.Register(msBuildInstance.MSBuildPath); +#endif + + MSBuildLocator.RegisterInstance(msBuildInstance); + } + + public static async Task LoadSolutionAsync(string solutionPath, CancellationToken cancellationToken) + { + var properties = new Dictionary + { +#if NETCOREAPP + // This property ensures that XAML files will be compiled in the current AppDomain + // rather than a separate one. Any tasks isolated in AppDomains or tasks that create + // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. + { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, +#endif + // Use the latest language version to force the full set of available analyzers to run on the project. + { "LangVersion", "latest" }, + }; + + var workspace = MSBuildWorkspace.Create(properties, AnalyzerRunnerMefHostServices.DefaultServices); + var solution = await workspace.OpenSolutionAsync(solutionPath, progress: null, cancellationToken).ConfigureAwait(false); + + return workspace; + } + } +} diff --git a/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs b/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs index c0911810c1e25..002852e0d7a32 100644 --- a/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs +++ b/src/Tools/AnalyzerRunner/CodeRefactoringRunner.cs @@ -5,11 +5,9 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; -using System.Runtime; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -22,14 +20,16 @@ namespace AnalyzerRunner { - internal sealed class CodeRefactoringRunner + public sealed class CodeRefactoringRunner { + private readonly Workspace _workspace; private readonly Options _options; private readonly ImmutableDictionary> _refactorings; private readonly ImmutableDictionary> _syntaxKinds; - public CodeRefactoringRunner(Options options) + public CodeRefactoringRunner(Workspace workspace, Options options) { + _workspace = workspace; _options = options; var refactorings = GetCodeRefactoringProviders(options.AnalyzerPath); @@ -40,21 +40,14 @@ public CodeRefactoringRunner(Options options) public bool HasRefactorings => _refactorings.Any(pair => pair.Value.Any()); - public async Task RunAsync(Workspace workspace, CancellationToken cancellationToken) + public async Task RunAsync(CancellationToken cancellationToken) { if (!HasRefactorings) { return; } - if (!string.IsNullOrEmpty(_options.ProfileRoot)) - { - ProfileOptimization.StartProfile(nameof(CodeRefactoringRunner)); - } - - var solution = workspace.CurrentSolution; - var stopwatch = PerformanceTracker.StartNew(); - + var solution = _workspace.CurrentSolution; var updatedSolution = solution; foreach (var project in solution.Projects) @@ -73,7 +66,7 @@ public async Task RunAsync(Workspace workspace, CancellationToken cancellationTo if (_options.ApplyChanges) { - workspace.TryApplyChanges(updatedSolution); + _workspace.TryApplyChanges(updatedSolution); } } diff --git a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs index c2beee7793ccb..04e340c1e3839 100644 --- a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs +++ b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs @@ -5,10 +5,8 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; using System.IO; using System.Linq; -using System.Runtime; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -19,13 +17,15 @@ namespace AnalyzerRunner { - internal sealed class DiagnosticAnalyzerRunner + public sealed class DiagnosticAnalyzerRunner { + private readonly Solution _solution; private readonly Options _options; private readonly ImmutableDictionary> _analyzers; - public DiagnosticAnalyzerRunner(Options options) + public DiagnosticAnalyzerRunner(Solution solution, Options options) { + _solution = solution; _options = options; var analyzers = GetDiagnosticAnalyzers(options.AnalyzerPath); @@ -34,20 +34,8 @@ public DiagnosticAnalyzerRunner(Options options) public bool HasAnalyzers => _analyzers.Any(pair => pair.Value.Any()); - public async Task RunAsync(Workspace workspace, CancellationToken cancellationToken) + private static Solution SetOptions(Solution solution) { - if (!HasAnalyzers) - { - return; - } - - if (!string.IsNullOrEmpty(_options.ProfileRoot)) - { - ProfileOptimization.StartProfile(nameof(DiagnosticAnalyzerRunner)); - } - - var solution = workspace.CurrentSolution; - // Make sure AD0001 and AD0002 are reported as errors foreach (var projectId in solution.ProjectIds) { @@ -62,6 +50,34 @@ public async Task RunAsync(Workspace workspace, CancellationToken cancellationTo solution = solution.WithProjectCompilationOptions(projectId, modifiedCompilationOptions); } + return solution; + } + + public async Task RunAsync(CancellationToken cancellationToken) + { + if (!HasAnalyzers) + { + return; + } + + var solution = _solution; + solution = SetOptions(solution); + + await GetAnalysisResultAsync(solution, _analyzers, _options, cancellationToken).ConfigureAwait(false); + } + + // Also runs per document analysis, used by AnalyzerRunner CLI tool + internal async Task RunAllAsync(CancellationToken cancellationToken) + { + if (!HasAnalyzers) + { + return; + } + + var solution = _solution; + + solution = SetOptions(solution); + var stopwatch = PerformanceTracker.StartNew(); var analysisResult = await GetAnalysisResultAsync(solution, _analyzers, _options, cancellationToken).ConfigureAwait(false); @@ -387,7 +403,7 @@ private static async Task GetProjectAnalysisResultAsync( } } - private static void WriteTelemetry(ImmutableDictionary dictionary) + internal static void WriteTelemetry(ImmutableDictionary dictionary) { if (dictionary.IsEmpty) { diff --git a/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs b/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs index 43e8597d24f69..130742fadb3ea 100644 --- a/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs +++ b/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Immutable; using System.Linq; -using System.Runtime; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -19,18 +18,20 @@ namespace AnalyzerRunner { - internal class IncrementalAnalyzerRunner + public sealed class IncrementalAnalyzerRunner { + private readonly Workspace _workspace; private readonly Options _options; - public IncrementalAnalyzerRunner(Options options) + public IncrementalAnalyzerRunner(Workspace workspace, Options options) { + _workspace = workspace; _options = options; } public bool HasAnalyzers => _options.IncrementalAnalyzerNames.Any(); - internal async Task RunAsync(Workspace workspace, CancellationToken cancellationToken) + public async Task RunAsync(CancellationToken cancellationToken) { if (!HasAnalyzers) { @@ -39,49 +40,40 @@ internal async Task RunAsync(Workspace workspace, CancellationToken cancellation var usePersistentStorage = _options.UsePersistentStorage; - workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options + _workspace.TryApplyChanges(_workspace.CurrentSolution.WithOptions(_workspace.Options .WithChangedOption(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp, _options.AnalysisScope) .WithChangedOption(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.VisualBasic, _options.AnalysisScope) .WithChangedOption(StorageOptions.Database, usePersistentStorage ? StorageDatabase.SQLite : StorageDatabase.None))); - if (!string.IsNullOrEmpty(_options.ProfileRoot)) - { - ProfileOptimization.StartProfile(nameof(IIncrementalAnalyzer)); - } - - var exportProvider = (IMefHostExportProvider)workspace.Services.HostServices; + var exportProvider = (IMefHostExportProvider)_workspace.Services.HostServices; - var solutionCrawlerRegistrationService = (SolutionCrawlerRegistrationService)workspace.Services.GetRequiredService(); - solutionCrawlerRegistrationService.Register(workspace); + var solutionCrawlerRegistrationService = (SolutionCrawlerRegistrationService)_workspace.Services.GetRequiredService(); + solutionCrawlerRegistrationService.Register(_workspace); if (usePersistentStorage) { - var persistentStorageService = workspace.Services.GetRequiredService(); - using var persistentStorage = persistentStorageService.GetStorage(workspace.CurrentSolution); + var persistentStorageService = _workspace.Services.GetRequiredService(); + using var persistentStorage = persistentStorageService.GetStorage(_workspace.CurrentSolution); if (persistentStorage is NoOpPersistentStorage) { throw new InvalidOperationException("Benchmark is not configured to use persistent storage."); } } - Console.WriteLine("Pausing 5 seconds before continuing analysis..."); - await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); - var incrementalAnalyzerProviders = exportProvider.GetExports(); - foreach (var incrementalAnalyzerName in _options.IncrementalAnalyzerNames) { - var incrementalAnalyzerProvider = incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).SingleOrDefault(provider => provider.Metadata.WorkspaceKinds?.Contains(workspace.Kind) ?? false)?.Value; + var incrementalAnalyzerProvider = incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).SingleOrDefault(provider => provider.Metadata.WorkspaceKinds?.Contains(_workspace.Kind) ?? false)?.Value; incrementalAnalyzerProvider ??= incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).SingleOrDefault(provider => provider.Metadata.WorkspaceKinds?.Contains(WorkspaceKind.Host) ?? false)?.Value; incrementalAnalyzerProvider ??= incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).Single(provider => provider.Metadata.WorkspaceKinds is null).Value; - var incrementalAnalyzer = incrementalAnalyzerProvider.CreateIncrementalAnalyzer(workspace); - solutionCrawlerRegistrationService.WaitUntilCompletion_ForTestingPurposesOnly(workspace, ImmutableArray.Create(incrementalAnalyzer)); + var incrementalAnalyzer = incrementalAnalyzerProvider.CreateIncrementalAnalyzer(_workspace); + solutionCrawlerRegistrationService.WaitUntilCompletion_ForTestingPurposesOnly(_workspace, ImmutableArray.Create(incrementalAnalyzer)); switch (incrementalAnalyzerName) { case nameof(SymbolTreeInfoIncrementalAnalyzerProvider): - var symbolTreeInfoCacheService = workspace.Services.GetRequiredService(); - var symbolTreeInfo = await symbolTreeInfoCacheService.TryGetSourceSymbolTreeInfoAsync(workspace.CurrentSolution.Projects.First(), cancellationToken).ConfigureAwait(false); + var symbolTreeInfoCacheService = _workspace.Services.GetRequiredService(); + var symbolTreeInfo = await symbolTreeInfoCacheService.TryGetSourceSymbolTreeInfoAsync(_workspace.CurrentSolution.Projects.First(), cancellationToken).ConfigureAwait(false); if (symbolTreeInfo is null) { throw new InvalidOperationException("Benchmark failed to calculate symbol tree info."); diff --git a/src/Tools/AnalyzerRunner/Options.cs b/src/Tools/AnalyzerRunner/Options.cs index 783ab9770cb7a..55851f9deb9a9 100644 --- a/src/Tools/AnalyzerRunner/Options.cs +++ b/src/Tools/AnalyzerRunner/Options.cs @@ -10,7 +10,7 @@ namespace AnalyzerRunner { - internal sealed class Options + public sealed class Options { public readonly string AnalyzerPath; public readonly string SolutionPath; @@ -20,22 +20,62 @@ internal sealed class Options public readonly bool RunConcurrent; public readonly bool ReportSuppressedDiagnostics; public readonly bool ApplyChanges; - public readonly bool ShowStats; - public readonly bool ShowCompilerDiagnostics; public readonly bool UseAll; public readonly int Iterations; - public readonly bool TestDocuments; - public readonly Func TestDocumentMatch; - public readonly int TestDocumentIterations; - public readonly string LogFileName; - public readonly string ProfileRoot; + // Options specific to incremental analyzers public readonly bool UsePersistentStorage; - public readonly BackgroundAnalysisScope AnalysisScope; - public readonly ImmutableList IncrementalAnalyzerNames; + public readonly ImmutableArray IncrementalAnalyzerNames; + public readonly bool FullSolutionAnalysis; + + // Options used by AnalyzerRunner CLI only + internal readonly bool ShowStats; + internal readonly bool ShowCompilerDiagnostics; + internal readonly bool TestDocuments; + internal readonly Func TestDocumentMatch; + internal readonly int TestDocumentIterations; + internal readonly string LogFileName; + internal readonly string ProfileRoot; + + internal BackgroundAnalysisScope AnalysisScope + => FullSolutionAnalysis ? BackgroundAnalysisScope.FullSolution : BackgroundAnalysisScope.Default; + + public Options( + string analyzerPath, + string solutionPath, + ImmutableHashSet analyzerIds, + ImmutableHashSet refactoringNodes, + bool runConcurrent, + bool reportSuppressedDiagnostics, + bool applyChanges, + bool useAll, + int iterations, + bool usePersistentStorage, + bool fullSolutionAnalysis, + ImmutableArray incrementalAnalyzerNames) + : this(analyzerPath, + solutionPath, + analyzerIds, + refactoringNodes, + runConcurrent, + reportSuppressedDiagnostics, + applyChanges, + showStats: false, + showCompilerDiagnostics: false, + useAll, + iterations, + testDocuments: false, + testDocumentMatch: _ => false, + testDocumentIterations: 0, + logFileName: null, + profileRoot: null, + usePersistentStorage, + fullSolutionAnalysis, + incrementalAnalyzerNames) + { } - private Options( + internal Options( string analyzerPath, string solutionPath, ImmutableHashSet analyzerIds, @@ -53,8 +93,8 @@ private Options( string logFileName, string profileRoot, bool usePersistentStorage, - BackgroundAnalysisScope analysisScope, - ImmutableList incrementalAnalyzerNames) + bool fullSolutionAnalysis, + ImmutableArray incrementalAnalyzerNames) { AnalyzerPath = analyzerPath; SolutionPath = solutionPath; @@ -73,7 +113,7 @@ private Options( LogFileName = logFileName; ProfileRoot = profileRoot; UsePersistentStorage = usePersistentStorage; - AnalysisScope = analysisScope; + FullSolutionAnalysis = fullSolutionAnalysis; IncrementalAnalyzerNames = incrementalAnalyzerNames; } @@ -96,8 +136,8 @@ internal static Options Create(string[] args) string logFileName = null; string profileRoot = null; var usePersistentStorage = false; - var analysisScope = BackgroundAnalysisScope.Default; - var incrementalAnalyzerNames = ImmutableList.CreateBuilder(); + var fullSolutionAnalysis = false; + var incrementalAnalyzerNames = ImmutableArray.CreateBuilder(); int i = 0; while (i < args.Length) @@ -155,7 +195,7 @@ internal static Options Create(string[] args) usePersistentStorage = true; break; case "/fsa": - analysisScope = BackgroundAnalysisScope.FullSolution; + fullSolutionAnalysis = true; break; case "/ia": incrementalAnalyzerNames.Add(ReadValue()); @@ -207,7 +247,7 @@ internal static Options Create(string[] args) logFileName: logFileName, profileRoot: profileRoot, usePersistentStorage: usePersistentStorage, - analysisScope: analysisScope, + fullSolutionAnalysis: fullSolutionAnalysis, incrementalAnalyzerNames: incrementalAnalyzerNames.ToImmutable()); } } diff --git a/src/Tools/AnalyzerRunner/Program.cs b/src/Tools/AnalyzerRunner/Program.cs index fdffa6eb1d4d2..ad9002bbeb656 100644 --- a/src/Tools/AnalyzerRunner/Program.cs +++ b/src/Tools/AnalyzerRunner/Program.cs @@ -6,13 +6,11 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime; using System.Threading; using System.Threading.Tasks; -using Microsoft.Build.Locator; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.MSBuild; @@ -39,7 +37,7 @@ public static async Task Main(string[] args) return; } - CancellationTokenSource cts = new CancellationTokenSource(); + var cts = new CancellationTokenSource(); Console.CancelKeyPress += (sender, e) => { @@ -47,23 +45,31 @@ public static async Task Main(string[] args) cts.Cancel(); }; - // QueryVisualStudioInstances returns Visual Studio installations on .NET Framework, and .NET Core SDK - // installations on .NET Core. We use the one with the most recent version. - var msBuildInstance = MSBuildLocator.QueryVisualStudioInstances().OrderByDescending(x => x.Version).First(); + var cancellationToken = cts.Token; + + var stopwatch = PerformanceTracker.StartNew(); -#if NETCOREAPP - // Since we do not inherit msbuild.deps.json when referencing the SDK copy - // of MSBuild and because the SDK no longer ships with version matched assemblies, we - // register an assembly loader that will load assemblies from the msbuild path with - // equal or higher version numbers than requested. - LooseVersionAssemblyLoader.Register(msBuildInstance.MSBuildPath); -#endif + if (!string.IsNullOrEmpty(options.ProfileRoot)) + { + ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync)); + } - MSBuildLocator.RegisterInstance(msBuildInstance); + using var workspace = await AnalyzerRunnerHelper.LoadSolutionAsync(options.SolutionPath, cancellationToken).ConfigureAwait(false); + + foreach (var workspaceDiagnostic in workspace.Diagnostics) + { + if (workspaceDiagnostic.Kind == WorkspaceDiagnosticKind.Failure) + { + Console.WriteLine(workspaceDiagnostic.Message); + } + } + + Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); + + var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(workspace, options); + var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(workspace.CurrentSolution, options); + var codeRefactoringRunner = new CodeRefactoringRunner(workspace, options); - var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(options); - var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(options); - var codeRefactoringRunner = new CodeRefactoringRunner(options); if (!incrementalAnalyzerRunner.HasAnalyzers && !diagnosticAnalyzerRunner.HasAnalyzers && !codeRefactoringRunner.HasRefactorings) { WriteLine("No analyzers found", ConsoleColor.Red); @@ -71,113 +77,114 @@ public static async Task Main(string[] args) return; } - var cancellationToken = cts.Token; - - if (!string.IsNullOrEmpty(options.ProfileRoot)) + if (options.ShowStats) { - Directory.CreateDirectory(options.ProfileRoot); - ProfileOptimization.SetProfileRoot(options.ProfileRoot); + stopwatch = PerformanceTracker.StartNew(); + ShowSolutionStatistics(workspace.CurrentSolution, cancellationToken); + Console.WriteLine($"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"); } - var stopwatch = PerformanceTracker.StartNew(); - var properties = new Dictionary + if (options.ShowCompilerDiagnostics) { -#if NETCOREAPP - // This property ensures that XAML files will be compiled in the current AppDomain - // rather than a separate one. Any tasks isolated in AppDomains or tasks that create - // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. - { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, -#endif - // Use the latest language version to force the full set of available analyzers to run on the project. - { "LangVersion", "latest" }, - }; - - if (!string.IsNullOrEmpty(options.ProfileRoot)) - { - ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync)); + await ShowCompilerDiagnosticsAsync(workspace.CurrentSolution, cancellationToken).ConfigureAwait(false); } - using (MSBuildWorkspace workspace = MSBuildWorkspace.Create(properties, AnalyzerRunnerMefHostServices.DefaultServices)) - { - Solution solution = await workspace.OpenSolutionAsync(options.SolutionPath, progress: null, cancellationToken).ConfigureAwait(false); - var projectIds = solution.ProjectIds; + Console.WriteLine("Pausing 5 seconds before starting analysis..."); + await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); - foreach (var workspaceDiagnostic in workspace.Diagnostics) + if (incrementalAnalyzerRunner.HasAnalyzers) + { + if (!string.IsNullOrEmpty(options.ProfileRoot)) { - if (workspaceDiagnostic.Kind == WorkspaceDiagnosticKind.Failure) - { - Console.WriteLine(workspaceDiagnostic.Message); - } + ProfileOptimization.StartProfile(nameof(Microsoft.CodeAnalysis.SolutionCrawler.IIncrementalAnalyzer)); } - foreach (var projectId in projectIds) + await incrementalAnalyzerRunner.RunAsync(cancellationToken).ConfigureAwait(false); + } + + if (diagnosticAnalyzerRunner.HasAnalyzers) + { + if (!string.IsNullOrEmpty(options.ProfileRoot)) { - solution = solution.WithProjectAnalyzerReferences(projectId, ImmutableArray.Empty); + ProfileOptimization.StartProfile(nameof(DiagnosticAnalyzerRunner)); } - Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); + await diagnosticAnalyzerRunner.RunAllAsync(cancellationToken).ConfigureAwait(false); + } - if (options.ShowStats) + if (codeRefactoringRunner.HasRefactorings) + { + if (!string.IsNullOrEmpty(options.ProfileRoot)) { - stopwatch = PerformanceTracker.StartNew(); - - List projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); + ProfileOptimization.StartProfile(nameof(CodeRefactoringRunner)); + } - Console.WriteLine("Number of projects:\t\t" + projects.Count); - Console.WriteLine("Number of documents:\t\t" + projects.Sum(x => x.DocumentIds.Count)); + await codeRefactoringRunner.RunAsync(cancellationToken).ConfigureAwait(false); + } + } - var statistics = GetSolutionStatistics(projects, cancellationToken); + private static async Task ShowCompilerDiagnosticsAsync(Solution solution, CancellationToken cancellationToken) + { + var projectIds = solution.ProjectIds; - Console.WriteLine("Number of syntax nodes:\t\t" + statistics.NumberofNodes); - Console.WriteLine("Number of syntax tokens:\t" + statistics.NumberOfTokens); - Console.WriteLine("Number of syntax trivia:\t" + statistics.NumberOfTrivia); + foreach (var projectId in projectIds) + { + solution = solution.WithProjectAnalyzerReferences(projectId, ImmutableArray.Empty); + } - Console.WriteLine($"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"); - } + var projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); - if (options.ShowCompilerDiagnostics) + var diagnosticStatistics = new Dictionary(); + foreach (var project in projects) + { + var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + foreach (var diagnostic in compilation.GetDiagnostics(cancellationToken)) { - var projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); - - var diagnosticStatistics = new Dictionary(); - foreach (var project in projects) + diagnosticStatistics.TryGetValue(diagnostic.Id, out var existing); + var description = existing.description; + if (string.IsNullOrEmpty(description)) { - var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - foreach (var diagnostic in compilation.GetDiagnostics(cancellationToken)) + description = diagnostic.Descriptor?.Title.ToString(); + if (string.IsNullOrEmpty(description)) { - diagnosticStatistics.TryGetValue(diagnostic.Id, out var existing); - var description = existing.description; - if (string.IsNullOrEmpty(description)) - { - description = diagnostic.Descriptor?.Title.ToString(); - if (string.IsNullOrEmpty(description)) - { - description = diagnostic.Descriptor?.MessageFormat.ToString(); - } - } - - diagnosticStatistics[diagnostic.Id] = (description, diagnostic.Descriptor.DefaultSeverity, existing.count + 1); + description = diagnostic.Descriptor?.MessageFormat.ToString(); } } - foreach (var pair in diagnosticStatistics) - { - Console.WriteLine($" {pair.Value.severity} {pair.Key}: {pair.Value.count} instances ({pair.Value.description})"); - } + diagnosticStatistics[diagnostic.Id] = (description, diagnostic.Descriptor.DefaultSeverity, existing.count + 1); } + } - Console.WriteLine("Pausing 5 seconds before starting analysis..."); - await Task.Delay(TimeSpan.FromSeconds(5)).ConfigureAwait(false); - - await incrementalAnalyzerRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); - await diagnosticAnalyzerRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); - await codeRefactoringRunner.RunAsync(workspace, cancellationToken).ConfigureAwait(false); + foreach (var pair in diagnosticStatistics) + { + Console.WriteLine($" {pair.Value.severity} {pair.Key}: {pair.Value.count} instances ({pair.Value.description})"); } } + private static void ShowSolutionStatistics(Solution solution, CancellationToken cancellationToken) + { + var sums = new ConcurrentBag(); + var projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); + + Console.WriteLine("Number of projects:\t\t" + projects.Count); + Console.WriteLine("Number of documents:\t\t" + projects.Sum(x => x.DocumentIds.Count)); + + Parallel.ForEach(projects.SelectMany(project => project.Documents), document => + { + var documentStatistics = GetSolutionStatisticsAsync(document, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(); + sums.Add(documentStatistics); + }); + + var statistics = sums.Aggregate(new Statistic(0, 0, 0), (currentResult, value) => currentResult + value); + + Console.WriteLine("Number of syntax nodes:\t\t" + statistics.NumberofNodes); + Console.WriteLine("Number of syntax tokens:\t" + statistics.NumberOfTokens); + Console.WriteLine("Number of syntax trivia:\t" + statistics.NumberOfTrivia); + } + private static Statistic GetSolutionStatistics(IEnumerable projects, CancellationToken cancellationToken) { - ConcurrentBag sums = new ConcurrentBag(); + var sums = new ConcurrentBag(); Parallel.ForEach(projects.SelectMany(project => project.Documents), document => { @@ -185,7 +192,7 @@ private static Statistic GetSolutionStatistics(IEnumerable projects, Ca sums.Add(documentStatistics); }); - Statistic sum = sums.Aggregate(new Statistic(0, 0, 0), (currentResult, value) => currentResult + value); + var sum = sums.Aggregate(new Statistic(0, 0, 0), (currentResult, value) => currentResult + value); return sum; } @@ -193,15 +200,15 @@ private static Statistic GetSolutionStatistics(IEnumerable projects, Ca // https://github.com/dotnet/roslyn/issues/23108 private static async Task GetSolutionStatisticsAsync(Document document, CancellationToken cancellationToken) { - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - SyntaxNode root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); + var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); var tokensAndNodes = root.DescendantNodesAndTokensAndSelf(descendIntoTrivia: true); - int numberOfNodes = tokensAndNodes.Count(x => x.IsNode); - int numberOfTokens = tokensAndNodes.Count(x => x.IsToken); - int numberOfTrivia = root.DescendantTrivia(descendIntoTrivia: true).Count(); + var numberOfNodes = tokensAndNodes.Count(x => x.IsNode); + var numberOfTokens = tokensAndNodes.Count(x => x.IsToken); + var numberOfTrivia = root.DescendantTrivia(descendIntoTrivia: true).Count(); return new Statistic(numberOfNodes, numberOfTokens, numberOfTrivia); } From 96fa5ccee928764825f58ecebcd9d98eeeadcf92 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Wed, 6 May 2020 15:23:50 -0700 Subject: [PATCH 087/222] Add IDE benchmark targeting .NET Core --- Roslyn.sln | 7 ++ .../Assets/Microsoft.CodeAnalysis.sln | 30 +++++++ .../CSharpIdeAnalyzerBenchmarks.cs | 81 +++++++++++++++++++ .../IdeCoreBenchmarks.csproj | 28 +++++++ src/Tools/IdeCoreBenchmarks/Program.cs | 36 +++++++++ 5 files changed, 182 insertions(+) create mode 100644 src/Tools/IdeCoreBenchmarks/Assets/Microsoft.CodeAnalysis.sln create mode 100644 src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs create mode 100644 src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj create mode 100644 src/Tools/IdeCoreBenchmarks/Program.cs diff --git a/Roslyn.sln b/Roslyn.sln index 7fa920356be86..b70b3ff6aa34e 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -462,6 +462,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Edit EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.CodeStyle.LegacyTestFramework.UnitTestUtilities", "src\CodeStyle\Core\Tests\Microsoft.CodeAnalysis.CodeStyle.LegacyTestFramework.UnitTestUtilities.csproj", "{2D5E2DE4-5DA8-41C1-A14F-49855DCCE9C5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdeCoreBenchmarks", "src\Tools\IdeCoreBenchmarks\IdeCoreBenchmarks.csproj", "{CEA80C83-5848-4FF6-B4E8-CEEE9482E4AA}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Analyzers\VisualBasic\CodeFixes\VisualBasicCodeFixes.projitems*{0141285d-8f6c-42c7-baf3-3c0ccd61c716}*SharedItemsImports = 5 @@ -1213,6 +1215,10 @@ Global {2D5E2DE4-5DA8-41C1-A14F-49855DCCE9C5}.Debug|Any CPU.Build.0 = Debug|Any CPU {2D5E2DE4-5DA8-41C1-A14F-49855DCCE9C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {2D5E2DE4-5DA8-41C1-A14F-49855DCCE9C5}.Release|Any CPU.Build.0 = Release|Any CPU + {CEA80C83-5848-4FF6-B4E8-CEEE9482E4AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CEA80C83-5848-4FF6-B4E8-CEEE9482E4AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CEA80C83-5848-4FF6-B4E8-CEEE9482E4AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CEA80C83-5848-4FF6-B4E8-CEEE9482E4AA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1428,6 +1434,7 @@ Global {9C1BE25C-5926-4E56-84AE-D2242CB0627E} = {DF17AF27-AA02-482B-8946-5CA8A50D5A2B} {B64766CD-1A1F-4C1B-B11F-C30F82B8E41E} = {EE97CB90-33BB-4F3A-9B3D-69375DEC6AC6} {2D5E2DE4-5DA8-41C1-A14F-49855DCCE9C5} = {DC014586-8D07-4DE6-B28E-C0540C59C085} + {CEA80C83-5848-4FF6-B4E8-CEEE9482E4AA} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {604E6B91-7BC0-4126-AE07-D4D2FEFC3D29} diff --git a/src/Tools/IdeCoreBenchmarks/Assets/Microsoft.CodeAnalysis.sln b/src/Tools/IdeCoreBenchmarks/Assets/Microsoft.CodeAnalysis.sln new file mode 100644 index 0000000000000..4abe698163c46 --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/Assets/Microsoft.CodeAnalysis.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30030.7 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis", "..\..\..\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj", "{7B3C638D-D43E-4346-ACAC-56ACCE13B500}" +EndProject +Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\..\Compilers\Core\AnalyzerDriver\AnalyzerDriver.projitems*{7b3c638d-d43e-4346-acac-56acce13b500}*SharedItemsImports = 5 + ..\..\..\Dependencies\CodeAnalysis.Debugging\Microsoft.CodeAnalysis.Debugging.projitems*{7b3c638d-d43e-4346-acac-56acce13b500}*SharedItemsImports = 5 + ..\..\..\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{7b3c638d-d43e-4346-acac-56acce13b500}*SharedItemsImports = 5 + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7B3C638D-D43E-4346-ACAC-56ACCE13B500}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B3C638D-D43E-4346-ACAC-56ACCE13B500}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B3C638D-D43E-4346-ACAC-56ACCE13B500}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B3C638D-D43E-4346-ACAC-56ACCE13B500}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1A659683-1C0B-4A31-93C6-08B9E9D97170} + EndGlobalSection +EndGlobal diff --git a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs new file mode 100644 index 0000000000000..e2b95957e3c70 --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs @@ -0,0 +1,81 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using AnalyzerRunner; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Diagnosers; +using Microsoft.CodeAnalysis.MSBuild; + +namespace IdeCoreBenchmarks +{ + [MemoryDiagnoser] + [LegacyJitX64Job] + [RyuJitX64Job] + public class CSharpIdeAnalyzerBenchmarks + { + private readonly string _solutionPath; + + private Options _options; + private MSBuildWorkspace _workspace; + private DiagnosticAnalyzerRunner _runner; + private string _analyzerAssemblyPath; + + [Params("CSharpAddBracesDiagnosticAnalyzer")] + public string AnalyzerName { get; set; } + + public CSharpIdeAnalyzerBenchmarks() + { + var roslynRoot = Environment.GetEnvironmentVariable(Program.RoslynRootPathEnvVariableName); + _solutionPath = Path.Combine(roslynRoot, @"src\Tools\IdeCoreBenchmarks\Assets\Microsoft.CodeAnalysis.sln"); + + if (!File.Exists(_solutionPath)) + { + throw new ArgumentException(); + } + + _analyzerAssemblyPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Microsoft.CodeAnalysis.CSharp.Features.dll"); + } + + [GlobalSetup] + public void Setup() + { + _options = new Options( + analyzerPath: _analyzerAssemblyPath, + solutionPath: _solutionPath, + analyzerIds: ImmutableHashSet.Create(AnalyzerName), + refactoringNodes: ImmutableHashSet.Empty, + runConcurrent: true, + reportSuppressedDiagnostics: true, + applyChanges: false, + useAll: false, + iterations: 1, + usePersistentStorage: false, + fullSolutionAnalysis: false, + incrementalAnalyzerNames: ImmutableArray.Empty); + + _workspace = AnalyzerRunnerHelper.LoadSolutionAsync(_solutionPath, CancellationToken.None).Result; + _runner = new DiagnosticAnalyzerRunner(_workspace.CurrentSolution, _options); + } + + [GlobalCleanup] + public void Cleanup() + { + _workspace?.Dispose(); + _workspace = null; + } + + [Benchmark] + public async Task RunAnalyzer() + { + await _runner.RunAsync(CancellationToken.None).ConfigureAwait(false); + } + + } +} diff --git a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj new file mode 100644 index 0000000000000..fee524b7fdf3a --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj @@ -0,0 +1,28 @@ + + + + + + + Exe + netcoreapp3.1;net472 + false + AnyCPU + + + + + + + + + + + + + + + + + + diff --git a/src/Tools/IdeCoreBenchmarks/Program.cs b/src/Tools/IdeCoreBenchmarks/Program.cs new file mode 100644 index 0000000000000..0fb1960efed35 --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/Program.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Threading; +using System.Threading.Tasks; +using AnalyzerRunner; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Running; +using Microsoft.CodeAnalysis.MSBuild; + +namespace IdeCoreBenchmarks +{ + internal class Program + { + public const string RoslynRootPathEnvVariableName = "ROSLYN_SOURCE_ROOT_PATH"; + + public static string GetRoslynRootLocation([CallerFilePath] string sourceFilePath = "") + { + //This file is located at [Roslyn]\src\Tools\IdeCoreBenchmarks\Program.cs + return Path.Combine(Path.GetDirectoryName(sourceFilePath), @"..\..\.."); + } + + private static void Main(string[] args) + { + Environment.SetEnvironmentVariable(RoslynRootPathEnvVariableName, GetRoslynRootLocation()); + new BenchmarkSwitcher(typeof(Program).Assembly).Run(args); + } + } +} From 3558f369b1defde328123cb703fef40d1ab93b6d Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Wed, 6 May 2020 15:24:06 -0700 Subject: [PATCH 088/222] Bump Benchmark.NET version --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 1e8a757b8de54..d781e7d67f61c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -40,7 +40,7 @@ --> 0.9.3 - 0.11.4 + 0.12.1 2.0.273-beta 1.4.4 17.144.28413-buildid7983345 From 63f72155e6dc743772fc0d492e81050a9f4ef40f Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 30 Apr 2020 09:38:23 -0700 Subject: [PATCH 089/222] Support sequential testing --- eng/build.ps1 | 5 +++++ src/Tools/Source/RunTests/AssemblyScheduler.cs | 12 +++--------- src/Tools/Source/RunTests/Options.cs | 10 ++++++++++ src/Tools/Source/RunTests/TestRunner.cs | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index 61b814b2e598c..5616974384046 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -59,6 +59,7 @@ param ( [switch][Alias('test')]$testDesktop, [switch]$testCoreClr, [switch]$testIOperation, + [switch]$sequential, [parameter(ValueFromRemainingArguments=$true)][string[]]$properties) @@ -437,6 +438,10 @@ function TestUsingOptimizedRunner() { $args += " -test64" } + if ($sequential) { + $args += " -sequential" + } + foreach ($dll in $dlls) { $args += " $dll" } diff --git a/src/Tools/Source/RunTests/AssemblyScheduler.cs b/src/Tools/Source/RunTests/AssemblyScheduler.cs index 4f9782bbbbc7c..35c7c4fdd8f26 100644 --- a/src/Tools/Source/RunTests/AssemblyScheduler.cs +++ b/src/Tools/Source/RunTests/AssemblyScheduler.cs @@ -196,19 +196,13 @@ internal AssemblyScheduler(Options options, int methodLimit = DefaultMethodLimit _methodLimit = methodLimit; } - internal IEnumerable Schedule(IEnumerable assemblyPaths) + public IEnumerable Schedule(string assemblyPath, bool force = false) { - var list = new List(); - foreach (var assemblyPath in assemblyPaths) + if (_options.Sequential) { - list.AddRange(Schedule(assemblyPath)); + return new[] { CreateAssemblyInfo(assemblyPath) }; } - return list; - } - - public IEnumerable Schedule(string assemblyPath, bool force = false) - { var typeInfoList = GetTypeInfoList(assemblyPath); var assemblyInfoList = new List(); var partitionList = new List(); diff --git a/src/Tools/Source/RunTests/Options.cs b/src/Tools/Source/RunTests/Options.cs index d6114e1d0cd72..f0cbf1a82fb33 100644 --- a/src/Tools/Source/RunTests/Options.cs +++ b/src/Tools/Source/RunTests/Options.cs @@ -76,6 +76,11 @@ internal class Options /// public bool UseProcDump { get; set; } + /// + /// Disable partitioning and parallelization across test assemblies. + /// + public bool Sequential { get; set; } + /// /// The directory which contains procdump.exe. /// @@ -214,6 +219,11 @@ bool isOption(string argument, string optionName, out string value) opt.UseProcDump = false; index++; } + else if (comparer.Equals(current, "-sequential")) + { + opt.Sequential = true; + index++; + } else { break; diff --git a/src/Tools/Source/RunTests/TestRunner.cs b/src/Tools/Source/RunTests/TestRunner.cs index 12fe9ec7ce59b..d0daf9f84b46b 100644 --- a/src/Tools/Source/RunTests/TestRunner.cs +++ b/src/Tools/Source/RunTests/TestRunner.cs @@ -47,7 +47,7 @@ internal async Task RunAllAsync(IEnumerable assembly // Use 1.5 times the number of processors for unit tests, but only 1 processor for the open integration tests // since they perform actual UI operations (such as mouse clicks and sending keystrokes) and we don't want two // tests to conflict with one-another. - var max = (_options.TestVsi) ? 1 : (int)(Environment.ProcessorCount * 1.5); + var max = (_options.TestVsi || _options.Sequential) ? 1 : (int)(Environment.ProcessorCount * 1.5); var cacheCount = 0; var waiting = new Stack(assemblyInfoList); var running = new List>(); From 76ee5f5ab890deda8746e49b9c0a0cad731af8c2 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Thu, 7 May 2020 05:56:53 -0700 Subject: [PATCH 090/222] Skip executing analyzers by default on build This change skips executing analyzers by default on explicit builds (both inside VS and on command line prompt). This should speed up the overall build time of Roslyn.sln when building locally. The only time a developer would want analyzers to run locally outside the typing scenario is to compute the exact set of warnings for a specific project/solution before pushing your local changes to CI. They can now perform the following steps to achieve this: 1. On command line: Build with `/p:UseRoslynAnalyzers=true` or `/p:RunCodeAnalysis=true` 2. Inside VS: 1. Start VS with `%RoslynEnforceCodeStyle% = true`, all builds in VS should execute analyzers 2. Use `Run Code Analysis` command from `Analyze` menu on selected project/solution --- azure-pipelines-official.yml | 1 - azure-pipelines.yml | 12 ++++++------ eng/build-utils.ps1 | 8 ++++---- eng/build.ps1 | 11 +++++------ eng/build.sh | 2 +- eng/targets/Imports.targets | 12 ++++++++++++ eng/targets/Settings.props | 1 - eng/test-build-correctness.ps1 | 2 +- eng/test-determinism.ps1 | 2 +- 9 files changed, 30 insertions(+), 21 deletions(-) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 57a8fddcf18fa..5d2f16d1b13d8 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -103,7 +103,6 @@ stages: -officialSourceBranchName $(SourceBranchName) -officialIbcSourceBranchName $(IbcSourceBranchName) -officialIbcDropId $(IbcDropId) - -skipAnalyzers /p:RepositoryName=$(Build.Repository.Name) /p:VisualStudioDropAccessToken=$(System.AccessToken) /p:VisualStudioDropName=$(VisualStudio.DropName) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index debbd3fcc5df1..ee60afa3a978d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -37,7 +37,7 @@ jobs: timeoutInMinutes: 90 steps: - - script: eng/cibuild.cmd -configuration $(_configuration) -prepareMachine -testDesktop -$(_testKind) -procdump -skipAnalyzers + - script: eng/cibuild.cmd -configuration $(_configuration) -prepareMachine -testDesktop -$(_testKind) -procdump displayName: Build and Test - task: PublishTestResults@2 @@ -65,7 +65,7 @@ jobs: timeoutInMinutes: 90 steps: - - script: eng/cibuild.cmd -configuration Debug -prepareMachine -testDesktop -skipAnalyzers + - script: eng/cibuild.cmd -configuration Debug -prepareMachine -testDesktop displayName: Build and Test - task: PublishTestResults@2 @@ -99,7 +99,7 @@ jobs: timeoutInMinutes: 90 steps: - - script: eng/cibuild.cmd -configuration $(_configuration) -prepareMachine -msbuildEngine:dotnet -testCoreClr -skipAnalyzers + - script: eng/cibuild.cmd -configuration $(_configuration) -prepareMachine -msbuildEngine:dotnet -testCoreClr displayName: Build and Test - task: PublishTestResults@2 @@ -190,7 +190,7 @@ jobs: # _configuration: Debug timeoutInMinutes: 90 steps: - - script: ./eng/cibuild.sh --configuration $(_configuration) --prepareMachine --skipAnalyzers $(_args) + - script: ./eng/cibuild.sh --configuration $(_configuration) --prepareMachine $(_args) displayName: Build and Test - task: PublishTestResults@2 displayName: Publish xUnit Test Results @@ -216,7 +216,7 @@ jobs: queue: BuildPool.Ubuntu.1604.amd64.Open timeoutInMinutes: 90 steps: - - script: ./eng/cibuild.sh --configuration Debug --prepareMachine --docker --sourceBuild --skipAnalyzers + - script: ./eng/cibuild.sh --configuration Debug --prepareMachine --docker --sourceBuild displayName: Build - task: PublishBuildArtifacts@1 displayName: Publish Logs @@ -233,7 +233,7 @@ jobs: timeoutInMinutes: 90 steps: - - script: ./eng/cibuild.sh --configuration Debug --prepareMachine --testCoreClr --skipAnalyzers + - script: ./eng/cibuild.sh --configuration Debug --prepareMachine --testCoreClr displayName: Build and Test - task: PublishTestResults@2 diff --git a/eng/build-utils.ps1 b/eng/build-utils.ps1 index e76f65fed6d9e..0b75e2de04274 100644 --- a/eng/build-utils.ps1 +++ b/eng/build-utils.ps1 @@ -247,7 +247,7 @@ function Get-PackageDir([string]$name, [string]$version = "") { return $p } -function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration, [switch]$skipAnalyzers = $false) { +function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string]$logFileName = "", [switch]$parallel = $true, [switch]$summary = $true, [switch]$warnAsError = $true, [string]$configuration = $script:configuration, [switch]$runAnalyzers = $false) { # Because we override the C#/VB toolset to build against our LKG package, it is important # that we do not reuse MSBuild nodes from other jobs/builds on the machine. Otherwise, # we'll run into issues such as https://github.com/dotnet/roslyn/issues/6211. @@ -268,8 +268,8 @@ function Run-MSBuild([string]$projectFilePath, [string]$buildArgs = "", [string] $args += " /m" } - if ($skipAnalyzers) { - $args += " /p:UseRoslynAnalyzers=false" + if ($runAnalyzers) { + $args += " /p:UseRoslynAnalyzers=true" } if ($binaryLog) { @@ -317,7 +317,7 @@ function Make-BootstrapBuild([switch]$force32 = $false) { $projectPath = "src\NuGet\$packageName\$packageName.Package.csproj" $force32Flag = if ($force32) { " /p:BOOTSTRAP32=true" } else { "" } - Run-MSBuild $projectPath "/restore /t:Pack /p:RoslynEnforceCodeStyle=false /p:UseRoslynAnalyzers=false /p:DotNetUseShippingVersions=true /p:InitialDefineConstants=BOOTSTRAP /p:PackageOutputPath=`"$dir`" /p:EnableNgenOptimization=false /p:PublishWindowsPdb=false $force32Flag" -logFileName "Bootstrap" -configuration $bootstrapConfiguration -skipAnalyzers + Run-MSBuild $projectPath "/restore /t:Pack /p:RoslynEnforceCodeStyle=false /p:UseRoslynAnalyzers=false /p:DotNetUseShippingVersions=true /p:InitialDefineConstants=BOOTSTRAP /p:PackageOutputPath=`"$dir`" /p:EnableNgenOptimization=false /p:PublishWindowsPdb=false $force32Flag" -logFileName "Bootstrap" -configuration $bootstrapConfiguration -runAnalyzers $packageFile = Get-ChildItem -Path $dir -Filter "$packageName.*.nupkg" Unzip "$dir\$packageFile" $dir diff --git a/eng/build.ps1 b/eng/build.ps1 index 61b814b2e598c..cf24f002759fb 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -37,7 +37,7 @@ param ( [switch]$buildServerLog, [switch]$ci, [switch]$procdump, - [switch]$skipAnalyzers, + [switch]$runAnalyzers, [switch][Alias('d')]$deployExtensions, [switch]$prepareMachine, [switch]$useGlobalNuGetCache = $true, @@ -97,7 +97,7 @@ function Print-Usage() { Write-Host " -bootstrapConfiguration Build configuration for bootstrap compiler: 'Debug' or 'Release'" Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." Write-Host " -procdump Monitor test runs with procdump" - Write-Host " -skipAnalyzers Do not run analyzers during build operations" + Write-Host " -runAnalyzers Run analyzers during build operations" Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" Write-Host " -useGlobalNuGetCache Use global NuGet cache." Write-Host " -warnAsError Treat all warnings as errors" @@ -120,7 +120,7 @@ function Print-Usage() { # specified. # # In this function it's okay to use two arguments to extend the effect of another. For -# example it's okay to look at $testVsi and infer $skipAnalyzers. It's not okay though to infer +# example it's okay to look at $testVsi and infer $runAnalyzers. It's not okay though to infer # $build based on say $testDesktop. It's possible the developer wanted only for testing # to execute, not any build. function Process-Arguments() { @@ -178,7 +178,7 @@ function Process-Arguments() { if ($testVsi) { # Avoid spending time in analyzers when requested, and also in the slowest integration test builds - $script:skipAnalyzers = $true + $script:runAnalyzers = $false $script:bootstrap = $false } @@ -215,7 +215,6 @@ function BuildSolution() { } $projects = Join-Path $RepoRoot $solution - $enableAnalyzers = !$skipAnalyzers $toolsetBuildProj = InitializeToolset $testTargetFrameworks = if ($testCoreClr) { "netcoreapp3.1" } else { "" } @@ -258,7 +257,7 @@ function BuildSolution() { /p:Publish=$publish ` /p:ContinuousIntegrationBuild=$ci ` /p:OfficialBuildId=$officialBuildId ` - /p:UseRoslynAnalyzers=$enableAnalyzers ` + /p:UseRoslynAnalyzers=$runAnalyzers ` /p:BootstrapBuildPath=$bootstrapDir ` /p:TestTargetFrameworks=$testTargetFrameworks ` /p:TreatWarningsAsErrors=true ` diff --git a/eng/build.sh b/eng/build.sh index be6f3426f4da3..c8dbf5ea290d6 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -31,7 +31,7 @@ usage() echo " --ci Building in CI" echo " --docker Run in a docker container if applicable" echo " --bootstrap Build using a bootstrap compilers" - echo " --skipAnalyzers Do not run analyzers during build operations" + echo " --runAnalyzers Run analyzers during build operations" echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --warnAsError Treat all warnings as errors" echo " --sourceBuild Simulate building for source-build" diff --git a/eng/targets/Imports.targets b/eng/targets/Imports.targets index 8b8d2b0762091..43364a7f6afd8 100644 --- a/eng/targets/Imports.targets +++ b/eng/targets/Imports.targets @@ -34,6 +34,18 @@ true + + + false + true + + $(NoWarn);Nullable diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props index a0ec480d03d58..61d1dd9ba2b3a 100644 --- a/eng/targets/Settings.props +++ b/eng/targets/Settings.props @@ -23,7 +23,6 @@ true true true - true NON_EXISTENT_FILE diff --git a/eng/test-build-correctness.ps1 b/eng/test-build-correctness.ps1 index bc0ce119ce2af..b59154f40d312 100644 --- a/eng/test-build-correctness.ps1 +++ b/eng/test-build-correctness.ps1 @@ -34,7 +34,7 @@ try { Push-Location $RepoRoot Write-Host "Building Roslyn" - Exec-Block { & (Join-Path $PSScriptRoot "build.ps1") -restore -build -ci:$ci -configuration:$configuration -pack -binaryLog -useGlobalNuGetCache:$false -warnAsError:$true -properties "/p:RoslynEnforceCodeStyle=true"} + Exec-Block { & (Join-Path $PSScriptRoot "build.ps1") -restore -build -ci:$ci -runAnalyzers:$true -configuration:$configuration -pack -binaryLog -useGlobalNuGetCache:$false -warnAsError:$true -properties "/p:RoslynEnforceCodeStyle=true"} # Verify the state of our various build artifacts Write-Host "Running BuildBoss" diff --git a/eng/test-determinism.ps1 b/eng/test-determinism.ps1 index 835c0e42d587c..9ecac2ecd91e6 100644 --- a/eng/test-determinism.ps1 +++ b/eng/test-determinism.ps1 @@ -249,7 +249,7 @@ try { Create-Directory $errorDirLeft Create-Directory $errorDirRight - $skipAnalyzers = $true + $runAnalyzers = $false $binaryLog = $true $officialBuildId = "" $ci = $true From 71716fd556552c83a8a948324f7c7180020c29ff Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Thu, 7 May 2020 06:57:51 -0700 Subject: [PATCH 091/222] Dummy commit violating build enforced code style rule to test CI failure --- src/Workspaces/Core/Portable/CodeActions/CodeAction.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs index 77aa9283fc823..b3afcde46c4e0 100644 --- a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs +++ b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs @@ -5,6 +5,7 @@ #nullable enable using System; +using System.IO; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; From 6654a7862056bec7d2770e6c3a4b533a1c42f851 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Thu, 7 May 2020 11:16:19 -0700 Subject: [PATCH 092/222] Remove compiler benchmarks --- Roslyn.sln | 7 -- .../CompilerBenchmarks.csproj | 30 ----- src/Tools/CompilerBenchmarks/Helpers.cs | 27 ----- src/Tools/CompilerBenchmarks/Program.cs | 47 -------- src/Tools/CompilerBenchmarks/README.md | 11 -- .../CompilerBenchmarks/StageBenchmarks.cs | 114 ------------------ src/Tools/CompilerBenchmarks/run-perf.ps1 | 36 ------ 7 files changed, 272 deletions(-) delete mode 100644 src/Tools/CompilerBenchmarks/CompilerBenchmarks.csproj delete mode 100644 src/Tools/CompilerBenchmarks/Helpers.cs delete mode 100644 src/Tools/CompilerBenchmarks/Program.cs delete mode 100644 src/Tools/CompilerBenchmarks/README.md delete mode 100644 src/Tools/CompilerBenchmarks/StageBenchmarks.cs delete mode 100644 src/Tools/CompilerBenchmarks/run-perf.ps1 diff --git a/Roslyn.sln b/Roslyn.sln index b70b3ff6aa34e..031a80f3c3280 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -352,8 +352,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveHost64", "src\In EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.IntegrationTest.IntegrationService", "src\VisualStudio\IntegrationTest\IntegrationService\Microsoft.VisualStudio.IntegrationTest.IntegrationService.csproj", "{764D2C19-0187-4837-A2A3-96DDC6EF4CE2}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompilerBenchmarks", "src\Tools\CompilerBenchmarks\CompilerBenchmarks.csproj", "{9860FCF7-3111-4C12-A16F-ACEBA42D930F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Net.Compilers.Package", "src\NuGet\Microsoft.Net.Compilers\Microsoft.Net.Compilers.Package.csproj", "{9102ECF3-5CD1-4107-B8B7-F3795A52D790}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NETCore.Compilers.Package", "src\NuGet\Microsoft.NETCore.Compilers\Microsoft.NETCore.Compilers.Package.csproj", "{50CF5D8F-F82F-4210-A06E-37CC9BFFDD49}" @@ -1095,10 +1093,6 @@ Global {764D2C19-0187-4837-A2A3-96DDC6EF4CE2}.Debug|Any CPU.Build.0 = Debug|Any CPU {764D2C19-0187-4837-A2A3-96DDC6EF4CE2}.Release|Any CPU.ActiveCfg = Release|Any CPU {764D2C19-0187-4837-A2A3-96DDC6EF4CE2}.Release|Any CPU.Build.0 = Release|Any CPU - {9860FCF7-3111-4C12-A16F-ACEBA42D930F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9860FCF7-3111-4C12-A16F-ACEBA42D930F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9860FCF7-3111-4C12-A16F-ACEBA42D930F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9860FCF7-3111-4C12-A16F-ACEBA42D930F}.Release|Any CPU.Build.0 = Release|Any CPU {9102ECF3-5CD1-4107-B8B7-F3795A52D790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9102ECF3-5CD1-4107-B8B7-F3795A52D790}.Debug|Any CPU.Build.0 = Debug|Any CPU {9102ECF3-5CD1-4107-B8B7-F3795A52D790}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1382,7 +1376,6 @@ Global {037F06F0-3BE8-42D0-801E-2F74FC380AB8} = {55A62CFA-1155-46F1-ADF3-BEEE51B58AB5} {2F11618A-9251-4609-B3D5-CE4D2B3D3E49} = {5CA5F70E-0FDB-467B-B22C-3CD5994F0087} {764D2C19-0187-4837-A2A3-96DDC6EF4CE2} = {CC126D03-7EAC-493F-B187-DCDEE1EF6A70} - {9860FCF7-3111-4C12-A16F-ACEBA42D930F} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {9102ECF3-5CD1-4107-B8B7-F3795A52D790} = {C52D8057-43AF-40E6-A01B-6CDBB7301985} {50CF5D8F-F82F-4210-A06E-37CC9BFFDD49} = {C52D8057-43AF-40E6-A01B-6CDBB7301985} {CFA94A39-4805-456D-A369-FC35CCC170E9} = {C52D8057-43AF-40E6-A01B-6CDBB7301985} diff --git a/src/Tools/CompilerBenchmarks/CompilerBenchmarks.csproj b/src/Tools/CompilerBenchmarks/CompilerBenchmarks.csproj deleted file mode 100644 index 72fe95584cc52..0000000000000 --- a/src/Tools/CompilerBenchmarks/CompilerBenchmarks.csproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Exe - netcoreapp3.1 - false - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Tools/CompilerBenchmarks/Helpers.cs b/src/Tools/CompilerBenchmarks/Helpers.cs deleted file mode 100644 index 5b45a300e3a4a..0000000000000 --- a/src/Tools/CompilerBenchmarks/Helpers.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Test.Utilities; - -namespace CompilerBenchmarks -{ - internal static class Helpers - { - public const string TestProjectEnvVarName = "ROSLYN_TEST_PROJECT_DIR"; - - public static Compilation CreateReproCompilation() - { - var projectDir = Environment.GetEnvironmentVariable(TestProjectEnvVarName); - var cmdLineParser = new CSharpCommandLineParser(); - var responseFile = Path.Combine(projectDir, "repro.rsp"); - var compiler = new MockCSharpCompiler(responseFile, projectDir, Array.Empty()); - var output = new StringWriter(); - return compiler.CreateCompilation(output, null, null); - } - } -} diff --git a/src/Tools/CompilerBenchmarks/Program.cs b/src/Tools/CompilerBenchmarks/Program.cs deleted file mode 100644 index f797811ef9d14..0000000000000 --- a/src/Tools/CompilerBenchmarks/Program.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.IO; -using System.Linq; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Diagnosers; -using BenchmarkDotNet.Jobs; -using BenchmarkDotNet.Running; -using BenchmarkDotNet.Validators; - -namespace CompilerBenchmarks -{ - public class Program - { - private class IgnoreReleaseOnly : ManualConfig - { - public IgnoreReleaseOnly() - { - Add(JitOptimizationsValidator.DontFailOnError); - Add(DefaultConfig.Instance.GetLoggers().ToArray()); - Add(DefaultConfig.Instance.GetExporters().ToArray()); - Add(DefaultConfig.Instance.GetColumnProviders().ToArray()); - Add(MemoryDiagnoser.Default); - Add(Job.Core.WithGcServer(true)); - } - } - - public static void Main(string[] args) - { - var projectPath = args[0]; - var artifactsPath = Path.Combine(projectPath, "../BenchmarkDotNet.Artifacts"); - - var config = new IgnoreReleaseOnly(); - var artifactsDir = Directory.CreateDirectory(artifactsPath); - config.ArtifactsPath = artifactsDir.FullName; - - // Benchmark.NET creates a new process to run the benchmark, so the easiest way - // to communicate information is pass by environment variable - Environment.SetEnvironmentVariable(Helpers.TestProjectEnvVarName, projectPath); - - _ = BenchmarkRunner.Run(config); - } - } -} diff --git a/src/Tools/CompilerBenchmarks/README.md b/src/Tools/CompilerBenchmarks/README.md deleted file mode 100644 index a4a49944e78e4..0000000000000 --- a/src/Tools/CompilerBenchmarks/README.md +++ /dev/null @@ -1,11 +0,0 @@ - -This project contains a set of "micro" benchmarks for the compiler, focused on measuring -the time spent in specific phases of the compiler, e.g. Emit, metadata serialization, binding, -parsing, etc. - -To run all benchmarks, simply run the `run-perf.ps1` file on your machine, which should produce -a simple output table containing the results. To compare the results of your change, you can -run the script before and after and attempt to compare the results. Calculating statistical -significance is beyond the scope of this document, but you can get a general idea of whether -or not your changes are significant if the different is substantially larger than the "error" -value reported in the results summary. \ No newline at end of file diff --git a/src/Tools/CompilerBenchmarks/StageBenchmarks.cs b/src/Tools/CompilerBenchmarks/StageBenchmarks.cs deleted file mode 100644 index df36f3533a38e..0000000000000 --- a/src/Tools/CompilerBenchmarks/StageBenchmarks.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.IO; -using BenchmarkDotNet.Attributes; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Emit; -using Roslyn.Utilities; -using static Microsoft.CodeAnalysis.Compilation; - -namespace CompilerBenchmarks -{ - public class StageBenchmarks - { - private Compilation _comp; - private CommonPEModuleBuilder _moduleBeingBuilt; - private EmitOptions _options; - private MemoryStream _peStream; - - [Benchmark] - public object Parsing() - { - return Helpers.CreateReproCompilation(); - } - - [GlobalSetup(Target = nameof(CompileMethodsAndEmit))] - public void LoadCompilation() - { - _peStream = new MemoryStream(); - _comp = Helpers.CreateReproCompilation(); - - // Call GetDiagnostics to force declaration symbol binding to finish - _ = _comp.GetDiagnostics(); - } - - [Benchmark] - public object CompileMethodsAndEmit() - { - _peStream.Position = 0; - return _comp.Emit(_peStream); - } - - [GlobalSetup(Target = nameof(SerializeMetadata))] - public void CompileMethods() - { - LoadCompilation(); - - _options = EmitOptions.Default.WithIncludePrivateMembers(true); - - bool embedPdb = _options.DebugInformationFormat == DebugInformationFormat.Embedded; - - var diagnostics = DiagnosticBag.GetInstance(); - - _moduleBeingBuilt = _comp.CheckOptionsAndCreateModuleBuilder( - diagnostics, - manifestResources: null, - _options, - debugEntryPoint: null, - sourceLinkStream: null, - embeddedTexts: null, - testData: null, - cancellationToken: default); - - bool success = false; - - success = _comp.CompileMethods( - _moduleBeingBuilt, - emittingPdb: embedPdb, - emitMetadataOnly: _options.EmitMetadataOnly, - emitTestCoverageData: _options.EmitTestCoverageData, - diagnostics: diagnostics, - filterOpt: null, - cancellationToken: default); - - _comp.GenerateResourcesAndDocumentationComments( - _moduleBeingBuilt, - xmlDocumentationStream: null, - win32ResourcesStream: null, - _options.OutputNameOverride, - diagnostics, - cancellationToken: default); - - _comp.ReportUnusedImports(null, diagnostics, default); - _moduleBeingBuilt.CompilationFinished(); - - diagnostics.Free(); - } - - [Benchmark] - public object SerializeMetadata() - { - var diagnostics = DiagnosticBag.GetInstance(); - - _comp.SerializeToPeStream( - _moduleBeingBuilt, - new SimpleEmitStreamProvider(_peStream), - metadataPEStreamProvider: null, - pdbStreamProvider: null, - testSymWriterFactory: null, - diagnostics, - metadataOnly: _options.EmitMetadataOnly, - includePrivateMembers: _options.IncludePrivateMembers, - emitTestCoverageData: _options.EmitTestCoverageData, - pePdbFilePath: _options.PdbFilePath, - privateKeyOpt: null, - cancellationToken: default); - - diagnostics.Free(); - - return _peStream; - } - } -} diff --git a/src/Tools/CompilerBenchmarks/run-perf.ps1 b/src/Tools/CompilerBenchmarks/run-perf.ps1 deleted file mode 100644 index ab8f4be53b9bf..0000000000000 --- a/src/Tools/CompilerBenchmarks/run-perf.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -# Licensed to the .NET Foundation under one or more agreements. -# The .NET Foundation licenses this file to you under the MIT license. -# See the LICENSE file in the project root for more information. - -[CmdletBinding(PositionalBinding=$false)] -param ( - # By default, the Roslyn dir is expected to be next to this dir - [string]$roslynDir = "$PSScriptRoot/../../.." -) - -Set-Variable -Name LastExitCode 0 -Set-StrictMode -Version 2.0 -$ErrorActionPreference = "Stop" -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 - -try { - . (Join-Path $roslynDir "eng/build-utils.ps1") - - # Download dotnet if it isn't already available - Ensure-DotnetSdk - - $reproPath = Join-Path $ArtifactsDir "CodeAnalysisRepro" - - if (-not (Test-Path $reproPath)) { - $tmpFile = [System.IO.Path]::GetTempFileName() - Invoke-WebRequest -Uri "https://roslyninfra.blob.core.windows.net/perf-artifacts/CodeAnalysisRepro.zip" -UseBasicParsing -OutFile $tmpFile - Unzip $tmpFile $ArtifactsDir - } - - Exec-Command "dotnet" "run -c Release $reproPath" -} -catch { - Write-Host $_ - Write-Host $_.Exception - exit 1 -} From 4f7053245cb8b7d898c2d4af4f2e28f7a44f1962 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Thu, 7 May 2020 11:43:31 -0700 Subject: [PATCH 093/222] Revert "Dummy commit violating build enforced code style rule to test CI failure" This reverts commit 71716fd556552c83a8a948324f7c7180020c29ff. --- src/Workspaces/Core/Portable/CodeActions/CodeAction.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs index b3afcde46c4e0..77aa9283fc823 100644 --- a/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs +++ b/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs @@ -5,7 +5,6 @@ #nullable enable using System; -using System.IO; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; From 9886b8ea9d1868fd9cfd872062c04d0f4747d3a6 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 12:06:45 -0700 Subject: [PATCH 094/222] Add some ToString() methods in core graph types to make debugging easier --- src/Features/Lsif/Generator/Graph/Edge.cs | 5 +++++ src/Features/Lsif/Generator/Graph/Id.cs | 5 +++++ src/Features/Lsif/Generator/Graph/Vertex.cs | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/Features/Lsif/Generator/Graph/Edge.cs b/src/Features/Lsif/Generator/Graph/Edge.cs index d11fb950e1105..893c75296f728 100644 --- a/src/Features/Lsif/Generator/Graph/Edge.cs +++ b/src/Features/Lsif/Generator/Graph/Edge.cs @@ -48,5 +48,10 @@ public static Edge Create(string label, Id ou return new Edge(label, outVertex.As(), inVerticesArray); } + + public override string ToString() + { + return $"{Label} edge from {OutVertex} to {string.Join(", ", InVertices)}"; + } } } diff --git a/src/Features/Lsif/Generator/Graph/Id.cs b/src/Features/Lsif/Generator/Graph/Id.cs index f91e823c9c019..6cb1194b48e3f 100644 --- a/src/Features/Lsif/Generator/Graph/Id.cs +++ b/src/Features/Lsif/Generator/Graph/Id.cs @@ -56,6 +56,11 @@ public override int GetHashCode() { return !(left == right); } + + public override string ToString() + { + return $"{NumericId}"; + } } internal interface ISerializableId diff --git a/src/Features/Lsif/Generator/Graph/Vertex.cs b/src/Features/Lsif/Generator/Graph/Vertex.cs index d28d28465c180..be161b216e4fe 100644 --- a/src/Features/Lsif/Generator/Graph/Vertex.cs +++ b/src/Features/Lsif/Generator/Graph/Vertex.cs @@ -13,5 +13,10 @@ protected Vertex(string label) : base(type: "vertex", label) { } + + public override string ToString() + { + return $"{Label} vertex with ID {Id}"; + } } } From 7a9e34bb3e8a4267b42045fd4d1c1562642e46e2 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 12:35:34 -0700 Subject: [PATCH 095/222] Fix race where we weren't writing LSIF output in the correct order We had a race where we might have one thread trying to use vertices that were still in the process of being written by another thread; adding a lock to the shared LsifJsonWriter addresses this. To make the use more clear InMemoryLsifJsonWriter is now renamed to BatcingLsifJsonWriter and now accepts the underying object once so that way there isn't the potential of misuse of different flushes going to different writers which would once again break rules. Unit tests are now added for the multi-document case which on my machine was sufficient to reproduce the race. --- src/Features/Lsif/Generator/Generator.cs | 8 +- .../Writing/BatchingLsifJsonWriter.cs | 79 +++++++++++++ .../Writing/InMemoryLsifJsonWriter.cs | 39 ------ .../Lsif/GeneratorTest/RangeResultSetTests.vb | 34 ++++++ .../Utilities/TestLsifJsonWriter.vb | 111 ++++++++++-------- .../GeneratorTest/Utilities/TestLsifOutput.vb | 41 ++++--- 6 files changed, 203 insertions(+), 109 deletions(-) create mode 100644 src/Features/Lsif/Generator/Writing/BatchingLsifJsonWriter.cs delete mode 100644 src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 6e758b00e8ed9..a9d8082402dac 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -36,7 +36,7 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // We create a ResultSetTracker to track all top-level symbols in the project. We don't want all writes to immediately go to // the JSON file -- we support parallel processing, so we'll accumulate them and then apply at once to avoid a lot // of contention on shared locks. - var topLevelSymbolsWriter = new InMemoryLsifJsonWriter(); + var topLevelSymbolsWriter = new BatchingLsifJsonWriter(_lsifJsonWriter); var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter, compilation); Parallel.ForEach(compilation.SyntaxTrees, syntaxTree => @@ -49,10 +49,10 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // level symbol result sets made first, since the document contents will point to that. Parallel calls to CopyAndEmpty // are allowed and might flush other unrelated stuff at the same time, but there's no harm -- the "causality" ordering // is preserved. - var documentWriter = new InMemoryLsifJsonWriter(); + var documentWriter = new BatchingLsifJsonWriter(_lsifJsonWriter); var documentId = GenerateForDocument(semanticModel, languageServices, topLevelSymbolsResultSetTracker, documentWriter); - topLevelSymbolsWriter.CopyToAndEmpty(_lsifJsonWriter); - documentWriter.CopyToAndEmpty(_lsifJsonWriter); + topLevelSymbolsWriter.FlushToUnderlyingAndEmpty(); + documentWriter.FlushToUnderlyingAndEmpty(); documentIds.Add(documentId); }); diff --git a/src/Features/Lsif/Generator/Writing/BatchingLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/BatchingLsifJsonWriter.cs new file mode 100644 index 0000000000000..ff7a6b6f62ba6 --- /dev/null +++ b/src/Features/Lsif/Generator/Writing/BatchingLsifJsonWriter.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; + +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing +{ + /// + /// An that lets us batch up a bunch of elements and + /// write them at once. This allows for less contention on shared locks since we can have + /// multiple parallel tasks producing items, and then only at the end contribute items into + /// the final file. + /// + internal sealed class BatchingLsifJsonWriter : ILsifJsonWriter + { + /// + /// A lock that must be held when adding elements to . + /// + private readonly object _elementsGate = new object(); + private List _elements = new List(); + + /// + /// A lock held when writing to ensure that we maintain ordering of elements across multiple threads. + /// + /// + /// The LSIF file format requires that any vertices referenced by an edge must be written before + /// the edges that use that vertex. This creates some complexity because we want to be able to batch + /// writes to the JSON as much as possible to avoid a lot of locking overhead. There's some shared state + /// that we must track for global symbols, like IDs of various reference lists, and for us to add + /// reference to those we need to ensure that shared state is flushed before we can write per-document state. + /// + /// This lock is acquired during the entirety of a call to . That + /// method wants to hold for a short as possible, to allow other threads + /// producing new (unrelated) work to not be blocked behind us writing to the output. But if multiple threads + /// are trying to flush the same thing, only one thread is going to acquire the list of items to flush. + /// However, all threads need to wait until that flushing is complete before they can continue to write + /// to the shared output. By having two locks, this lets us release as soon + /// as we have the list of items, but we can still ensure that all callers to + /// have waited for what they needed done. + /// + private readonly object _writingGate = new object(); + + private readonly ILsifJsonWriter _underlyingWriter; + + public BatchingLsifJsonWriter(ILsifJsonWriter underlyingWriter) + { + _underlyingWriter = underlyingWriter; + } + + public void Write(Element element) + { + lock (_elementsGate) + { + _elements.Add(element); + } + } + + public void FlushToUnderlyingAndEmpty() + { + lock (_writingGate) + { + List localElements; + + lock (_elementsGate) + { + localElements = _elements; + _elements = new List(); + } + + foreach (var element in localElements) + { + _underlyingWriter.Write(element); + } + } + } + } +} diff --git a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs deleted file mode 100644 index 2af0ed7fc9ac9..0000000000000 --- a/src/Features/Lsif/Generator/Writing/InMemoryLsifJsonWriter.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph; - -namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing -{ - internal sealed class InMemoryLsifJsonWriter : ILsifJsonWriter - { - private readonly object _gate = new object(); - private List _elements = new List(); - - public void Write(Element element) - { - lock (_gate) - { - _elements.Add(element); - } - } - - public void CopyToAndEmpty(ILsifJsonWriter writer) - { - List localElements; - - lock (_gate) - { - localElements = _elements; - _elements = new List(); - } - - foreach (var element in localElements) - { - writer.Write(element); - } - } - } -} diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb index 9c0810f141c5e..f6bba949f896f 100644 --- a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -77,5 +77,39 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Dim referencedRange = Assert.Single(lsif.GetLinkedVertices(Of Graph.Range)(referencesVertex, "item")) Assert.Same(rangeVertex, referencedRange) End Sub + + + Public Async Sub ReferenceIncludedInSameReferenceResultForMultipleFilesAsync() + Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + FilePath="Z:\TestProject.csproj" CommonReferences="true"> + + class A { [|string|] s; } + + + class B { [|string|] s; } + + + class C { [|string|] s; } + + + class D { [|string|] s; } + + + class E { [|string|] s; } + + + )) + + For Each rangeVertex In Await lsif.GetSelectedRangesAsync() + Dim resultSetVertex = lsif.GetLinkedVertices(Of Graph.ResultSet)(rangeVertex, "next").Single() + Dim referencesVertex = lsif.GetLinkedVertices(Of Graph.ReferenceResult)(resultSetVertex, Methods.TextDocumentReferencesName).Single() + + ' The references vertex should point back to our range + Dim referencedRanges = lsif.GetLinkedVertices(Of Graph.Range)(referencesVertex, "item") + Assert.Contains(rangeVertex, referencedRanges) + Next + End Sub End Class End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb index c51ee056c129c..b89436583432b 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifJsonWriter.vb @@ -14,80 +14,89 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U Friend Class TestLsifJsonWriter Implements ILsifJsonWriter + Private ReadOnly _gate As Object = New Object() Private ReadOnly _elementsById As Dictionary(Of Id(Of Element), Element) = New Dictionary(Of Id(Of Element), Element) Private ReadOnly _edgesByOutVertex As Dictionary(Of Vertex, List(Of Edge)) = New Dictionary(Of Vertex, List(Of Edge)) Private Sub ILsifJsonWriter_Write(element As Element) Implements ILsifJsonWriter.Write - ' We intentionally use Add so it'll throw if we have a duplicate ID. - _elementsById.Add(element.Id, element) - - Dim edge = TryCast(element, Edge) - - If edge IsNot Nothing Then - ' Fetch all the out And in vertices, which validates they exist. This ensures we satisfy the rule - ' that an edge can only be written after all the vertices it writes to already exist. - Dim outVertex = GetElementById(edge.OutVertex) - - For Each inVertexId In edge.InVertices - ' We are ignoring the return, but this call implicitly validates the element - ' exists and is of the correct type. - GetElementById(inVertexId) - Next - - ' Record the edge in a map of edges exiting this outVertex. We could do a nested Dictionary - ' for this but that seems a bit expensive when many nodes may only have one item. - Dim edgesForOutVertex As List(Of Edge) = Nothing - If Not _edgesByOutVertex.TryGetValue(outVertex, edgesForOutVertex) Then - edgesForOutVertex = New List(Of Edge)(capacity:=1) - _edgesByOutVertex.Add(outVertex, edgesForOutVertex) - End If + SyncLock _gate + ' We intentionally use Add so it'll throw if we have a duplicate ID. + _elementsById.Add(element.Id, element) + + Dim edge = TryCast(element, Edge) + + If edge IsNot Nothing Then + ' Fetch all the out And in vertices, which validates they exist. This ensures we satisfy the rule + ' that an edge can only be written after all the vertices it writes to already exist. + Dim outVertex = GetElementById(edge.OutVertex) + + For Each inVertexId In edge.InVertices + ' We are ignoring the return, but this call implicitly validates the element + ' exists and is of the correct type. + GetElementById(inVertexId) + Next + + ' Record the edge in a map of edges exiting this outVertex. We could do a nested Dictionary + ' for this but that seems a bit expensive when many nodes may only have one item. + Dim edgesForOutVertex As List(Of Edge) = Nothing + If Not _edgesByOutVertex.TryGetValue(outVertex, edgesForOutVertex) Then + edgesForOutVertex = New List(Of Edge)(capacity:=1) + _edgesByOutVertex.Add(outVertex, edgesForOutVertex) + End If - ' It's possible to have more than one item edge, but for anything else we really only expect one. - If edge.Label <> "item" Then - If (edgesForOutVertex.Any(Function(e) e.Label = edge.Label)) Then - Throw New InvalidOperationException($"The outVertex {outVertex} already has an edge with label {edge.Label}.") + ' It's possible to have more than one item edge, but for anything else we really only expect one. + If edge.Label <> "item" Then + If (edgesForOutVertex.Any(Function(e) e.Label = edge.Label)) Then + Throw New InvalidOperationException($"The outVertex {outVertex} already has an edge with label {edge.Label}.") + End If End If - End If - edgesForOutVertex.Add(edge) - End If + edgesForOutVertex.Add(edge) + End If + End SyncLock End Sub ''' ''' Returns all the vertices linked to the given vertex by the edge type. ''' Public Function GetLinkedVertices(Of T As Vertex)(vertex As Graph.Vertex, edgeLabel As String) As ImmutableArray(Of T) - Dim builder = ImmutableArray.CreateBuilder(Of T) - - Dim edges As List(Of Edge) = Nothing - If _edgesByOutVertex.TryGetValue(vertex, edges) Then - Dim inVerticesId = edges.Where(Function(e) e.Label = edgeLabel).SelectMany(Function(e) e.InVertices) - - For Each inVertexId In inVerticesId - ' This is an unsafe "cast" if you will converting the ID to the expected type; - ' GetElementById checks the real vertex type so thta will stay safe in the end. - builder.Add(GetElementById(Of T)(New Id(Of T)(inVertexId.NumericId))) - Next - End If + SyncLock _gate + Dim builder = ImmutableArray.CreateBuilder(Of T) + + Dim edges As List(Of Edge) = Nothing + If _edgesByOutVertex.TryGetValue(vertex, edges) Then + Dim inVerticesId = edges.Where(Function(e) e.Label = edgeLabel).SelectMany(Function(e) e.InVertices) + + For Each inVertexId In inVerticesId + ' This is an unsafe "cast" if you will converting the ID to the expected type; + ' GetElementById checks the real vertex type so thta will stay safe in the end. + builder.Add(GetElementById(Of T)(New Id(Of T)(inVertexId.NumericId))) + Next + End If - Return builder.ToImmutable() + Return builder.ToImmutable() + End SyncLock End Function - Public ReadOnly Property Vertices As IEnumerable(Of Vertex) + Public ReadOnly Property Vertices As ImmutableArray(Of Vertex) Get - Return _elementsById.Values.OfType(Of Vertex) + SyncLock _gate + Return _elementsById.Values.OfType(Of Vertex).ToImmutableArray() + End SyncLock End Get End Property Public Function GetElementById(Of T As Element)(id As Id(Of T)) As T - Dim element As Element = Nothing + SyncLock _gate + Dim element As Element = Nothing - ' TODO: why am I unable to use the extension method As here? - If Not _elementsById.TryGetValue(New Id(Of Element)(id.NumericId), element) Then - Throw New Exception($"Element with ID {id} could not be found.") - End If + ' TODO: why am I unable to use the extension method As here? + If Not _elementsById.TryGetValue(New Id(Of Element)(id.NumericId), element) Then + Throw New Exception($"Element {id} could not be found.") + End If - Return Assert.IsAssignableFrom(Of T)(element) + Return Assert.IsAssignableFrom(Of T)(element) + End SyncLock End Function End Class End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index b5e59b28d54ad..a16a8d2a2169d 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -46,23 +46,34 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U End Property ''' - ''' Returns the vertex in the output that corresponds to the selected range in the . + ''' Returns the verticies in the output that corresponds to the selected range in the . ''' + Public Async Function GetSelectedRangesAsync() As Task(Of IEnumerable(Of Graph.Range)) + Dim builder = ImmutableArray.CreateBuilder(Of Range) + + For Each testDocument In _workspace.Documents + Dim documentVertex = _testLsifJsonWriter.Vertices _ + .OfType(Of Graph.Document) _ + .Where(Function(d) d.Uri.LocalPath = testDocument.FilePath) _ + .Single() + Dim rangeVertices = GetLinkedVertices(Of Range)(documentVertex, "contains") + + + For Each selectedSpan In testDocument.SelectedSpans + Dim document = _workspace.CurrentSolution.GetDocument(testDocument.Id) + Dim selectionRange = Range.FromTextSpan(selectedSpan, Await document.GetTextAsync()) + + builder.Add(rangeVertices.Where(Function(r) r.Start = selectionRange.Start AndAlso + r.End = selectionRange.End) _ + .Single()) + Next + Next + + Return builder.ToImmutable() + End Function + Public Async Function GetSelectedRangeAsync() As Task(Of Graph.Range) - Dim selectedTestDocument = _workspace.Documents.Single(Function(d) d.SelectedSpans.Any()) - Dim selectedDocument = _workspace.CurrentSolution.GetDocument(selectedTestDocument.Id) - Dim selectionTextSpan = selectedTestDocument.SelectedSpans.Single() - Dim selectionRange = Range.FromTextSpan(selectionTextSpan, Await selectedDocument.GetTextAsync()) - - Dim documentVertex = _testLsifJsonWriter.Vertices _ - .OfType(Of Graph.Document) _ - .Where(Function(d) d.Uri.LocalPath = selectedDocument.FilePath) _ - .Single() - - Return _testLsifJsonWriter.GetLinkedVertices(Of Range)(documentVertex, "contains") _ - .Where(Function(r) r.Start = selectionRange.Start AndAlso - r.End = selectionRange.End) _ - .Single() + Return (Await GetSelectedRangesAsync()).Single() End Function End Class End Namespace From c532d5343760be0d4ba52cf0d34865327a7b9d87 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 14:36:32 -0700 Subject: [PATCH 096/222] Switch to Environment.NewLine --- src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs index 4724caae0acdc..d44f8e38dbf71 100644 --- a/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs @@ -41,7 +41,7 @@ public void Write(Element element) lock (_writeGate) { _jsonSerializer.Serialize(_jsonTextWriter, element); - _jsonTextWriter.WriteWhitespace("\r\n"); + _jsonTextWriter.WriteWhitespace(Environment.NewLine); } } From e9fbdf5cdc03adb4c452df04aaaa7a57c30cb2bb Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 7 May 2020 14:48:50 -0700 Subject: [PATCH 097/222] Add NonCopyableAttribute --- .../InternalUtilities/NonCopyableAttribute.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Compilers/Core/Portable/InternalUtilities/NonCopyableAttribute.cs diff --git a/src/Compilers/Core/Portable/InternalUtilities/NonCopyableAttribute.cs b/src/Compilers/Core/Portable/InternalUtilities/NonCopyableAttribute.cs new file mode 100644 index 0000000000000..9a5e05fb875a6 --- /dev/null +++ b/src/Compilers/Core/Portable/InternalUtilities/NonCopyableAttribute.cs @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Roslyn.Utilities +{ + [AttributeUsage(AttributeTargets.Struct | AttributeTargets.GenericParameter)] + internal sealed class NonCopyableAttribute : Attribute + { + } +} From 43980bc6ca6075fbd00a185c452ed80ef18b83ad Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 14:59:01 -0700 Subject: [PATCH 098/222] Add some more comments explaining why some methods exist --- src/Features/Lsif/Generator/CompilerInvocation.cs | 11 +++++++++++ src/Features/Lsif/Generator/Generator.cs | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Features/Lsif/Generator/CompilerInvocation.cs b/src/Features/Lsif/Generator/CompilerInvocation.cs index b0ea66156daea..0290240144143 100644 --- a/src/Features/Lsif/Generator/CompilerInvocation.cs +++ b/src/Features/Lsif/Generator/CompilerInvocation.cs @@ -123,6 +123,17 @@ private static string GetLanguageName(CompilerInvocationInfo invocationInfo) /// /// Given the JSON description, returns a function that will map paths from the original paths to the current paths. /// + /// + /// The compiler invocation JSON input is allowed to specify a map of file paths. The scenario here is to allow us to + /// do LSIF indexing on another machine than an original build might have been done on. For example, say the main build process + /// for a repository has the source synchronized to the S:\source1, but we want to do analysis on a different machine which has + /// the source in a folder S:\source2. If we have the original compilation command line when it was built under S:\source1, and + /// know that any time we see S:\source1 we should actually read the file out of S:\source2, then we analyze on a separate machine. + /// + /// This is used to enable some internal-to-Microsoft build environments which have a mechanism to run "analysis" passes like + /// the LSIF tool independent from the main build machines, and can restore source and build artifacts to provide the environment + /// that is close enough to match the original. + /// private static Func GetPathMapper(CompilerInvocationInfo invocationInfo) { return unmappedPath => diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index a9d8082402dac..8401d7e7516bd 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -62,6 +62,17 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); } + /// + /// Generates the LSIF content for a single document. + /// + /// The ID of the outputted Document vertex. + /// + /// The high level algorithm here is we are going to walk across each token, produce a for that token's span, + /// bind that token, and then link up the various features. So we'll link that range to the symbols it defines or references, + /// will link it to results like Quick Info, and more. This method has a that + /// lets us link symbols across files, and will only talk about "top level" symbols that aren't things like locals that can't + /// leak outside a file. + /// private static Id GenerateForDocument( SemanticModel semanticModel, HostLanguageServices languageServices, From 7368206cc1cb1c93375d5225706618e9732e1c80 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 15:08:44 -0700 Subject: [PATCH 099/222] Add more comments describing the various nodes --- src/Features/Lsif/Generator/Graph/DefinitionResult.cs | 3 +++ src/Features/Lsif/Generator/Graph/Document.cs | 3 +++ src/Features/Lsif/Generator/Graph/Event.cs | 2 +- src/Features/Lsif/Generator/Graph/Id.cs | 4 ++-- src/Features/Lsif/Generator/Graph/Range.cs | 3 +++ src/Features/Lsif/Generator/Graph/ReferenceResult.cs | 3 +++ src/Features/Lsif/Generator/Graph/ResultSet.cs | 2 +- src/Features/Lsif/Generator/Graph/Vertex.cs | 2 +- 8 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/Features/Lsif/Generator/Graph/DefinitionResult.cs b/src/Features/Lsif/Generator/Graph/DefinitionResult.cs index f85c5fbd2b683..a2c536371a34f 100644 --- a/src/Features/Lsif/Generator/Graph/DefinitionResult.cs +++ b/src/Features/Lsif/Generator/Graph/DefinitionResult.cs @@ -4,6 +4,9 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { + /// + /// Represents a definitionResult vertex for serialization. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#request-textdocumentdefinition for further details. + /// internal sealed class DefinitionResult : Vertex { public DefinitionResult() diff --git a/src/Features/Lsif/Generator/Graph/Document.cs b/src/Features/Lsif/Generator/Graph/Document.cs index 9a0274534e5bd..93f00a4187ccc 100644 --- a/src/Features/Lsif/Generator/Graph/Document.cs +++ b/src/Features/Lsif/Generator/Graph/Document.cs @@ -6,6 +6,9 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { + /// + /// Represents the document vertex that contains all the s. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#ranges for examples. + /// internal sealed class Document : Vertex { public Uri Uri { get; } diff --git a/src/Features/Lsif/Generator/Graph/Event.cs b/src/Features/Lsif/Generator/Graph/Event.cs index de1e669c59cd5..184b3ec7b8037 100644 --- a/src/Features/Lsif/Generator/Graph/Event.cs +++ b/src/Features/Lsif/Generator/Graph/Event.cs @@ -7,7 +7,7 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// - /// Represents an event. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#events for further details. + /// Represents an event vertex for serialization. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#events for further details. /// internal sealed class Event : Vertex { diff --git a/src/Features/Lsif/Generator/Graph/Id.cs b/src/Features/Lsif/Generator/Graph/Id.cs index 6cb1194b48e3f..d7c990aa0b9dc 100644 --- a/src/Features/Lsif/Generator/Graph/Id.cs +++ b/src/Features/Lsif/Generator/Graph/Id.cs @@ -10,8 +10,8 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph /// /// Represents an ID of a vertex or edge. /// - /// Used to distinguish what type of object this ID applies to. This is not actually used, but simply helps - /// to ensure type safety since it's not uncommon to hold onto just an ID somewhere. + /// Used to distinguish what type of object this ID applies to. This is dropped in serialization, but simply helps + /// to ensure type safety in the code so we don't cross IDs of different types. internal struct Id : IEquatable>, ISerializableId where T : Element { /// diff --git a/src/Features/Lsif/Generator/Graph/Range.cs b/src/Features/Lsif/Generator/Graph/Range.cs index 6696662873af5..d371f99c4361f 100644 --- a/src/Features/Lsif/Generator/Graph/Range.cs +++ b/src/Features/Lsif/Generator/Graph/Range.cs @@ -7,6 +7,9 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { + /// + /// Represents a Range for serialization. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#ranges for further details. + /// internal sealed class Range : Vertex { public Position Start { get; } diff --git a/src/Features/Lsif/Generator/Graph/ReferenceResult.cs b/src/Features/Lsif/Generator/Graph/ReferenceResult.cs index a0fe200f9f18a..935783cbac108 100644 --- a/src/Features/Lsif/Generator/Graph/ReferenceResult.cs +++ b/src/Features/Lsif/Generator/Graph/ReferenceResult.cs @@ -4,6 +4,9 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { + /// + /// Represents a referenceResult vertex for serialization. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#request-textdocumentreferences for further details. + /// internal sealed class ReferenceResult : Vertex { public ReferenceResult() diff --git a/src/Features/Lsif/Generator/Graph/ResultSet.cs b/src/Features/Lsif/Generator/Graph/ResultSet.cs index 63e5a80ef7396..85f177908abe0 100644 --- a/src/Features/Lsif/Generator/Graph/ResultSet.cs +++ b/src/Features/Lsif/Generator/Graph/ResultSet.cs @@ -5,7 +5,7 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// - /// Represents a single ResultSet in the LSIF file. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set for further details. + /// Represents a single ResultSet for serialization. See https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set for further details. /// internal sealed class ResultSet : Vertex { diff --git a/src/Features/Lsif/Generator/Graph/Vertex.cs b/src/Features/Lsif/Generator/Graph/Vertex.cs index be161b216e4fe..a2f593c751505 100644 --- a/src/Features/Lsif/Generator/Graph/Vertex.cs +++ b/src/Features/Lsif/Generator/Graph/Vertex.cs @@ -5,7 +5,7 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { /// - /// The base class of any vertex in the graph. + /// The base class of any vertex in the graph that we serialize. /// internal abstract class Vertex : Element { From 0de86757373dd1ce905abc954ab1dfff0a98907b Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 15:14:13 -0700 Subject: [PATCH 100/222] Remove unnecessary blank lines --- src/Features/Lsif/Generator/Writing/LsifConverter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Features/Lsif/Generator/Writing/LsifConverter.cs b/src/Features/Lsif/Generator/Writing/LsifConverter.cs index f4b23caa37385..02904571b842b 100644 --- a/src/Features/Lsif/Generator/Writing/LsifConverter.cs +++ b/src/Features/Lsif/Generator/Writing/LsifConverter.cs @@ -26,17 +26,14 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s switch (value) { case ISerializableId id: - writer.WriteValue(id.NumericId); break; case Uri uri: - writer.WriteValue(uri.AbsoluteUri); break; default: - throw new NotSupportedException(); } } From 1646305a710fe712a67b2a972f168046251db98f Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Thu, 7 May 2020 15:52:56 -0700 Subject: [PATCH 101/222] Fix --- .../IdeBenchmarks/MemoryDiagnoserConfig.cs | 2 +- .../CSharpIdeAnalyzerBenchmarks.cs | 1 - .../IdeCoreBenchmarks.csproj | 9 +++- src/Tools/IdeCoreBenchmarks/Program.cs | 15 ++++++ .../SerializationBenchmarks.cs | 47 +++++++++++++++++++ 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs diff --git a/src/Tools/IdeBenchmarks/MemoryDiagnoserConfig.cs b/src/Tools/IdeBenchmarks/MemoryDiagnoserConfig.cs index ff316e9b39ac3..18cd4d3f96885 100644 --- a/src/Tools/IdeBenchmarks/MemoryDiagnoserConfig.cs +++ b/src/Tools/IdeBenchmarks/MemoryDiagnoserConfig.cs @@ -11,7 +11,7 @@ public class MemoryDiagnoserConfig : ManualConfig { public MemoryDiagnoserConfig() { - Add(MemoryDiagnoser.Default); + AddDiagnoser(MemoryDiagnoser.Default); } } } diff --git a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs index e2b95957e3c70..b79a94ed04858 100644 --- a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs +++ b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs @@ -76,6 +76,5 @@ public async Task RunAnalyzer() { await _runner.RunAsync(CancellationToken.None).ConfigureAwait(false); } - } } diff --git a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj index fee524b7fdf3a..4abf326151442 100644 --- a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj +++ b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj @@ -5,14 +5,21 @@ Exe - netcoreapp3.1;net472 + net472;netcoreapp3.1 false AnyCPU + + true + + + + + diff --git a/src/Tools/IdeCoreBenchmarks/Program.cs b/src/Tools/IdeCoreBenchmarks/Program.cs index 0fb1960efed35..915b01334c9b1 100644 --- a/src/Tools/IdeCoreBenchmarks/Program.cs +++ b/src/Tools/IdeCoreBenchmarks/Program.cs @@ -5,20 +5,35 @@ using System; using System.Collections.Immutable; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using AnalyzerRunner; using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Running; +using BenchmarkDotNet.Validators; using Microsoft.CodeAnalysis.MSBuild; namespace IdeCoreBenchmarks { internal class Program { + private class IgnoreReleaseOnly : ManualConfig + { + public IgnoreReleaseOnly() + { + AddValidator(JitOptimizationsValidator.DontFailOnError); + AddLogger(DefaultConfig.Instance.GetLoggers().ToArray()); + AddExporter(DefaultConfig.Instance.GetExporters().ToArray()); + AddColumnProvider(DefaultConfig.Instance.GetColumnProviders().ToArray()); + AddDiagnoser(MemoryDiagnoser.Default); + } + } + public const string RoslynRootPathEnvVariableName = "ROSLYN_SOURCE_ROOT_PATH"; public static string GetRoslynRootLocation([CallerFilePath] string sourceFilePath = "") diff --git a/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs new file mode 100644 index 0000000000000..d0b44de82e81a --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.IO; +using BenchmarkDotNet.Attributes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace IdeCoreBenchmarks +{ + [MemoryDiagnoser] + public class SerializationBenchmarks + { + private CompilationUnitSyntax _root; + + [GlobalSetup] + public void GlobalSetup() + { + var roslynRoot = Environment.GetEnvironmentVariable(Program.RoslynRootPathEnvVariableName); + var csFilePath = Path.Combine(roslynRoot, @"src\Compilers\CSharp\Portable\Generated\Syntax.xml.Syntax.Generated.cs"); + + if (!File.Exists(csFilePath)) + { + throw new ArgumentException(); + } + + var text = File.ReadAllText(csFilePath); + var tree = SyntaxFactory.ParseSyntaxTree(text); + _root = tree.GetCompilationUnitRoot(); + } + + [Benchmark] + public void RoundTripSyntaxNode() + { + var stream = new MemoryStream(); + _root.SerializeTo(stream); + + stream.Position = 0; + + var droot = CSharpSyntaxNode.DeserializeFrom(stream); + var nodes = droot.DescendantNodesAndSelf().ToImmutableArray(); + } + } +} From e7332499f59e5adcd003096cd26ec56af348fd77 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 7 May 2020 16:10:07 -0700 Subject: [PATCH 102/222] Update to roslyn-analyzers 3.3.0-beta1.20257.5 --- eng/Versions.props | 2 +- eng/config/rulesets/NonShipping.ruleset | 3 +++ eng/config/rulesets/Shipping.ruleset | 9 +++++++++ ...odeStyleHostLanguageServices.MefHostExportProvider.cs | 1 + .../Workspace/Core/Workspace/Mef/MefWorkspaceServices.cs | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index d9bdd3af440f3..183852665ebdc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -27,7 +27,7 @@ - 3.0.0-beta2.20169.3 + 3.3.0-beta1.20257.5 3.6.0-2.final 1.0.1-beta1.20210.2 3.7.0-1.20210.7 diff --git a/eng/config/rulesets/NonShipping.ruleset b/eng/config/rulesets/NonShipping.ruleset index 88a8f77500f62..06c77b66519f9 100644 --- a/eng/config/rulesets/NonShipping.ruleset +++ b/eng/config/rulesets/NonShipping.ruleset @@ -43,6 +43,9 @@ + + + diff --git a/eng/config/rulesets/Shipping.ruleset b/eng/config/rulesets/Shipping.ruleset index d7a208dea46da..6ad2ce784371c 100644 --- a/eng/config/rulesets/Shipping.ruleset +++ b/eng/config/rulesets/Shipping.ruleset @@ -35,6 +35,7 @@ + @@ -55,8 +56,11 @@ + + + @@ -68,6 +72,7 @@ + @@ -110,6 +115,10 @@ + + + + diff --git a/src/CodeStyle/Core/CodeFixes/Host/Mef/CodeStyleHostLanguageServices.MefHostExportProvider.cs b/src/CodeStyle/Core/CodeFixes/Host/Mef/CodeStyleHostLanguageServices.MefHostExportProvider.cs index 048eb961da134..820bc0133cc1f 100644 --- a/src/CodeStyle/Core/CodeFixes/Host/Mef/CodeStyleHostLanguageServices.MefHostExportProvider.cs +++ b/src/CodeStyle/Core/CodeFixes/Host/Mef/CodeStyleHostLanguageServices.MefHostExportProvider.cs @@ -20,6 +20,7 @@ internal sealed partial class CodeStyleHostLanguageServices : HostLanguageServic private readonly HostLanguageServices _hostLanguageServices; private readonly HostLanguageServices _codeStyleLanguageServices; + [SuppressMessage("ApiDesign", "RS0030:Do not used banned APIs", Justification = "This is the replacement API")] private CodeStyleHostLanguageServices(HostLanguageServices hostLanguageServices) { _hostLanguageServices = hostLanguageServices; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Workspace/Mef/MefWorkspaceServices.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Workspace/Mef/MefWorkspaceServices.cs index f9304713a87c5..d24777881c52a 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Workspace/Mef/MefWorkspaceServices.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Workspace/Mef/MefWorkspaceServices.cs @@ -164,7 +164,9 @@ public override IEnumerable FindLanguageServices Date: Thu, 7 May 2020 16:23:30 -0700 Subject: [PATCH 103/222] Address feedback --- eng/build.ps1 | 4 ++-- eng/build.sh | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/eng/build.ps1 b/eng/build.ps1 index cf24f002759fb..03864e6c1ddd5 100644 --- a/eng/build.ps1 +++ b/eng/build.ps1 @@ -37,7 +37,7 @@ param ( [switch]$buildServerLog, [switch]$ci, [switch]$procdump, - [switch]$runAnalyzers, + [switch][Alias('a')]$runAnalyzers, [switch][Alias('d')]$deployExtensions, [switch]$prepareMachine, [switch]$useGlobalNuGetCache = $true, @@ -97,7 +97,7 @@ function Print-Usage() { Write-Host " -bootstrapConfiguration Build configuration for bootstrap compiler: 'Debug' or 'Release'" Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." Write-Host " -procdump Monitor test runs with procdump" - Write-Host " -runAnalyzers Run analyzers during build operations" + Write-Host " -runAnalyzers Run analyzers during build operations (short: -a)" Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" Write-Host " -useGlobalNuGetCache Use global NuGet cache." Write-Host " -warnAsError Treat all warnings as errors" diff --git a/eng/build.sh b/eng/build.sh index c8dbf5ea290d6..4369538d5c03e 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -64,7 +64,7 @@ verbosity='minimal' binary_log=false ci=false bootstrap=false -skip_analyzers=false +run_analyzers=false prepare_machine=false warn_as_error=false properties="" @@ -129,8 +129,8 @@ while [[ $# > 0 ]]; do # Bootstrap requires restore restore=true ;; - --skipanalyzers) - skip_analyzers=true + --runAnalyzers) + run_analyzers=true ;; --preparemachine) prepare_machine=true @@ -224,10 +224,9 @@ function BuildSolution { local projects="$repo_root/$solution" # https://github.com/dotnet/roslyn/issues/23736 - local enable_analyzers=!$skip_analyzers UNAME="$(uname)" if [[ "$UNAME" == "Darwin" ]]; then - enable_analyzers=false + run_analyzers=false fi # NuGet often exceeds the limit of open files on Mac and Linux @@ -273,7 +272,7 @@ function BuildSolution { /p:Test=$test \ /p:Pack=$pack \ /p:Publish=$publish \ - /p:UseRoslynAnalyzers=$enable_analyzers \ + /p:UseRoslynAnalyzers=$run_analyzers \ /p:BootstrapBuildPath="$bootstrap_dir" \ /p:ContinuousIntegrationBuild=$ci \ /p:TreatWarningsAsErrors=true \ From 6d9567b2e928eb07d1d7b116f2d1a020661ed9ca Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 7 May 2020 16:28:51 -0700 Subject: [PATCH 104/222] Enable non-copyable value analysis --- eng/config/rulesets/Shipping.ruleset | 1 - src/Test/PdbUtilities/Shared/DummyMetadataImport.cs | 2 ++ .../TestUtilities2/CodeModel/CodeModelTestHelpers.vb | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/eng/config/rulesets/Shipping.ruleset b/eng/config/rulesets/Shipping.ruleset index 6ad2ce784371c..161ff6f8744d9 100644 --- a/eng/config/rulesets/Shipping.ruleset +++ b/eng/config/rulesets/Shipping.ruleset @@ -115,7 +115,6 @@ - diff --git a/src/Test/PdbUtilities/Shared/DummyMetadataImport.cs b/src/Test/PdbUtilities/Shared/DummyMetadataImport.cs index 88d1ea6d2551e..e5e8da2fdac0a 100644 --- a/src/Test/PdbUtilities/Shared/DummyMetadataImport.cs +++ b/src/Test/PdbUtilities/Shared/DummyMetadataImport.cs @@ -66,7 +66,9 @@ public unsafe int GetSigFromToken( ppvSig = (byte*)pinnedBuffer.AddrOfPinnedObject(); pcbSig = signature.Length; +#pragma warning disable RS0042 // Do not copy value _pinnedBuffers.Add(pinnedBuffer); +#pragma warning restore RS0042 // Do not copy value return 0; } diff --git a/src/VisualStudio/TestUtilities2/CodeModel/CodeModelTestHelpers.vb b/src/VisualStudio/TestUtilities2/CodeModel/CodeModelTestHelpers.vb index 33a7669f47447..e1b44559b21de 100644 --- a/src/VisualStudio/TestUtilities2/CodeModel/CodeModelTestHelpers.vb +++ b/src/VisualStudio/TestUtilities2/CodeModel/CodeModelTestHelpers.vb @@ -128,7 +128,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.CodeModel Dim handle = GCHandle.Alloc(managedObject, GCHandleType.Normal) Dim freeHandle = True Try +#Disable Warning RS0042 ' Do not copy value BlindAggregatorFactory.SetInnerObject(wrapperUnknown, innerUnknown, GCHandle.ToIntPtr(handle)) +#Enable Warning RS0042 ' Do not copy value freeHandle = False Finally If freeHandle Then handle.Free() From 913bbd567ea278b3e156d4a074955e5e64a784da Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Thu, 7 May 2020 16:43:10 -0700 Subject: [PATCH 105/222] Add IDE incremental analyzer benchmark --- .../IncrementalAnalyzerRunner.cs | 1 + .../CSharpIdeAnalyzerBenchmarks.cs | 15 ++-- .../IncrementalAnalyzerBenchmarks.cs | 80 +++++++++++++++++++ 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs diff --git a/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs b/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs index 130742fadb3ea..f038106868594 100644 --- a/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs +++ b/src/Tools/AnalyzerRunner/IncrementalAnalyzerRunner.cs @@ -65,6 +65,7 @@ public async Task RunAsync(CancellationToken cancellationToken) { var incrementalAnalyzerProvider = incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).SingleOrDefault(provider => provider.Metadata.WorkspaceKinds?.Contains(_workspace.Kind) ?? false)?.Value; incrementalAnalyzerProvider ??= incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).SingleOrDefault(provider => provider.Metadata.WorkspaceKinds?.Contains(WorkspaceKind.Host) ?? false)?.Value; + incrementalAnalyzerProvider ??= incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).SingleOrDefault(provider => provider.Metadata.WorkspaceKinds?.Contains(WorkspaceKind.RemoteWorkspace) ?? false)?.Value; incrementalAnalyzerProvider ??= incrementalAnalyzerProviders.Where(x => x.Metadata.Name == incrementalAnalyzerName).Single(provider => provider.Metadata.WorkspaceKinds is null).Value; var incrementalAnalyzer = incrementalAnalyzerProvider.CreateIncrementalAnalyzer(_workspace); solutionCrawlerRegistrationService.WaitUntilCompletion_ForTestingPurposesOnly(_workspace, ImmutableArray.Create(incrementalAnalyzer)); diff --git a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs index b79a94ed04858..bc42291886ff9 100644 --- a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs +++ b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs @@ -16,7 +16,6 @@ namespace IdeCoreBenchmarks { [MemoryDiagnoser] - [LegacyJitX64Job] [RyuJitX64Job] public class CSharpIdeAnalyzerBenchmarks { @@ -24,8 +23,8 @@ public class CSharpIdeAnalyzerBenchmarks private Options _options; private MSBuildWorkspace _workspace; - private DiagnosticAnalyzerRunner _runner; - private string _analyzerAssemblyPath; + + private DiagnosticAnalyzerRunner _diagnosticAnalyzerRunner; [Params("CSharpAddBracesDiagnosticAnalyzer")] public string AnalyzerName { get; set; } @@ -39,15 +38,15 @@ public CSharpIdeAnalyzerBenchmarks() { throw new ArgumentException(); } - - _analyzerAssemblyPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Microsoft.CodeAnalysis.CSharp.Features.dll"); } [GlobalSetup] public void Setup() { + var analyzerAssemblyPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Microsoft.CodeAnalysis.CSharp.Features.dll"); + _options = new Options( - analyzerPath: _analyzerAssemblyPath, + analyzerPath: analyzerAssemblyPath, solutionPath: _solutionPath, analyzerIds: ImmutableHashSet.Create(AnalyzerName), refactoringNodes: ImmutableHashSet.Empty, @@ -61,7 +60,7 @@ public void Setup() incrementalAnalyzerNames: ImmutableArray.Empty); _workspace = AnalyzerRunnerHelper.LoadSolutionAsync(_solutionPath, CancellationToken.None).Result; - _runner = new DiagnosticAnalyzerRunner(_workspace.CurrentSolution, _options); + _diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(_workspace.CurrentSolution, _options); } [GlobalCleanup] @@ -74,7 +73,7 @@ public void Cleanup() [Benchmark] public async Task RunAnalyzer() { - await _runner.RunAsync(CancellationToken.None).ConfigureAwait(false); + await _diagnosticAnalyzerRunner.RunAsync(CancellationToken.None).ConfigureAwait(false); } } } diff --git a/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs new file mode 100644 index 0000000000000..f57f931c2a449 --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.IO; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using AnalyzerRunner; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Diagnosers; +using Microsoft.CodeAnalysis.MSBuild; + +namespace IdeCoreBenchmarks +{ + [MemoryDiagnoser] + [RyuJitX64Job] + public class IncrementalAnalyzerBenchmarks + { + private readonly string _solutionPath; + + private Options _options; + private MSBuildWorkspace _workspace; + + private IncrementalAnalyzerRunner _incrementalAnalyzerRunner; + + [Params("SymbolTreeInfoIncrementalAnalyzerProvider", "SyntaxTreeInfoIncrementalAnalyzerProvider")] + public string AnalyzerName { get; set; } + + public IncrementalAnalyzerBenchmarks() + { + var roslynRoot = Environment.GetEnvironmentVariable(Program.RoslynRootPathEnvVariableName); + _solutionPath = Path.Combine(roslynRoot, @"src\Tools\IdeCoreBenchmarks\Assets\Microsoft.CodeAnalysis.sln"); + + if (!File.Exists(_solutionPath)) + { + throw new ArgumentException(); + } + } + + [IterationSetup] + public void Setup() + { + var analyzerAssemblyPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Microsoft.CodeAnalysis.Features.dll"); + + _options = new Options( + analyzerPath: analyzerAssemblyPath, + solutionPath: _solutionPath, + analyzerIds: ImmutableHashSet.Empty, + refactoringNodes: ImmutableHashSet.Empty, + runConcurrent: true, + reportSuppressedDiagnostics: true, + applyChanges: false, + useAll: false, + iterations: 1, + usePersistentStorage: false, + fullSolutionAnalysis: true, + incrementalAnalyzerNames: ImmutableArray.Create(AnalyzerName)); + + _workspace = AnalyzerRunnerHelper.LoadSolutionAsync(_solutionPath, CancellationToken.None).Result; + _incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(_workspace, _options); + } + + [IterationCleanup] + public void Cleanup() + { + _workspace?.Dispose(); + _workspace = null; + } + + [Benchmark] + public async Task RunIncrementalAnalyzer() + { + await _incrementalAnalyzerRunner.RunAsync(CancellationToken.None).ConfigureAwait(false); + } + + } +} From 5f2d97252fe5c14de58e0b6e41e1fbe3498947d2 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 16:44:56 -0700 Subject: [PATCH 106/222] Add more tests for the LSIF generator around ranges, and also fix test naming Tests were named with "Async" suffixes that shouldn't have been done. --- .../WellKnownSymbolMonikerSchemes.cs | 4 +- .../Microsoft.CodeAnalysis.Features.csproj | 1 + .../Lsif/GeneratorTest/RangeResultSetTests.vb | 39 ++++++++++++++----- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs b/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs index a0380faa114f7..9398602e76936 100644 --- a/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs +++ b/src/Features/Core/Portable/LanguageServiceIndexFormat/WellKnownSymbolMonikerSchemes.cs @@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat { internal static class WellKnownSymbolMonikerSchemes { - public static string DotnetNamespace = "dotnet-namespace"; - public static string DotnetXmlDoc = "dotnet-xml-doc"; + public const string DotnetNamespace = "dotnet-namespace"; + public const string DotnetXmlDoc = "dotnet-xml-doc"; } } diff --git a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj index db98934567454..063fd18ae8581 100644 --- a/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj +++ b/src/Features/Core/Portable/Microsoft.CodeAnalysis.Features.csproj @@ -41,6 +41,7 @@ + diff --git a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb index f6bba949f896f..b327ac25f6eb3 100644 --- a/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb +++ b/src/Features/Lsif/GeneratorTest/RangeResultSetTests.vb @@ -12,13 +12,14 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Private Const TestProjectAssemblyName As String = "TestProject" - - - - - - - Public Async Sub ReferenceMonikerAsync(code As String, expectedMoniker As String) + + + + + + + ", WellKnownSymbolMonikerSchemes.DotnetNamespace)> + Public Async Sub ReferenceMoniker(code As String, expectedMoniker As String, expectedMonikerScheme As String) Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( @@ -34,10 +35,28 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Dim monikerVertex = lsif.GetLinkedVertices(Of Graph.Moniker)(resultSetVertex, "moniker").SingleOrDefault() Assert.Equal(expectedMoniker, monikerVertex?.Identifier) + Assert.Equal(expectedMonikerScheme, monikerVertex?.Scheme) + End Sub + + + + + Public Async Sub NoRangesAtAll(code As String) + Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + FilePath="Z:\TestProject.csproj" CommonReferences="true"> + + <%= code %> + + + )) + + Assert.Empty(lsif.Vertices.OfType(Of Range)) End Sub - Public Async Sub DefinitionIncludedInDefinitionResultAsync() + Public Async Sub DefinitionIncludedInDefinitionResult() Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( @@ -58,7 +77,7 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests End Sub - Public Async Sub ReferenceIncludedInReferenceResultAsync() + Public Async Sub ReferenceIncludedInReferenceResult() Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( @@ -79,7 +98,7 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests End Sub - Public Async Sub ReferenceIncludedInSameReferenceResultForMultipleFilesAsync() + Public Async Sub ReferenceIncludedInSameReferenceResultForMultipleFiles() Dim lsif = Await TestLsifOutput.GenerateForWorkspaceAsync( TestWorkspace.CreateWorkspace( From 440ec5a34f4102958424a79a7ab431eae0651a0e Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 16:47:57 -0700 Subject: [PATCH 107/222] Move local method to end --- .../Lsif/Generator/CompilerInvocation.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Features/Lsif/Generator/CompilerInvocation.cs b/src/Features/Lsif/Generator/CompilerInvocation.cs index 0290240144143..0f4180fd0eee3 100644 --- a/src/Features/Lsif/Generator/CompilerInvocation.cs +++ b/src/Features/Lsif/Generator/CompilerInvocation.cs @@ -78,16 +78,6 @@ public static async Task CreateFromJsonAsync(string jsonCont var projectId = ProjectId.CreateNewId(invocationInfo.ProjectFilePath); - DocumentInfo CreateDocumentInfo(string unmappedPath) - { - var mappedPath = mapPath(unmappedPath); - return DocumentInfo.Create( - DocumentId.CreateNewId(projectId, mappedPath), - name: mappedPath, - filePath: mappedPath, - loader: new FileTextLoader(mappedPath, parsedCommandLine.Encoding)); - } - var projectInfo = ProjectInfo.Create( projectId, VersionStamp.Default, @@ -108,6 +98,17 @@ DocumentInfo CreateDocumentInfo(string unmappedPath) var compilation = await workspace.CurrentSolution.GetProject(projectId)!.GetRequiredCompilationAsync(CancellationToken.None); return new CompilerInvocation(compilation, languageServices, invocationInfo.ProjectFilePath); + + // Local methods: + DocumentInfo CreateDocumentInfo(string unmappedPath) + { + var mappedPath = mapPath(unmappedPath); + return DocumentInfo.Create( + DocumentId.CreateNewId(projectId, mappedPath), + name: mappedPath, + filePath: mappedPath, + loader: new FileTextLoader(mappedPath, parsedCommandLine.Encoding)); + } } private static string GetLanguageName(CompilerInvocationInfo invocationInfo) From f26bf6ad5cad045608d47361b18c7610658fe0e0 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 7 May 2020 16:52:10 -0700 Subject: [PATCH 108/222] Mark types as non-copyable --- .../ReaderWriterLockSlimExtensions.cs | 3 +++ .../InternalUtilities/SemaphoreSlimExtensions.cs | 1 + src/Dependencies/PooledObjects/PooledDelegates.cs | 6 ++++++ .../Microsoft.CodeAnalysis.InteractiveHost.csproj | 1 + .../Portable/Shared/Extensions/SafeHandleLease.cs | 2 ++ .../Storage/SQLite/Interop/SafeSqliteBlobHandle.cs | 14 ++++++++++---- .../SQLite/Interop/SafeSqliteStatementHandle.cs | 14 ++++++++++---- .../Compiler/Core/CompilerExtensions.projitems | 1 + .../Compiler/Core/ObjectPools/PooledDisposer.cs | 2 ++ 9 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs index 62e22dfb0b33d..952ad07d2610f 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ReaderWriterLockSlimExtensions.cs @@ -16,6 +16,7 @@ internal static ReadLockExiter DisposableRead(this ReaderWriterLockSlim @lock) return new ReadLockExiter(@lock); } + [NonCopyable] internal readonly struct ReadLockExiter : IDisposable { private readonly ReaderWriterLockSlim _lock; @@ -37,6 +38,7 @@ internal static UpgradeableReadLockExiter DisposableUpgradeableRead(this ReaderW return new UpgradeableReadLockExiter(@lock); } + [NonCopyable] internal readonly struct UpgradeableReadLockExiter : IDisposable { private readonly ReaderWriterLockSlim _lock; @@ -68,6 +70,7 @@ internal static WriteLockExiter DisposableWrite(this ReaderWriterLockSlim @lock) return new WriteLockExiter(@lock); } + [NonCopyable] internal readonly struct WriteLockExiter : IDisposable { private readonly ReaderWriterLockSlim _lock; diff --git a/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs index aca4f612bab84..c06a9049d2beb 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/SemaphoreSlimExtensions.cs @@ -25,6 +25,7 @@ public static async ValueTask DisposableWaitAsync(this Semaph return new SemaphoreDisposer(semaphore); } + [NonCopyable] internal struct SemaphoreDisposer : IDisposable { private readonly SemaphoreSlim _semaphore; diff --git a/src/Dependencies/PooledObjects/PooledDelegates.cs b/src/Dependencies/PooledObjects/PooledDelegates.cs index abc2036ea0bd6..9bc47a206af14 100644 --- a/src/Dependencies/PooledObjects/PooledDelegates.cs +++ b/src/Dependencies/PooledObjects/PooledDelegates.cs @@ -313,6 +313,7 @@ public static Releaser GetPooledFunction(Func is /// called multiple times is undefined. /// + [NonCopyable] public struct Releaser : IDisposable { private readonly Poolable _pooledObject; @@ -416,5 +417,10 @@ private sealed class FuncWithBoundArgument protected override Func Bind() => (arg1, arg2, arg3) => UnboundDelegate(arg1, arg2, arg3, Argument); } + + [AttributeUsage(AttributeTargets.Struct)] + private sealed class NonCopyableAttribute : Attribute + { + } } } diff --git a/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj b/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj index d9747dc75bec4..437c35b92d8e8 100644 --- a/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj +++ b/src/Interactive/Host/Microsoft.CodeAnalysis.InteractiveHost.csproj @@ -37,6 +37,7 @@ + diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs b/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs index 901fb2d3ec73d..68c390a6cc001 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/SafeHandleLease.cs @@ -6,6 +6,7 @@ using System; using System.Runtime.InteropServices; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Shared.Extensions { @@ -13,6 +14,7 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions /// Represents a lease of a . /// /// + [NonCopyable] internal readonly struct SafeHandleLease : IDisposable { private readonly SafeHandle? _handle; diff --git a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs index c7b9ab79c10b7..e2e1b0618a0b2 100644 --- a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs +++ b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteBlobHandle.cs @@ -31,10 +31,16 @@ public sqlite3_blob DangerousGetWrapper() protected override bool ReleaseHandle() { - using var _ = _lease; - var result = (Result)raw.sqlite3_blob_close(_wrapper); - SetHandle(IntPtr.Zero); - return result == Result.OK; + try + { + var result = (Result)raw.sqlite3_blob_close(_wrapper); + SetHandle(IntPtr.Zero); + return result == Result.OK; + } + finally + { + _lease.Dispose(); + } } } } diff --git a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs index b8b27f2883d8d..1a30942fff3c2 100644 --- a/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs +++ b/src/Workspaces/Core/Portable/Storage/SQLite/Interop/SafeSqliteStatementHandle.cs @@ -31,10 +31,16 @@ public sqlite3_stmt DangerousGetWrapper() protected override bool ReleaseHandle() { - using var _ = _lease; - var result = (Result)raw.sqlite3_finalize(_wrapper); - SetHandle(IntPtr.Zero); - return result == Result.OK; + try + { + var result = (Result)raw.sqlite3_finalize(_wrapper); + SetHandle(IntPtr.Zero); + return result == Result.OK; + } + finally + { + _lease.Dispose(); + } } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems index 3bbc78457b7ae..ec9732473e33f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems @@ -14,6 +14,7 @@ + diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs index a57e378d67be3..337358e4cda92 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledDisposer.cs @@ -3,9 +3,11 @@ // See the LICENSE file in the project root for more information. using System; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.PooledObjects { + [NonCopyable] internal readonly struct PooledDisposer : IDisposable where TPoolable : class, IPooled { From bb7e2a590d9358beef342be2e556937df56163ae Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Thu, 7 May 2020 16:53:09 -0700 Subject: [PATCH 109/222] Remove compiler benchmarks --- Compilers.sln | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Compilers.sln b/Compilers.sln index 2ce868d9d4379..aa65ded7dbb63 100644 --- a/Compilers.sln +++ b/Compilers.sln @@ -148,8 +148,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Scri EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Package", "src\NuGet\Microsoft.CodeAnalysis.Package.csproj", "{2483917E-7024-4D10-99C6-2BEF338FF53B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompilerBenchmarks", "src\Tools\CompilerBenchmarks\CompilerBenchmarks.csproj", "{B446E771-AB52-41C9-ACFC-FDF8EACAF291}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildBoss", "src\Tools\BuildBoss\BuildBoss.csproj", "{8A02AFAF-F622-4E3E-9E1A-8CFDACC7C7E1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Net.Compilers.Toolset.Package", "src\NuGet\Microsoft.Net.Compilers.Toolset\Microsoft.Net.Compilers.Toolset.Package.csproj", "{6D407402-CC4A-4125-9B00-C70562A636A5}" @@ -423,10 +421,6 @@ Global {2483917E-7024-4D10-99C6-2BEF338FF53B}.Debug|Any CPU.Build.0 = Debug|Any CPU {2483917E-7024-4D10-99C6-2BEF338FF53B}.Release|Any CPU.ActiveCfg = Release|Any CPU {2483917E-7024-4D10-99C6-2BEF338FF53B}.Release|Any CPU.Build.0 = Release|Any CPU - {B446E771-AB52-41C9-ACFC-FDF8EACAF291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B446E771-AB52-41C9-ACFC-FDF8EACAF291}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B446E771-AB52-41C9-ACFC-FDF8EACAF291}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B446E771-AB52-41C9-ACFC-FDF8EACAF291}.Release|Any CPU.Build.0 = Release|Any CPU {8A02AFAF-F622-4E3E-9E1A-8CFDACC7C7E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8A02AFAF-F622-4E3E-9E1A-8CFDACC7C7E1}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A02AFAF-F622-4E3E-9E1A-8CFDACC7C7E1}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -506,7 +500,6 @@ Global {E0756C89-603F-4B48-8E64-1D53E62654C8} = {274B96B7-F815-47E3-9CA4-4024A57A478F} {7F8057D9-F70F-4EA7-BD64-AB2D0DD8057B} = {3FF38FD4-DF16-44B0-924F-0D5AE155495B} {2483917E-7024-4D10-99C6-2BEF338FF53B} = {274B96B7-F815-47E3-9CA4-4024A57A478F} - {B446E771-AB52-41C9-ACFC-FDF8EACAF291} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {8A02AFAF-F622-4E3E-9E1A-8CFDACC7C7E1} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {6D407402-CC4A-4125-9B00-C70562A636A5} = {274B96B7-F815-47E3-9CA4-4024A57A478F} {706CFC25-B6E0-4DAA-BCC4-F6FAAFEEDF87} = {3FF38FD4-DF16-44B0-924F-0D5AE155495B} From 82f1687cacfe8bcf6ee1894145f08baba20513f9 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 7 May 2020 17:46:26 -0700 Subject: [PATCH 110/222] Add tests for the direct serialized formats This adds some minimal testing for the output formats directly; the majority of this is removing the global static that was assigning Ids and replacing it with an IdFactory to avoid one test impacting another in terms of Id generation. --- src/Features/Lsif/Generator/Generator.cs | 38 +++--- .../Lsif/Generator/Graph/DefinitionResult.cs | 4 +- src/Features/Lsif/Generator/Graph/Document.cs | 6 +- src/Features/Lsif/Generator/Graph/Edge.cs | 12 +- src/Features/Lsif/Generator/Graph/Element.cs | 4 +- src/Features/Lsif/Generator/Graph/Event.cs | 12 +- src/Features/Lsif/Generator/Graph/Id.cs | 12 -- .../Lsif/Generator/Graph/IdFactory.cs | 25 ++++ src/Features/Lsif/Generator/Graph/Item.cs | 4 +- src/Features/Lsif/Generator/Graph/Moniker.cs | 4 +- src/Features/Lsif/Generator/Graph/Project.cs | 6 +- src/Features/Lsif/Generator/Graph/Range.cs | 10 +- .../Lsif/Generator/Graph/ReferenceResult.cs | 4 +- .../Lsif/Generator/Graph/ResultSet.cs | 4 +- src/Features/Lsif/Generator/Graph/Vertex.cs | 4 +- .../SymbolHoldingResultSetTracker.cs | 16 ++- .../Writing/JsonModeLsifJsonWriter.cs | 2 +- .../Lsif/GeneratorTest/OutputFormatTests.vb | 120 ++++++++++++++++++ .../GeneratorTest/Utilities/TestLsifOutput.vb | 21 ++- 19 files changed, 225 insertions(+), 83 deletions(-) create mode 100644 src/Features/Lsif/Generator/Graph/IdFactory.cs create mode 100644 src/Features/Lsif/GeneratorTest/OutputFormatTests.vb diff --git a/src/Features/Lsif/Generator/Generator.cs b/src/Features/Lsif/Generator/Generator.cs index 8401d7e7516bd..6dcb572b4d37f 100644 --- a/src/Features/Lsif/Generator/Generator.cs +++ b/src/Features/Lsif/Generator/Generator.cs @@ -19,6 +19,7 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator internal sealed class Generator { private readonly ILsifJsonWriter _lsifJsonWriter; + private readonly IdFactory _idFactory = new IdFactory(); public Generator(ILsifJsonWriter lsifJsonWriter) { @@ -27,9 +28,9 @@ public Generator(ILsifJsonWriter lsifJsonWriter) public void GenerateForCompilation(Compilation compilation, string projectPath, HostLanguageServices languageServices) { - var projectVertex = new Graph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath)); + var projectVertex = new Graph.Project(kind: GetLanguageKind(compilation.Language), new Uri(projectPath), _idFactory); _lsifJsonWriter.Write(projectVertex); - _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, projectVertex.GetId())); + _lsifJsonWriter.Write(new Event(Event.EventKind.Begin, projectVertex.GetId(), _idFactory)); var documentIds = new ConcurrentBag>(); @@ -37,7 +38,7 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // the JSON file -- we support parallel processing, so we'll accumulate them and then apply at once to avoid a lot // of contention on shared locks. var topLevelSymbolsWriter = new BatchingLsifJsonWriter(_lsifJsonWriter); - var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter, compilation); + var topLevelSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(topLevelSymbolsWriter, compilation, _idFactory); Parallel.ForEach(compilation.SyntaxTrees, syntaxTree => { @@ -50,16 +51,16 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // are allowed and might flush other unrelated stuff at the same time, but there's no harm -- the "causality" ordering // is preserved. var documentWriter = new BatchingLsifJsonWriter(_lsifJsonWriter); - var documentId = GenerateForDocument(semanticModel, languageServices, topLevelSymbolsResultSetTracker, documentWriter); + var documentId = GenerateForDocument(semanticModel, languageServices, topLevelSymbolsResultSetTracker, documentWriter, _idFactory); topLevelSymbolsWriter.FlushToUnderlyingAndEmpty(); documentWriter.FlushToUnderlyingAndEmpty(); documentIds.Add(documentId); }); - _lsifJsonWriter.Write(Edge.Create("contains", projectVertex.GetId(), documentIds.ToArray())); + _lsifJsonWriter.Write(Edge.Create("contains", projectVertex.GetId(), documentIds.ToArray(), _idFactory)); - _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId())); + _lsifJsonWriter.Write(new Event(Event.EventKind.End, projectVertex.GetId(), _idFactory)); } /// @@ -77,23 +78,24 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, SemanticModel semanticModel, HostLanguageServices languageServices, IResultSetTracker topLevelSymbolsResultSetTracker, - ILsifJsonWriter lsifJsonWriter) + ILsifJsonWriter lsifJsonWriter, + IdFactory idFactory) { var syntaxTree = semanticModel.SyntaxTree; var sourceText = semanticModel.SyntaxTree.GetText(); var syntaxFactsService = languageServices.GetRequiredService(); var semanticFactsService = languageServices.GetRequiredService(); - var documentVertex = new Graph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language)); + var documentVertex = new Graph.Document(new Uri(syntaxTree.FilePath), GetLanguageKind(semanticModel.Language), idFactory); lsifJsonWriter.Write(documentVertex); - lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId())); + lsifJsonWriter.Write(new Event(Event.EventKind.Begin, documentVertex.GetId(), idFactory)); // As we are processing this file, we are going to encounter symbols that have a shared resultSet with other documents like types // or methods. We're also going to encounter locals that never leave this document. We don't want those locals being held by // the topLevelSymbolsResultSetTracker, so we'll make another tracker for document local symbols, and then have a delegating // one that picks the correct one of the two. - var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter, semanticModel.Compilation); + var documentLocalSymbolsResultSetTracker = new SymbolHoldingResultSetTracker(lsifJsonWriter, semanticModel.Compilation, idFactory); var symbolResultsTracker = new DelegatingResultSetTracker(symbol => { if (symbol.Kind == SymbolKind.Local || @@ -123,7 +125,7 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // so we'll just make it Lazy. var lazyRangeVertex = new Lazy(() => { - var rangeVertex = Graph.Range.FromTextSpan(syntaxToken.Span, sourceText); + var rangeVertex = Graph.Range.FromTextSpan(syntaxToken.Span, sourceText, idFactory); lsifJsonWriter.Write(rangeVertex); rangeVertices.Add(rangeVertex.GetId()); @@ -157,12 +159,12 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // since we show different contents for different constructed types there. var symbolForLinkedResultSet = (declaredSymbol ?? referencedSymbol)!.OriginalDefinition; var symbolForLinkedResultSetId = symbolResultsTracker.GetResultSetIdForSymbol(symbolForLinkedResultSet); - lsifJsonWriter.Write(Edge.Create("next", lazyRangeVertex.Value.GetId(), symbolForLinkedResultSetId)); + lsifJsonWriter.Write(Edge.Create("next", lazyRangeVertex.Value.GetId(), symbolForLinkedResultSetId, idFactory)); if (declaredSymbol != null) { - var definitionResultsId = symbolResultsTracker.GetResultIdForSymbol(declaredSymbol, Methods.TextDocumentDefinitionName, () => new DefinitionResult()); - lsifJsonWriter.Write(new Item(definitionResultsId.As(), lazyRangeVertex.Value.GetId(), documentVertex.GetId())); + var definitionResultsId = symbolResultsTracker.GetResultIdForSymbol(declaredSymbol, Methods.TextDocumentDefinitionName, () => new DefinitionResult(idFactory)); + lsifJsonWriter.Write(new Item(definitionResultsId.As(), lazyRangeVertex.Value.GetId(), documentVertex.GetId(), idFactory)); } if (referencedSymbol != null) @@ -171,14 +173,14 @@ public void GenerateForCompilation(Compilation compilation, string projectPath, // symbol but the range can point a different symbol's resultSet. This can happen if the token is // both a definition of a symbol (where we will point to the definition) but also a reference to some // other symbol. - var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(referencedSymbol.OriginalDefinition, Methods.TextDocumentReferencesName, () => new ReferenceResult()); - lsifJsonWriter.Write(new Item(referenceResultsId.As(), lazyRangeVertex.Value.GetId(), documentVertex.GetId(), property: "references")); + var referenceResultsId = symbolResultsTracker.GetResultIdForSymbol(referencedSymbol.OriginalDefinition, Methods.TextDocumentReferencesName, () => new ReferenceResult(idFactory)); + lsifJsonWriter.Write(new Item(referenceResultsId.As(), lazyRangeVertex.Value.GetId(), documentVertex.GetId(), idFactory, property: "references")); } } } - lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices)); - lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId())); + lsifJsonWriter.Write(Edge.Create("contains", documentVertex.GetId(), rangeVertices, idFactory)); + lsifJsonWriter.Write(new Event(Event.EventKind.End, documentVertex.GetId(), idFactory)); return documentVertex.GetId(); } diff --git a/src/Features/Lsif/Generator/Graph/DefinitionResult.cs b/src/Features/Lsif/Generator/Graph/DefinitionResult.cs index a2c536371a34f..6705ebefa2d86 100644 --- a/src/Features/Lsif/Generator/Graph/DefinitionResult.cs +++ b/src/Features/Lsif/Generator/Graph/DefinitionResult.cs @@ -9,8 +9,8 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph /// internal sealed class DefinitionResult : Vertex { - public DefinitionResult() - : base(label: "definitionResult") + public DefinitionResult(IdFactory idFactory) + : base(label: "definitionResult", idFactory) { } } diff --git a/src/Features/Lsif/Generator/Graph/Document.cs b/src/Features/Lsif/Generator/Graph/Document.cs index 93f00a4187ccc..f0fcde9723f06 100644 --- a/src/Features/Lsif/Generator/Graph/Document.cs +++ b/src/Features/Lsif/Generator/Graph/Document.cs @@ -13,14 +13,12 @@ internal sealed class Document : Vertex { public Uri Uri { get; } public string LanguageId { get; } - public string? Contents { get; } - public Document(Uri uri, string languageId, string? contents = null) - : base(label: "document") + public Document(Uri uri, string languageId, IdFactory idFactory) + : base(label: "document", idFactory) { this.Uri = uri; this.LanguageId = languageId; - this.Contents = contents; } } } diff --git a/src/Features/Lsif/Generator/Graph/Edge.cs b/src/Features/Lsif/Generator/Graph/Edge.cs index 893c75296f728..c551e97474078 100644 --- a/src/Features/Lsif/Generator/Graph/Edge.cs +++ b/src/Features/Lsif/Generator/Graph/Edge.cs @@ -20,22 +20,22 @@ internal class Edge : Element [JsonProperty("inVs")] public Id[] InVertices { get; } - public Edge(string label, Id outVertex, Id[] inVertices) - : base(type: "edge", label: label) + public Edge(string label, Id outVertex, Id[] inVertices, IdFactory idFactory) + : base(type: "edge", label: label, idFactory) { OutVertex = outVertex; InVertices = inVertices; } - public static Edge Create(string label, Id outVertex, Id inVertex) where TOutVertex : Vertex where TInVertex : Vertex + public static Edge Create(string label, Id outVertex, Id inVertex, IdFactory idFactory) where TOutVertex : Vertex where TInVertex : Vertex { var inVerticesArray = new Id[1]; inVerticesArray[0] = inVertex.As(); - return new Edge(label, outVertex.As(), inVerticesArray); + return new Edge(label, outVertex.As(), inVerticesArray, idFactory); } - public static Edge Create(string label, Id outVertex, IList> inVertices) where TOutVertex : Vertex where TInVertex : Vertex + public static Edge Create(string label, Id outVertex, IList> inVertices, IdFactory idFactory) where TOutVertex : Vertex where TInVertex : Vertex { var inVerticesArray = new Id[inVertices.Count]; @@ -46,7 +46,7 @@ public static Edge Create(string label, Id ou inVerticesArray[i] = inVertices[i].As(); } - return new Edge(label, outVertex.As(), inVerticesArray); + return new Edge(label, outVertex.As(), inVerticesArray, idFactory); } public override string ToString() diff --git a/src/Features/Lsif/Generator/Graph/Element.cs b/src/Features/Lsif/Generator/Graph/Element.cs index 1b573fa728324..9f9ebbbbf8493 100644 --- a/src/Features/Lsif/Generator/Graph/Element.cs +++ b/src/Features/Lsif/Generator/Graph/Element.cs @@ -13,9 +13,9 @@ internal abstract class Element public string Type { get; } public string Label { get; } - protected Element(string type, string label) + protected Element(string type, string label, IdFactory idFactory) { - this.Id = Id.Create(); + this.Id = idFactory.Create(); this.Label = label; this.Type = type; } diff --git a/src/Features/Lsif/Generator/Graph/Event.cs b/src/Features/Lsif/Generator/Graph/Event.cs index 184b3ec7b8037..abc3134855871 100644 --- a/src/Features/Lsif/Generator/Graph/Event.cs +++ b/src/Features/Lsif/Generator/Graph/Event.cs @@ -15,21 +15,21 @@ internal sealed class Event : Vertex public string Scope { get; } public Id Data { get; } - private Event(EventKind kind, string scope, Id data) - : base(label: "$event") + private Event(EventKind kind, string scope, Id data, IdFactory idFactory) + : base(label: "$event", idFactory) { this.Kind = kind switch { EventKind.Begin => "begin", EventKind.End => "end", _ => throw new ArgumentException(nameof(kind)) }; this.Scope = scope; this.Data = data; } - public Event(EventKind kind, Id data) - : this(kind, "project", data.As()) + public Event(EventKind kind, Id data, IdFactory idFactory) + : this(kind, "project", data.As(), idFactory) { } - public Event(EventKind kind, Id data) - : this(kind, "document", data.As()) + public Event(EventKind kind, Id data, IdFactory idFactory) + : this(kind, "document", data.As(), idFactory) { } diff --git a/src/Features/Lsif/Generator/Graph/Id.cs b/src/Features/Lsif/Generator/Graph/Id.cs index d7c990aa0b9dc..a9af34d83f863 100644 --- a/src/Features/Lsif/Generator/Graph/Id.cs +++ b/src/Features/Lsif/Generator/Graph/Id.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Threading; namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph { @@ -14,11 +13,6 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph /// to ensure type safety in the code so we don't cross IDs of different types. internal struct Id : IEquatable>, ISerializableId where T : Element { - /// - /// The next numberic ID that will be used for an object. Accessed only with Interlocked.Increment. - /// - private static int s_globalId = 0; - public Id(int id) { NumericId = id; @@ -26,12 +20,6 @@ public Id(int id) public int NumericId { get; } - public static Id Create() - { - var id = Interlocked.Increment(ref s_globalId); - return new Id(id); - } - public override bool Equals(object? obj) { return obj is Id other && Equals(other); diff --git a/src/Features/Lsif/Generator/Graph/IdFactory.cs b/src/Features/Lsif/Generator/Graph/IdFactory.cs new file mode 100644 index 0000000000000..b20d92d862967 --- /dev/null +++ b/src/Features/Lsif/Generator/Graph/IdFactory.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading; + +namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph +{ + /// + /// A little class which holds onto the next ID to be produced. Avoids static state in unit testing. + /// + internal sealed class IdFactory + { + /// + /// The next numberic ID that will be used for an object. Accessed only with Interlocked.Increment. + /// + private int _globalId = 0; + + public Id Create() where T : Element + { + var id = Interlocked.Increment(ref _globalId); + return new Id(id); + } + } +} diff --git a/src/Features/Lsif/Generator/Graph/Item.cs b/src/Features/Lsif/Generator/Graph/Item.cs index 567018db97c42..49d53622289e0 100644 --- a/src/Features/Lsif/Generator/Graph/Item.cs +++ b/src/Features/Lsif/Generator/Graph/Item.cs @@ -13,8 +13,8 @@ internal sealed class Item : Edge public Id Document { get; } public string? Property { get; } - public Item(Id outVertex, Id range, Id document, string? property = null) - : base(label: "item", outVertex, new[] { range.As() }) + public Item(Id outVertex, Id range, Id document, IdFactory idFactory, string? property = null) + : base(label: "item", outVertex, new[] { range.As() }, idFactory) { Document = document; Property = property; diff --git a/src/Features/Lsif/Generator/Graph/Moniker.cs b/src/Features/Lsif/Generator/Graph/Moniker.cs index ddd8a0fbcc7b8..1b8c034e3763c 100644 --- a/src/Features/Lsif/Generator/Graph/Moniker.cs +++ b/src/Features/Lsif/Generator/Graph/Moniker.cs @@ -10,8 +10,8 @@ internal sealed class Moniker : Vertex public string Identifier { get; } public string? Kind { get; } - public Moniker(string scheme, string identifier, string? kind = null) - : base(label: "moniker") + public Moniker(string scheme, string identifier, string? kind, IdFactory idFactory) + : base(label: "moniker", idFactory) { Scheme = scheme; Identifier = identifier; diff --git a/src/Features/Lsif/Generator/Graph/Project.cs b/src/Features/Lsif/Generator/Graph/Project.cs index c77224669b387..cb65634c79c9d 100644 --- a/src/Features/Lsif/Generator/Graph/Project.cs +++ b/src/Features/Lsif/Generator/Graph/Project.cs @@ -13,14 +13,12 @@ internal sealed class Project : Vertex { public string Kind { get; } public Uri? Resource { get; } - public string? Contents { get; } - public Project(string kind, Uri? resource = null, string? contents = null) - : base(label: "project") + public Project(string kind, Uri? resource, IdFactory idFactory) + : base(label: "project", idFactory) { Kind = kind; Resource = resource; - Contents = contents; } } } diff --git a/src/Features/Lsif/Generator/Graph/Range.cs b/src/Features/Lsif/Generator/Graph/Range.cs index d371f99c4361f..a6b752616f7f4 100644 --- a/src/Features/Lsif/Generator/Graph/Range.cs +++ b/src/Features/Lsif/Generator/Graph/Range.cs @@ -15,21 +15,21 @@ internal sealed class Range : Vertex public Position Start { get; } public Position End { get; } - public Range(Position start, Position end) - : base(label: "range") + public Range(Position start, Position end, IdFactory idFactory) + : base(label: "range", idFactory) { Start = start; End = end; } - public static Range FromTextSpan(TextSpan textSpan, SourceText sourceText) + public static Range FromTextSpan(TextSpan textSpan, SourceText sourceText, IdFactory idFactory) { var linePositionSpan = sourceText.Lines.GetLinePositionSpan(textSpan); - return new Range(start: FromLinePositionSpan(linePositionSpan.Start), end: FromLinePositionSpan(linePositionSpan.End)); + return new Range(start: ConvertLinePositionToPosition(linePositionSpan.Start), end: ConvertLinePositionToPosition(linePositionSpan.End), idFactory); } - private static Position FromLinePositionSpan(LinePosition linePosition) + internal static Position ConvertLinePositionToPosition(LinePosition linePosition) { return new Position { Line = linePosition.Line, Character = linePosition.Character }; } diff --git a/src/Features/Lsif/Generator/Graph/ReferenceResult.cs b/src/Features/Lsif/Generator/Graph/ReferenceResult.cs index 935783cbac108..4ae5c85f070e3 100644 --- a/src/Features/Lsif/Generator/Graph/ReferenceResult.cs +++ b/src/Features/Lsif/Generator/Graph/ReferenceResult.cs @@ -9,8 +9,8 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph /// internal sealed class ReferenceResult : Vertex { - public ReferenceResult() - : base(label: "referenceResult") + public ReferenceResult(IdFactory idFactory) + : base(label: "referenceResult", idFactory) { } } diff --git a/src/Features/Lsif/Generator/Graph/ResultSet.cs b/src/Features/Lsif/Generator/Graph/ResultSet.cs index 85f177908abe0..2f6ccb01df7b6 100644 --- a/src/Features/Lsif/Generator/Graph/ResultSet.cs +++ b/src/Features/Lsif/Generator/Graph/ResultSet.cs @@ -9,8 +9,8 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph /// internal sealed class ResultSet : Vertex { - public ResultSet() - : base(label: "resultSet") + public ResultSet(IdFactory idFactory) + : base(label: "resultSet", idFactory) { } } diff --git a/src/Features/Lsif/Generator/Graph/Vertex.cs b/src/Features/Lsif/Generator/Graph/Vertex.cs index a2f593c751505..10894ccdef15d 100644 --- a/src/Features/Lsif/Generator/Graph/Vertex.cs +++ b/src/Features/Lsif/Generator/Graph/Vertex.cs @@ -9,8 +9,8 @@ namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph /// internal abstract class Vertex : Element { - protected Vertex(string label) - : base(type: "vertex", label) + protected Vertex(string label, IdFactory idFactory) + : base(type: "vertex", label, idFactory) { } diff --git a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs index 6cab4a31a07b1..588a628f03539 100644 --- a/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs +++ b/src/Features/Lsif/Generator/ResultSetTracking/SymbolHoldingResultSetTracker.cs @@ -16,6 +16,7 @@ internal sealed class SymbolHoldingResultSetTracker : IResultSetTracker private readonly Dictionary _symbolToResultSetId = new Dictionary(); private readonly ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); private readonly ILsifJsonWriter _lsifJsonWriter; + private readonly IdFactory _idFactory; /// /// The compilation which we are analyzing. When we make ResultSets, we attach monikers to them, and those @@ -25,10 +26,11 @@ internal sealed class SymbolHoldingResultSetTracker : IResultSetTracker /// private readonly Compilation _sourceCompilation; - public SymbolHoldingResultSetTracker(ILsifJsonWriter lsifJsonWriter, Compilation sourceCompilation) + public SymbolHoldingResultSetTracker(ILsifJsonWriter lsifJsonWriter, Compilation sourceCompilation, IdFactory idFactory) { _lsifJsonWriter = lsifJsonWriter; _sourceCompilation = sourceCompilation; + _idFactory = idFactory; } private TrackedResultSet GetTrackedResultSet(ISymbol symbol) @@ -57,7 +59,7 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) // We still don't have it, so we have to start writing now upgradeableReadLock.EnterWrite(); - var resultSet = new ResultSet(); + var resultSet = new ResultSet(_idFactory); _lsifJsonWriter.Write(resultSet); trackedResultSet = new TrackedResultSet(resultSet.GetId()); _symbolToResultSetId.Add(symbol, trackedResultSet); @@ -77,7 +79,7 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) if (monikerVertex != null) { _lsifJsonWriter.Write(monikerVertex); - _lsifJsonWriter.Write(Edge.Create("moniker", trackedResultSet.Id, monikerVertex.GetId())); + _lsifJsonWriter.Write(Edge.Create("moniker", trackedResultSet.Id, monikerVertex.GetId(), _idFactory)); } } @@ -108,7 +110,7 @@ private TrackedResultSet GetTrackedResultSet(ISymbol symbol) kind = "import"; } - return new Moniker(moniker.Scheme, moniker.Identifier, kind); + return new Moniker(moniker.Scheme, moniker.Identifier, kind, _idFactory); } public Id GetResultSetIdForSymbol(ISymbol symbol) @@ -118,7 +120,7 @@ public Id GetResultSetIdForSymbol(ISymbol symbol) public Id GetResultIdForSymbol(ISymbol symbol, string edgeKind, Func vertexCreator) where T : Vertex { - return GetTrackedResultSet(symbol).GetResultId(edgeKind, vertexCreator, _lsifJsonWriter); + return GetTrackedResultSet(symbol).GetResultId(edgeKind, vertexCreator, _lsifJsonWriter, _idFactory); } public bool ResultSetNeedsInformationalEdgeAdded(ISymbol symbol, string edgeKind) @@ -153,7 +155,7 @@ public TrackedResultSet(Id id) Id = id; } - public Id GetResultId(string edgeKind, Func vertexCreator, ILsifJsonWriter lsifJsonWriter) where T : Vertex + public Id GetResultId(string edgeKind, Func vertexCreator, ILsifJsonWriter lsifJsonWriter, IdFactory idFactory) where T : Vertex { lock (_edgeKindToVertexId) { @@ -173,7 +175,7 @@ public Id GetResultId(string edgeKind, Func vertexCreator, ILsifJsonWri _edgeKindToVertexId.Add(edgeKind, vertex.GetId().As()); lsifJsonWriter.Write(vertex); - lsifJsonWriter.Write(Edge.Create(edgeKind, Id, vertex.GetId())); + lsifJsonWriter.Write(Edge.Create(edgeKind, Id, vertex.GetId(), idFactory)); return vertex.GetId(); } diff --git a/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs b/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs index d44f8e38dbf71..d0be03a7bfdb1 100644 --- a/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs +++ b/src/Features/Lsif/Generator/Writing/JsonModeLsifJsonWriter.cs @@ -41,12 +41,12 @@ public void Write(Element element) lock (_writeGate) { _jsonSerializer.Serialize(_jsonTextWriter, element); - _jsonTextWriter.WriteWhitespace(Environment.NewLine); } } public void Dispose() { + _jsonTextWriter.WriteWhitespace(Environment.NewLine); _jsonTextWriter.WriteEndArray(); _jsonTextWriter.Close(); } diff --git a/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb b/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb new file mode 100644 index 0000000000000..86c77ef482289 --- /dev/null +++ b/src/Features/Lsif/GeneratorTest/OutputFormatTests.vb @@ -0,0 +1,120 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports System.IO +Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces +Imports Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Roslyn.Test.Utilities + +Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests + + Public NotInheritable Class OutputFormatTests + + Public Async Sub TestLineModeOutput() + Dim stringWriter = New StringWriter() + Dim jsonWriter = New LineModeLsifJsonWriter(stringWriter) + + Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + + + + ), jsonWriter) + + AssertEx.EqualOrDiff( +"{""kind"":""csharp"",""resource"":""file:///Z:/TestProject.csproj"",""id"":1,""type"":""vertex"",""label"":""project""} +{""kind"":""begin"",""scope"":""project"",""data"":1,""id"":2,""type"":""vertex"",""label"":""$event""} +{""uri"":""file:///Z:/A.cs"",""languageId"":""csharp"",""id"":3,""type"":""vertex"",""label"":""document""} +{""kind"":""begin"",""scope"":""document"",""data"":3,""id"":4,""type"":""vertex"",""label"":""$event""} +{""outV"":3,""inVs"":[],""id"":5,""type"":""edge"",""label"":""contains""} +{""kind"":""end"",""scope"":""document"",""data"":3,""id"":6,""type"":""vertex"",""label"":""$event""} +{""outV"":1,""inVs"":[3],""id"":7,""type"":""edge"",""label"":""contains""} +{""kind"":""end"",""scope"":""project"",""data"":1,""id"":8,""type"":""vertex"",""label"":""$event""} +", stringWriter.ToString()) + End Sub + + + Public Async Sub TestJsonModeOutput() + Dim stringWriter = New StringWriter() + Using jsonWriter = New JsonModeLsifJsonWriter(stringWriter) + + Await TestLsifOutput.GenerateForWorkspaceAsync( + TestWorkspace.CreateWorkspace( + + + + + ), jsonWriter) + End Using + + AssertEx.EqualOrDiff( + "[ + { + ""kind"": ""csharp"", + ""resource"": ""file:///Z:/TestProject.csproj"", + ""id"": 1, + ""type"": ""vertex"", + ""label"": ""project"" + }, + { + ""kind"": ""begin"", + ""scope"": ""project"", + ""data"": 1, + ""id"": 2, + ""type"": ""vertex"", + ""label"": ""$event"" + }, + { + ""uri"": ""file:///Z:/A.cs"", + ""languageId"": ""csharp"", + ""id"": 3, + ""type"": ""vertex"", + ""label"": ""document"" + }, + { + ""kind"": ""begin"", + ""scope"": ""document"", + ""data"": 3, + ""id"": 4, + ""type"": ""vertex"", + ""label"": ""$event"" + }, + { + ""outV"": 3, + ""inVs"": [], + ""id"": 5, + ""type"": ""edge"", + ""label"": ""contains"" + }, + { + ""kind"": ""end"", + ""scope"": ""document"", + ""data"": 3, + ""id"": 6, + ""type"": ""vertex"", + ""label"": ""$event"" + }, + { + ""outV"": 1, + ""inVs"": [ + 3 + ], + ""id"": 7, + ""type"": ""edge"", + ""label"": ""contains"" + }, + { + ""kind"": ""end"", + ""scope"": ""project"", + ""data"": 1, + ""id"": 8, + ""type"": ""vertex"", + ""label"": ""$event"" + } +]", stringWriter.ToString()) + End Sub + End Class +End Namespace diff --git a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb index a16a8d2a2169d..48c406f223eb4 100644 --- a/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb +++ b/src/Features/Lsif/GeneratorTest/Utilities/TestLsifOutput.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces Imports Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Graph +Imports Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.Writing Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.Utilities Friend Class TestLsifOutput @@ -18,14 +19,19 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U Public Shared Async Function GenerateForWorkspaceAsync(workspace As TestWorkspace) As Task(Of TestLsifOutput) Dim testLsifJsonWriter = New TestLsifJsonWriter() - Dim generator = New Generator(testLsifJsonWriter) + + Await GenerateForWorkspaceAsync(workspace, testLsifJsonWriter) + + Return New TestLsifOutput(testLsifJsonWriter, workspace) + End Function + + Public Shared Async Function GenerateForWorkspaceAsync(workspace As TestWorkspace, jsonWriter As ILsifJsonWriter) As Task + Dim generator = New Generator(jsonWriter) For Each project In workspace.CurrentSolution.Projects Dim compilation = Await project.GetCompilationAsync() generator.GenerateForCompilation(compilation, project.FilePath, project.LanguageServices) Next - - Return New TestLsifOutput(testLsifJsonWriter, workspace) End Function Public Function GetElementById(Of T As Element)(id As Id(Of T)) As T @@ -61,10 +67,13 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests.U For Each selectedSpan In testDocument.SelectedSpans Dim document = _workspace.CurrentSolution.GetDocument(testDocument.Id) - Dim selectionRange = Range.FromTextSpan(selectedSpan, Await document.GetTextAsync()) + Dim text = Await document.GetTextAsync() + Dim linePositionSpan = text.Lines.GetLinePositionSpan(selectedSpan) + Dim positionStart = Range.ConvertLinePositionToPosition(linePositionSpan.Start) + Dim positionEnd = Range.ConvertLinePositionToPosition(linePositionSpan.End) - builder.Add(rangeVertices.Where(Function(r) r.Start = selectionRange.Start AndAlso - r.End = selectionRange.End) _ + builder.Add(rangeVertices.Where(Function(r) r.Start = positionStart AndAlso + r.End = positionEnd) _ .Single()) Next Next From 6d317555cf415afe2142f2570d7da3fea5c601a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Thu, 7 May 2020 18:10:10 -0700 Subject: [PATCH 111/222] ActiveStatementTagger Nullable annotations (#44053) --- .../EditAndContinue/ActiveStatementTag.cs | 2 ++ .../EditAndContinue/ActiveStatementTagger.cs | 28 ++++++++++--------- .../ActiveStatementTaggerProvider.cs | 4 ++- .../ActiveStatementTrackingServiceFactory.cs | 2 ++ .../EditAndContinueErrorTypeDefinition.cs | 4 ++- .../EditAndContinueSaveFileCommandHandler.cs | 2 ++ .../Workspace/Workspace_Registration.cs | 5 +++- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTag.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTag.cs index 91374163a0b18..c72e56781a419 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTag.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTag.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using Microsoft.VisualStudio.Text.Tagging; namespace Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTagger.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTagger.cs index 5ecbff6b255e4..5b221099ef70c 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTagger.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTagger.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Linq; @@ -20,7 +22,9 @@ internal sealed class ActiveStatementTagger : ForegroundThreadAffinitizedObject, private readonly WorkspaceRegistration _workspaceRegistration; private readonly ITextBuffer _buffer; - private IActiveStatementTrackingService _trackingServiceOpt; + private IActiveStatementTrackingService? _trackingService; + + public event EventHandler? TagsChanged; public ActiveStatementTagger(IThreadingContext threadingContext, ITextBuffer buffer) : base(threadingContext) @@ -35,21 +39,21 @@ public ActiveStatementTagger(IThreadingContext threadingContext, ITextBuffer buf _buffer = buffer; } - private void OnWorkspaceChanged(object sender, EventArgs e) + private void OnWorkspaceChanged(object? sender, EventArgs e) => ConnectToWorkspace(_workspaceRegistration.Workspace); - private void ConnectToWorkspace(Workspace workspaceOpt) + private void ConnectToWorkspace(Workspace? workspace) { - var newServiceOpt = workspaceOpt?.Services.GetService(); - if (newServiceOpt != null) + var newService = workspace?.Services.GetService(); + if (newService != null) { - newServiceOpt.TrackingSpansChanged += OnTrackingSpansChanged; + newService.TrackingSpansChanged += OnTrackingSpansChanged; } - var previousServiceOpt = Interlocked.Exchange(ref _trackingServiceOpt, newServiceOpt); - if (previousServiceOpt != null) + var previousService = Interlocked.Exchange(ref _trackingService, newService); + if (previousService != null) { - previousServiceOpt.TrackingSpansChanged -= OnTrackingSpansChanged; + previousService.TrackingSpansChanged -= OnTrackingSpansChanged; } } @@ -58,11 +62,9 @@ public void Dispose() AssertIsForeground(); _workspaceRegistration.WorkspaceChanged -= OnWorkspaceChanged; - ConnectToWorkspace(workspaceOpt: null); + ConnectToWorkspace(workspace: null); } - public event EventHandler TagsChanged; - private void OnTrackingSpansChanged(bool leafChanged) { var handler = TagsChanged; @@ -78,7 +80,7 @@ public IEnumerable> GetTags(NormalizedSnapshotSpanColle { AssertIsForeground(); - var service = _trackingServiceOpt; + var service = _trackingService; if (service == null) { yield break; diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTaggerProvider.cs index 648aa3e5a9938..9ffafa90be006 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTaggerProvider.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; @@ -26,7 +28,7 @@ internal sealed class ActiveStatementTaggerProvider : ITaggerProvider public ActiveStatementTaggerProvider(IThreadingContext threadingContext) => _threadingContext = threadingContext; - public ITagger CreateTagger(ITextBuffer buffer) where T : ITag + public ITagger? CreateTagger(ITextBuffer buffer) where T : ITag => new ActiveStatementTagger(_threadingContext, buffer) as ITagger; } } diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs index dc71d46680286..b86988c6dcc0e 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/ActiveStatementTrackingServiceFactory.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Composition; using Microsoft.CodeAnalysis.EditAndContinue; diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueErrorTypeDefinition.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueErrorTypeDefinition.cs index 5f3fc04bc6c34..dd2744543a1ae 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueErrorTypeDefinition.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueErrorTypeDefinition.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.ComponentModel.Composition; using Microsoft.VisualStudio.Text.Adornments; using Microsoft.VisualStudio.Utilities; @@ -14,6 +16,6 @@ internal static class EditAndContinueErrorTypeDefinition [Export(typeof(ErrorTypeDefinition))] [Name(Name)] - internal static ErrorTypeDefinition Definition; + internal static ErrorTypeDefinition? Definition; } } diff --git a/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueSaveFileCommandHandler.cs b/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueSaveFileCommandHandler.cs index d3a90d9f0b4e0..285cd2f9ad5fc 100644 --- a/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueSaveFileCommandHandler.cs +++ b/src/EditorFeatures/Core/Implementation/EditAndContinue/EditAndContinueSaveFileCommandHandler.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Host.Mef; diff --git a/src/Workspaces/Core/Portable/Workspace/Workspace_Registration.cs b/src/Workspaces/Core/Portable/Workspace/Workspace_Registration.cs index 402958e1c6077..0fed4b60c2911 100644 --- a/src/Workspaces/Core/Portable/Workspace/Workspace_Registration.cs +++ b/src/Workspaces/Core/Portable/Workspace/Workspace_Registration.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.Text; @@ -17,7 +20,7 @@ public abstract partial class Workspace /// /// Gets the workspace associated with the specific text container. /// - public static bool TryGetWorkspace(SourceTextContainer textContainer, out Workspace workspace) + public static bool TryGetWorkspace(SourceTextContainer textContainer, [NotNullWhen(true)] out Workspace? workspace) { if (textContainer == null) { From ebdcc5472fd4bb1dd280e47ab31479b232579917 Mon Sep 17 00:00:00 2001 From: Joseph Musser Date: Fri, 8 May 2020 12:18:49 -0400 Subject: [PATCH 112/222] Update module initializers feature status (#43909) --- docs/Language Feature Status.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Language Feature Status.md b/docs/Language Feature Status.md index a9cd216490ecd..1811a80b59c60 100644 --- a/docs/Language Feature Status.md +++ b/docs/Language Feature Status.md @@ -24,7 +24,7 @@ efforts behind them. | [Target-typed conditional](https://github.com/dotnet/csharplang/issues/2460) | [features/target-typing](https://github.com/dotnet/roslyn/tree/features/target-typing) | [In Progress](https://github.com/dotnet/roslyn/issues/43186) | [gafter](https://github.com/gafter) | [agocke](https://github.com/agocke), [RikkiGibson](https://github.com/RikkiGibson) | [gafter](https://github.com/gafter) | | [Covariant](https://github.com/dotnet/csharplang/issues/49) [Returns](https://github.com/dotnet/csharplang/issues/2844) | [features/covariant-returns](https://github.com/dotnet/roslyn/tree/features/covariant-returns) | [In Progress](https://github.com/dotnet/roslyn/issues/43188) | [gafter](https://github.com/gafter) | [AlekseyTs](https://github.com/AlekseyTs), [agocke](https://github.com/agocke) | [gafter](https://github.com/gafter) | | [Extension GetEnumerator](https://github.com/dotnet/csharplang/issues/3194) | [features/extension-foreach](https://github.com/dotnet/roslyn/tree/features/extension-foreach) | [In Progress](https://github.com/dotnet/roslyn/issues/43184) | [YairHalberstadt](https://github.com/YairHalberstadt) | [333fred](https://github.com/333fred) | [333fred](https://github.com/333fred) | -| [Module initializers](https://github.com/RikkiGibson/csharplang/blob/module-initializers/proposals/module-initializers.md) | TBD | [In progress / design](https://github.com/dotnet/roslyn/issues/40500) | [RikkiGibson](https://github.com/RikkiGibson) [jnm2](https://github.com/jnm2)| [AlekseyTs](https://github.com/AlekseyTs) | [gafter](https://github.com/gafter) | +| [Module initializers](https://github.com/dotnet/csharplang/blob/master/proposals/module-initializers.md) | [features/module-initializers](https://github.com/dotnet/roslyn/tree/features/module-initializers) | [In progress / design](https://github.com/dotnet/roslyn/issues/40500) | [RikkiGibson](https://github.com/RikkiGibson) [jnm2](https://github.com/jnm2)| [AlekseyTs](https://github.com/AlekseyTs) | [gafter](https://github.com/gafter) | | [Extending Partial](https://github.com/jaredpar/csharplang/blob/partial/proposals/extending-partial-methods.md) | [features/partial-methods](https://github.com/dotnet/roslyn/tree/features/partial-methods) | [In-Progress](https://github.com/dotnet/roslyn/issues/43795) | [RikkiGibson](https://github.com/RikkiGibson) | [chsienki](https://github.com/chsienki) | [jaredpar](https://github.com/jaredpar) | | [Top-level statements](https://github.com/dotnet/csharplang/blob/master/proposals/top-level-statements.md) | [features/SimplePrograms](https://github.com/dotnet/roslyn/tree/features/SimplePrograms) | [In-Progress](https://github.com/dotnet/roslyn/issues/43563) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) | From 23774583333a1d0223e4eb8cb673f15201378e6b Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Fri, 8 May 2020 10:24:50 -0700 Subject: [PATCH 113/222] Remove skipAnalyzers from vscode tasks --- .vscode/tasks.json | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3d3bdb520ada3..871242672e0e8 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -16,23 +16,23 @@ "group": "build" }, { - "label": "build skip analyzers", + "label": "build with analyzers", "command": "./build.sh", "type": "shell", "args": [ - "--skipAnalyzers" + "--runAnalyzers" ], "windows": { "command": "./build.cmd", "args": [ - "-skipAnalyzers" + "-runAnalyzers" ], }, "problemMatcher": "$msCompile", "group": "build" }, { - "label": "build csc skip analyzers", + "label": "build csc", "command": "./.dotnet/dotnet", "type": "shell", "args": [ @@ -45,7 +45,7 @@ "group": "build" }, { - "label": "build current project skip analyzers", + "label": "build current project", "type": "shell", "command": "./.dotnet/dotnet", "args": [ @@ -70,7 +70,7 @@ "group": "build" }, { - "label": "msbuild current project skip analyzers", + "label": "msbuild current project", "type": "shell", "command": "echo 'Task not supported on this OS'", "windows": { @@ -101,14 +101,8 @@ "label": "update xlf files", "command": "./build.sh", "type": "shell", - "args": [ - "--skipAnalyzers" - ], "windows": { - "command": "./build.cmd", - "args": [ - "-skipAnalyzers" - ], + "command": "./build.cmd" }, "options": { "env": { "UpdateXlfOnBuild": "true" } From ace6dbc2520acf7867e415487c9fbc0f13466d96 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 8 May 2020 11:08:12 -0700 Subject: [PATCH 114/222] Add test. --- .../Test2/Rename/RenameEngineTests.vb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb b/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb index 341368b763e70..77fdd04a27123 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb @@ -7045,5 +7045,26 @@ class C , host:=host, renameTo:="Cat") End Using End Sub + + + Public Sub RenameTypeParameterFromCRef(host As TestHost) + Using result = RenameEngineResult.Create(_outputHelper, + + + + /// + /// + void Goo(T t) { } +}]]> + + + , host:=host, renameTo:="D") + + result.AssertLabeledSpansAre("Complex", "C.Goo{D}(X)", RelatedLocationType.UnresolvedConflict) + End Using + End Sub End Class End Namespace From 889966ca6a6ba94f32e21b5528ee1dc82a80f60c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 8 May 2020 02:31:32 -0700 Subject: [PATCH 115/222] Keep track of associated project when finding symbols for faster lookup. --- .../FindReferences/DependentTypeFinder.cs | 39 +++++++++++-------- .../DependentTypeFinder_DerivedClasses.cs | 4 +- .../DependentTypeFinder_DerivedInterfaces.cs | 4 +- .../DependentTypeFinder_ImplementingTypes.cs | 12 +++--- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs index 63944ca82287d..a0b7dbe95a9ba 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs @@ -53,7 +53,8 @@ internal static partial class DependentTypeFinder private static readonly Func s_isNonSealedClass = t => t?.TypeKind == TypeKind.Class && !t.IsSealed; private static readonly Func s_isInterfaceOrNonSealedClass = t => s_isInterface(t) || s_isNonSealedClass(t); - private static readonly ObjectPool> s_setPool1 = PooledHashSet.CreatePool(SymbolEquivalenceComparer.Instance); + private static readonly ObjectPool> s_symbolSetPool = PooledHashSet.CreatePool(SymbolEquivalenceComparer.Instance); + private static readonly ObjectPool> s_symbolToProjectPool = PooledDictionary.CreatePool(SymbolEquivalenceComparer.Instance); // Caches from a types to their related types (in the context of a specific solution). // Kept as a cache so that clients who make many calls into us won't end up computing @@ -84,7 +85,7 @@ private static async Task> FindTypesFromCacheOr Solution solution, IImmutableSet projects, RelatedTypeCache cache, - Func>> findAsync, + Func>> findAsync, CancellationToken cancellationToken) { var dictionary = cache.GetValue(solution, s_createTypeMap); @@ -96,7 +97,7 @@ private static async Task> FindTypesFromCacheOr { lazy = dictionary.GetOrAdd(key, new AsyncLazy>( - c => GetSymbolKeysAndProjectIdsAsync(solution, findAsync, c), + c => GetSymbolKeysAndProjectIdsAsync(findAsync, c), cacheResult: true)); } @@ -138,8 +139,7 @@ private static async Task> FindTypesFromCacheOr } private static async Task> GetSymbolKeysAndProjectIdsAsync( - Solution solution, - Func>> findAsync, + Func>> findAsync, CancellationToken cancellationToken) { // If we're the code that is actually computing the symbols, then just @@ -147,7 +147,7 @@ private static async Task> FindTypesFromCacheOr // doesn't need to incur the cost of deserializing the symbol keys that // we're create right below this. var result = await findAsync(cancellationToken).ConfigureAwait(false); - return result.SelectAsArray(t => (t.GetSymbolKey(), solution.GetOriginatingProjectId(t))); + return result.SelectAsArray(t => (t.Item1.GetSymbolKey(), t.Item2.Id)); } /// @@ -159,7 +159,7 @@ private static async Task> FindTypesFromCacheOr /// inherit from it that would match this search. /// If this search after finding the direct inherited types that match the provided /// predicate, or if the search should continue recursively using those types as the starting point. - private static async Task> DescendInheritanceTreeAsync( + private static async Task> DescendInheritanceTreeAsync( INamedTypeSymbol type, Solution solution, IImmutableSet projects, @@ -200,9 +200,8 @@ private static async Task> DescendInheritanceTr var orderedProjectsToExamine = GetOrderedProjectsToExamine( solution, projects, projectsThatCouldReferenceType); - // The final set of results we'll be returning. - using var _1 = GetSymbolSet(out var result); + using var _1 = GetSymbolToProjectMap(out var result); // The current total set of matching metadata types in the descendant tree (including the initial type if it // is from metadata). Will be used when examining new types to see if they inherit from any of these. @@ -236,12 +235,12 @@ await DescendInheritanceTreeInProjectAsync( transitive, cancellationToken).ConfigureAwait(false); } - return result.ToImmutableArray(); + return result.SelectAsArray(kvp => (kvp.Key, kvp.Value)); } private static async Task DescendInheritanceTreeInProjectAsync( bool searchInMetadata, - SymbolSet result, + Dictionary result, SymbolSet currentMetadataTypes, SymbolSet currentSourceAndMetadataTypes, Project project, @@ -272,7 +271,7 @@ await AddDescendantMetadataTypesInProjectAsync( // Add all the matches we found to the result set. AssertContents(tempBuffer, assert: s_isInMetadata, "Found type was not from metadata"); - AddRange(tempBuffer, result); + AddRange(tempBuffer, project, result); // Now, if we're doing a transitive search, add these found types to the 'current' sets we're // searching for more results for. These will then be used when searching for more types in the next @@ -299,7 +298,7 @@ await AddDescendantSourceTypesInProjectAsync( // Add all the matches we found to the result set. AssertContents(tempBuffer, assert: s_isInSource, "Found type was not from source"); - AddRange(tempBuffer, result); + AddRange(tempBuffer, project, result); // Now, if we're doing a transitive search, add these types to the currentSourceAndMetadataTypes // set. These will then be used when searching for more types in the next project (which our caller @@ -318,11 +317,11 @@ private static void AssertContents( Debug.Assert(type.Locations.All(assert), message); } - private static void AddRange(SymbolSet foundTypes, SymbolSet result) + private static void AddRange(SymbolSet foundTypes, Project project, Dictionary result) { // Directly enumerate to avoid IEnumerator allocations. foreach (var type in foundTypes) - result.Add(type); + result[type] = project; } private static void AddRange(SymbolSet foundTypes, SymbolSet currentTypes, Func shouldContinueSearching) @@ -722,10 +721,18 @@ private static async Task AddMatchingTypesAsync( public static PooledDisposer> GetSymbolSet(out SymbolSet instance) { - var pooledInstance = s_setPool1.Allocate(); + var pooledInstance = s_symbolSetPool.Allocate(); Debug.Assert(pooledInstance.Count == 0); instance = pooledInstance; return new PooledDisposer>(pooledInstance); } + + public static PooledDisposer> GetSymbolToProjectMap(out Dictionary instance) + { + var pooledInstance = s_symbolToProjectPool.Allocate(); + Debug.Assert(pooledInstance.Count == 0); + instance = pooledInstance; + return new PooledDisposer>(pooledInstance); + } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs index a55c7fb259e76..ceff58dcd9498 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs @@ -49,7 +49,7 @@ private static Task> FindAndCacheDerivedClasses cancellationToken); } - private static Task> FindWithoutCachingDerivedClassesAsync( + private static Task> FindWithoutCachingDerivedClassesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet projects, @@ -68,7 +68,7 @@ static bool TypeMatches(INamedTypeSymbol type, SymbolSet set) cancellationToken: cancellationToken); } - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray<(INamedTypeSymbol, Project)>(); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs index f4a9de0183af5..88c9e04a3b2e5 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs @@ -49,7 +49,7 @@ private static Task> FindAndCacheDerivedInterfa cancellationToken); } - private static Task> FindWithoutCachingDerivedInterfacesAsync( + private static Task> FindWithoutCachingDerivedInterfacesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet projects, @@ -69,7 +69,7 @@ static bool TypeMatches(INamedTypeSymbol type, SymbolSet set) cancellationToken: cancellationToken); } - return SpecializedTasks.EmptyImmutableArray(); + return SpecializedTasks.EmptyImmutableArray<(INamedTypeSymbol, Project)>(); } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs index 5e0ca42c2bdf9..bfc4270ac6fa7 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs @@ -48,7 +48,7 @@ private static Task> FindAndCacheImplementingTy cancellationToken); } - private static async Task> FindWithoutCachingImplementingTypesAsync( + private static async Task> FindWithoutCachingImplementingTypesAsync( INamedTypeSymbol type, Solution solution, IImmutableSet projects, @@ -88,13 +88,13 @@ static bool TypeMatches(INamedTypeSymbol type, SymbolSet set) // FindDerivedInterfacesAsync. Delegates/Enums only happen in a few corner cases. For example, enums // implement IComparable, and delegates implement ICloneable. return allTypes.WhereAsArray( - t => t.TypeKind == TypeKind.Class || - t.TypeKind == TypeKind.Struct || - t.TypeKind == TypeKind.Delegate || - t.TypeKind == TypeKind.Enum); + t => t.Item1.TypeKind == TypeKind.Class || + t.Item1.TypeKind == TypeKind.Struct || + t.Item1.TypeKind == TypeKind.Delegate || + t.Item1.TypeKind == TypeKind.Enum); } - return ImmutableArray.Empty; + return ImmutableArray<(INamedTypeSymbol, Project)>.Empty; } } } From 538110de9b41eb764c6ef0e5eabdc4c38ec14488 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 8 May 2020 11:28:42 -0700 Subject: [PATCH 116/222] NRT --- .../Test2/Rename/RenameEngineTests.vb | 1 + .../FindReferences/DependentProjectsFinder.cs | 2 +- ...DependentTypeFinder.KeyEqualityComparer.cs | 12 +++++---- .../FindReferences/DependentTypeFinder.cs | 26 ++++++++++++------- .../DependentTypeFinder_DerivedClasses.cs | 2 ++ .../DependentTypeFinder_DerivedInterfaces.cs | 2 ++ .../DependentTypeFinder_ImplementingTypes.cs | 2 ++ .../DependentTypeFinder_ProjectIndex.cs | 4 ++- .../DependentTypeFinder_Remote.cs | 4 ++- 9 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb b/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb index 77fdd04a27123..677bdf92e85e3 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineTests.vb @@ -7046,6 +7046,7 @@ class C End Using End Sub + Public Sub RenameTypeParameterFromCRef(host As TestHost) Using result = RenameEngineResult.Create(_outputHelper, diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs index aead66b605f5f..70927b43ebdb4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentProjectsFinder.cs @@ -85,7 +85,7 @@ public bool Equals(DependentProject other) _ => new ConcurrentDictionary>(concurrencyLevel: 2, capacity: 20); public static async Task> GetDependentProjectsAsync( - ISymbol symbol, Solution solution, IImmutableSet projects, CancellationToken cancellationToken) + ISymbol symbol, Solution solution, IImmutableSet? projects, CancellationToken cancellationToken) { if (symbol.Kind == SymbolKind.Namespace) { diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.KeyEqualityComparer.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.KeyEqualityComparer.cs index 19a47af9a4a32..450c31a3d9ee3 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.KeyEqualityComparer.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.KeyEqualityComparer.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using Roslyn.Utilities; @@ -14,7 +16,7 @@ internal static partial class DependentTypeFinder /// Special comparer we need for our cache keys. Necessary because uses /// reference equality and not value-equality semantics. /// - private class KeyEqualityComparer : IEqualityComparer<(SymbolKey, ProjectId, IImmutableSet)> + private class KeyEqualityComparer : IEqualityComparer<(SymbolKey, ProjectId?, IImmutableSet)> { public static readonly KeyEqualityComparer Instance = new KeyEqualityComparer(); @@ -22,8 +24,8 @@ private KeyEqualityComparer() { } - public bool Equals((SymbolKey, ProjectId, IImmutableSet) x, - (SymbolKey, ProjectId, IImmutableSet) y) + public bool Equals((SymbolKey, ProjectId?, IImmutableSet) x, + (SymbolKey, ProjectId?, IImmutableSet) y) { var (xSymbolKey, xProjectId, xProjects) = x; var (ySymbolKey, yProjectId, yProjects) = y; @@ -31,7 +33,7 @@ public bool Equals((SymbolKey, ProjectId, IImmutableSet) x, if (!xSymbolKey.Equals(ySymbolKey)) return false; - if (!xProjectId.Equals(yProjectId)) + if (!Equals(xProjectId, yProjectId)) return false; if (xProjects is null) @@ -43,7 +45,7 @@ public bool Equals((SymbolKey, ProjectId, IImmutableSet) x, return xProjects.SetEquals(yProjects); } - public int GetHashCode((SymbolKey, ProjectId, IImmutableSet) obj) + public int GetHashCode((SymbolKey, ProjectId?, IImmutableSet) obj) { var (symbolKey, projectId, projects) = obj; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs index a0b7dbe95a9ba..13ed6b1c060fc 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -13,6 +15,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Roslyn.Utilities; @@ -22,7 +25,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols // the same operation on the same symbol key might produce different results depending on which project it was found // in. For example, each symbol's project may have a different set of downstream dependent projects. As such, // there may be a different set of related symbols found for each. - using RelatedTypeCache = ConditionalWeakTable), AsyncLazy>>>; + using RelatedTypeCache = ConditionalWeakTable), AsyncLazy>>>; using SymbolSet = HashSet; @@ -40,7 +43,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols /// which has derived type called 'B' somewhere". So when the index is examined for the name 'A', it will say /// 'examine types called 'B' to see if they're an actual match'. /// - /// These links are then continually tranversed to get the full set of results. + /// These links are then continually traversed to get the full set of results. /// internal static partial class DependentTypeFinder { @@ -78,7 +81,7 @@ internal static partial class DependentTypeFinder /// uses reference equality not value equality. /// private static readonly RelatedTypeCache.CreateValueCallback s_createTypeMap = - _ => new ConcurrentDictionary<(SymbolKey, ProjectId, IImmutableSet), AsyncLazy>>(KeyEqualityComparer.Instance); + _ => new ConcurrentDictionary<(SymbolKey, ProjectId?, IImmutableSet), AsyncLazy>>(KeyEqualityComparer.Instance); private static async Task> FindTypesFromCacheOrComputeAsync( INamedTypeSymbol type, @@ -119,7 +122,7 @@ private static async Task> FindTypesFromCacheOr { cancellationToken.ThrowIfCancellationRequested(); - var project = solution.GetProject(group.Key); + var project = solution.GetRequiredProject(group.Key); if (project.SupportsCompilation) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); @@ -446,7 +449,7 @@ private static IEnumerable GetProjectsToExamineWorker( // Finally, because we're searching metadata and source symbols, this needs to be a project // that actually supports compilations. return projectsThatCouldReferenceType.Intersect(allProjectsThatTheseProjectsDependOn) - .Select(solution.GetProject) + .Select(id => solution.GetRequiredProject(id)) .Where(p => p.SupportsCompilation) .ToList(); } @@ -465,7 +468,7 @@ private static async Task AddDescendantMetadataTypesInProjectAsync( if (currentMetadataTypes.Count == 0) return; - var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); using var _1 = GetSymbolSet(out var typesToSearchFor); using var _2 = GetSymbolSet(out var tempBuffer); @@ -536,7 +539,10 @@ private static async Task AddMatchingMetadataTypesInMetadataReferenceAsync( } private static bool TypeHasBaseTypeInSet(INamedTypeSymbol type, SymbolSet set) - => set.Contains(type.BaseType?.OriginalDefinition); + { + var baseType = type.BaseType?.OriginalDefinition; + return baseType != null && set.Contains(baseType); + } private static bool TypeHasInterfaceInSet(INamedTypeSymbol type, SymbolSet set) { @@ -675,7 +681,7 @@ private static async Task AddSourceTypesThatDeriveFromNameAsync( { cancellationToken.ThrowIfCancellationRequested(); - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); cachedModels.Add(semanticModel); var resolvedType = info.TryResolve(semanticModel, cancellationToken); @@ -691,7 +697,7 @@ private static async Task AddMatchingTypesAsync( ConcurrentSet cachedModels, MultiDictionary documentToInfos, SymbolSet result, - Func predicateOpt, + Func? predicateOpt, CancellationToken cancellationToken) { foreach (var (document, infos) in documentToInfos) @@ -699,7 +705,7 @@ private static async Task AddMatchingTypesAsync( cancellationToken.ThrowIfCancellationRequested(); Debug.Assert(infos.Count > 0); - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); cachedModels.Add(semanticModel); foreach (var info in infos) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs index ceff58dcd9498..01dec9a517b21 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedClasses.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs index 88c9e04a3b2e5..f14ba44c3de3d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_DerivedInterfaces.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs index bfc4270ac6fa7..aa82390db9afb 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ProjectIndex.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ProjectIndex.cs index 8a593d22b604e..4b79463191b5e 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ProjectIndex.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ProjectIndex.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -54,7 +56,7 @@ private static async Task CreateIndexAsync(Project project, Cancel var delegates = new MultiDictionary(); var namedTypes = new MultiDictionary( - project.LanguageServices.GetService().StringComparer); + project.LanguageServices.GetRequiredService().StringComparer); foreach (var document in project.Documents) { diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_Remote.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_Remote.cs index 17afd00aea98d..b6d491714a587 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_Remote.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_Remote.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -35,7 +37,7 @@ internal static partial class DependentTypeFinder WellKnownServiceHubServices.CodeAnalysisService, remoteFunctionName, solution, - new object[] + new object?[] { SerializableSymbolAndProjectId.Create(type, project, cancellationToken), projects?.Select(p => p.Id).ToArray(), From 5eccec0808879d82b45f8383d7a1bfb9ee7adb4b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 8 May 2020 12:44:05 -0700 Subject: [PATCH 117/222] use named params --- .../FindSymbols/FindReferences/DependentTypeFinder.cs | 8 ++++---- .../DependentTypeFinder_ImplementingTypes.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs index 13ed6b1c060fc..ef82891ae14bf 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder.cs @@ -88,7 +88,7 @@ private static async Task> FindTypesFromCacheOr Solution solution, IImmutableSet projects, RelatedTypeCache cache, - Func>> findAsync, + Func>> findAsync, CancellationToken cancellationToken) { var dictionary = cache.GetValue(solution, s_createTypeMap); @@ -142,7 +142,7 @@ private static async Task> FindTypesFromCacheOr } private static async Task> GetSymbolKeysAndProjectIdsAsync( - Func>> findAsync, + Func>> findAsync, CancellationToken cancellationToken) { // If we're the code that is actually computing the symbols, then just @@ -150,7 +150,7 @@ private static async Task> FindTypesFromCacheOr // doesn't need to incur the cost of deserializing the symbol keys that // we're create right below this. var result = await findAsync(cancellationToken).ConfigureAwait(false); - return result.SelectAsArray(t => (t.Item1.GetSymbolKey(), t.Item2.Id)); + return result.SelectAsArray(t => (t.type.GetSymbolKey(), t.project.Id)); } /// @@ -162,7 +162,7 @@ private static async Task> FindTypesFromCacheOr /// inherit from it that would match this search. /// If this search after finding the direct inherited types that match the provided /// predicate, or if the search should continue recursively using those types as the starting point. - private static async Task> DescendInheritanceTreeAsync( + private static async Task> DescendInheritanceTreeAsync( INamedTypeSymbol type, Solution solution, IImmutableSet projects, diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs index aa82390db9afb..6e2922610021a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/DependentTypeFinder_ImplementingTypes.cs @@ -90,10 +90,10 @@ static bool TypeMatches(INamedTypeSymbol type, SymbolSet set) // FindDerivedInterfacesAsync. Delegates/Enums only happen in a few corner cases. For example, enums // implement IComparable, and delegates implement ICloneable. return allTypes.WhereAsArray( - t => t.Item1.TypeKind == TypeKind.Class || - t.Item1.TypeKind == TypeKind.Struct || - t.Item1.TypeKind == TypeKind.Delegate || - t.Item1.TypeKind == TypeKind.Enum); + t => t.type.TypeKind == TypeKind.Class || + t.type.TypeKind == TypeKind.Struct || + t.type.TypeKind == TypeKind.Delegate || + t.type.TypeKind == TypeKind.Enum); } return ImmutableArray<(INamedTypeSymbol, Project)>.Empty; From ee3698de018b8fe11c289cb0158d18289310d98c Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Fri, 8 May 2020 15:36:05 -0700 Subject: [PATCH 118/222] Address review comments --- eng/Versions.props | 1 + .../AnalyzerRunner/AnalyzerRunnerHelper.cs | 15 +++--- .../DiagnosticAnalyzerRunner.cs | 10 ++-- src/Tools/AnalyzerRunner/Program.cs | 31 ++++++------ .../CSharpIdeAnalyzerBenchmarks.cs | 7 ++- .../IdeCoreBenchmarks.csproj | 5 +- .../IncrementalAnalyzerBenchmarks.cs | 5 +- src/Tools/IdeCoreBenchmarks/Program.cs | 7 --- .../SerializationBenchmarks.cs | 47 ++++++++++++++++--- 9 files changed, 80 insertions(+), 48 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index d781e7d67f61c..b041730e03014 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -189,6 +189,7 @@ 0.0.4 1.0.21 4.5.1 + 4.7.0 4.5.0 4.5.0 4.3.0 diff --git a/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs b/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs index 02ce3865d2ed3..a8cce257125e4 100644 --- a/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs +++ b/src/Tools/AnalyzerRunner/AnalyzerRunnerHelper.cs @@ -30,24 +30,21 @@ static AnalyzerRunnerHelper() MSBuildLocator.RegisterInstance(msBuildInstance); } - public static async Task LoadSolutionAsync(string solutionPath, CancellationToken cancellationToken) + public static MSBuildWorkspace CreateWorkspace() { var properties = new Dictionary { #if NETCOREAPP - // This property ensures that XAML files will be compiled in the current AppDomain - // rather than a separate one. Any tasks isolated in AppDomains or tasks that create - // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. - { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, + // This property ensures that XAML files will be compiled in the current AppDomain + // rather than a separate one. Any tasks isolated in AppDomains or tasks that create + // AppDomains will likely not work due to https://github.com/Microsoft/MSBuildLocator/issues/16. + { "AlwaysCompileMarkupFilesInSeparateDomain", bool.FalseString }, #endif // Use the latest language version to force the full set of available analyzers to run on the project. { "LangVersion", "latest" }, }; - var workspace = MSBuildWorkspace.Create(properties, AnalyzerRunnerMefHostServices.DefaultServices); - var solution = await workspace.OpenSolutionAsync(solutionPath, progress: null, cancellationToken).ConfigureAwait(false); - - return workspace; + return MSBuildWorkspace.Create(properties, AnalyzerRunnerMefHostServices.DefaultServices); } } } diff --git a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs index 04e340c1e3839..20ff953ba976e 100644 --- a/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs +++ b/src/Tools/AnalyzerRunner/DiagnosticAnalyzerRunner.cs @@ -19,13 +19,13 @@ namespace AnalyzerRunner { public sealed class DiagnosticAnalyzerRunner { - private readonly Solution _solution; + private readonly Workspace _workspace; private readonly Options _options; private readonly ImmutableDictionary> _analyzers; - public DiagnosticAnalyzerRunner(Solution solution, Options options) + public DiagnosticAnalyzerRunner(Workspace workspace, Options options) { - _solution = solution; + _workspace = workspace; _options = options; var analyzers = GetDiagnosticAnalyzers(options.AnalyzerPath); @@ -60,7 +60,7 @@ public async Task RunAsync(CancellationToken cancellationToken) return; } - var solution = _solution; + var solution = _workspace.CurrentSolution; solution = SetOptions(solution); await GetAnalysisResultAsync(solution, _analyzers, _options, cancellationToken).ConfigureAwait(false); @@ -74,7 +74,7 @@ internal async Task RunAllAsync(CancellationToken cancellationToken) return; } - var solution = _solution; + var solution = _workspace.CurrentSolution; solution = SetOptions(solution); diff --git a/src/Tools/AnalyzerRunner/Program.cs b/src/Tools/AnalyzerRunner/Program.cs index ad9002bbeb656..a18f2672c924b 100644 --- a/src/Tools/AnalyzerRunner/Program.cs +++ b/src/Tools/AnalyzerRunner/Program.cs @@ -47,14 +47,13 @@ public static async Task Main(string[] args) var cancellationToken = cts.Token; - var stopwatch = PerformanceTracker.StartNew(); - if (!string.IsNullOrEmpty(options.ProfileRoot)) { - ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync)); + Directory.CreateDirectory(options.ProfileRoot); + ProfileOptimization.SetProfileRoot(options.ProfileRoot); } - using var workspace = await AnalyzerRunnerHelper.LoadSolutionAsync(options.SolutionPath, cancellationToken).ConfigureAwait(false); + using var workspace = AnalyzerRunnerHelper.CreateWorkspace(); foreach (var workspaceDiagnostic in workspace.Diagnostics) { @@ -64,10 +63,8 @@ public static async Task Main(string[] args) } } - Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); - var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(workspace, options); - var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(workspace.CurrentSolution, options); + var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(workspace, options); var codeRefactoringRunner = new CodeRefactoringRunner(workspace, options); if (!incrementalAnalyzerRunner.HasAnalyzers && !diagnosticAnalyzerRunner.HasAnalyzers && !codeRefactoringRunner.HasRefactorings) @@ -77,6 +74,15 @@ public static async Task Main(string[] args) return; } + var stopwatch = PerformanceTracker.StartNew(); + + if (!string.IsNullOrEmpty(options.ProfileRoot)) + { + ProfileOptimization.StartProfile(nameof(MSBuildWorkspace.OpenSolutionAsync)); + } + + await workspace.OpenSolutionAsync(options.SolutionPath, progress: null, cancellationToken).ConfigureAwait(false); + if (options.ShowStats) { stopwatch = PerformanceTracker.StartNew(); @@ -84,6 +90,8 @@ public static async Task Main(string[] args) Console.WriteLine($"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"); } + Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); + if (options.ShowCompilerDiagnostics) { await ShowCompilerDiagnosticsAsync(workspace.CurrentSolution, cancellationToken).ConfigureAwait(false); @@ -163,19 +171,12 @@ private static async Task ShowCompilerDiagnosticsAsync(Solution solution, Cancel private static void ShowSolutionStatistics(Solution solution, CancellationToken cancellationToken) { - var sums = new ConcurrentBag(); var projects = solution.Projects.Where(project => project.Language == LanguageNames.CSharp || project.Language == LanguageNames.VisualBasic).ToList(); Console.WriteLine("Number of projects:\t\t" + projects.Count); Console.WriteLine("Number of documents:\t\t" + projects.Sum(x => x.DocumentIds.Count)); - Parallel.ForEach(projects.SelectMany(project => project.Documents), document => - { - var documentStatistics = GetSolutionStatisticsAsync(document, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult(); - sums.Add(documentStatistics); - }); - - var statistics = sums.Aggregate(new Statistic(0, 0, 0), (currentResult, value) => currentResult + value); + var statistics = GetSolutionStatistics(projects, cancellationToken); Console.WriteLine("Number of syntax nodes:\t\t" + statistics.NumberofNodes); Console.WriteLine("Number of syntax tokens:\t" + statistics.NumberOfTokens); diff --git a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs index bc42291886ff9..a2921bf95b144 100644 --- a/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs +++ b/src/Tools/IdeCoreBenchmarks/CSharpIdeAnalyzerBenchmarks.cs @@ -11,6 +11,7 @@ using AnalyzerRunner; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Diagnosers; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.MSBuild; namespace IdeCoreBenchmarks @@ -59,8 +60,10 @@ public void Setup() fullSolutionAnalysis: false, incrementalAnalyzerNames: ImmutableArray.Empty); - _workspace = AnalyzerRunnerHelper.LoadSolutionAsync(_solutionPath, CancellationToken.None).Result; - _diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(_workspace.CurrentSolution, _options); + _workspace = AnalyzerRunnerHelper.CreateWorkspace(); + _diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(_workspace, _options); + + _ = _workspace.OpenSolutionAsync(_solutionPath, progress: null, CancellationToken.None).Result; } [GlobalCleanup] diff --git a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj index 4abf326151442..b04d7c1113a19 100644 --- a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj +++ b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj @@ -5,7 +5,7 @@ Exe - net472;netcoreapp3.1 + $(RoslynPortableTargetFrameworks) false AnyCPU @@ -14,11 +14,12 @@ + - + diff --git a/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs index f57f931c2a449..408674f170b4f 100644 --- a/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs +++ b/src/Tools/IdeCoreBenchmarks/IncrementalAnalyzerBenchmarks.cs @@ -16,7 +16,6 @@ namespace IdeCoreBenchmarks { [MemoryDiagnoser] - [RyuJitX64Job] public class IncrementalAnalyzerBenchmarks { private readonly string _solutionPath; @@ -59,8 +58,10 @@ public void Setup() fullSolutionAnalysis: true, incrementalAnalyzerNames: ImmutableArray.Create(AnalyzerName)); - _workspace = AnalyzerRunnerHelper.LoadSolutionAsync(_solutionPath, CancellationToken.None).Result; + _workspace = AnalyzerRunnerHelper.CreateWorkspace(); _incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(_workspace, _options); + + _ = _workspace.OpenSolutionAsync(_solutionPath, progress: null, CancellationToken.None).Result; } [IterationCleanup] diff --git a/src/Tools/IdeCoreBenchmarks/Program.cs b/src/Tools/IdeCoreBenchmarks/Program.cs index 915b01334c9b1..2e709e94023a9 100644 --- a/src/Tools/IdeCoreBenchmarks/Program.cs +++ b/src/Tools/IdeCoreBenchmarks/Program.cs @@ -3,20 +3,13 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Immutable; using System.IO; using System.Linq; -using System.Reflection; using System.Runtime.CompilerServices; -using System.Threading; -using System.Threading.Tasks; -using AnalyzerRunner; -using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Running; using BenchmarkDotNet.Validators; -using Microsoft.CodeAnalysis.MSBuild; namespace IdeCoreBenchmarks { diff --git a/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs index d0b44de82e81a..3e6cefbe4e831 100644 --- a/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs +++ b/src/Tools/IdeCoreBenchmarks/SerializationBenchmarks.cs @@ -15,6 +15,9 @@ namespace IdeCoreBenchmarks public class SerializationBenchmarks { private CompilationUnitSyntax _root; + private MemoryStream _stream; + + private readonly int _iterationCount = 10; [GlobalSetup] public void GlobalSetup() @@ -32,16 +35,48 @@ public void GlobalSetup() _root = tree.GetCompilationUnitRoot(); } + [IterationCleanup] + public void SerializationCleanup() + { + _stream?.Dispose(); + } + + [IterationSetup(Target = nameof(SerializeSyntaxNode))] + public void SerializationSetup() + { + _stream = new MemoryStream(); + } + [Benchmark] - public void RoundTripSyntaxNode() + public void SerializeSyntaxNode() + { + for (var i = 0; i < _iterationCount; ++i) + { + _root.SerializeTo(_stream); + } + } + + [IterationSetup(Target = nameof(DeserializeSyntaxNode))] + public void DeserializationSetup() { - var stream = new MemoryStream(); - _root.SerializeTo(stream); + _stream = new MemoryStream(); + + for (var i = 0; i < _iterationCount; ++i) + { + _root.SerializeTo(_stream); + } - stream.Position = 0; + _stream.Position = 0; + } - var droot = CSharpSyntaxNode.DeserializeFrom(stream); - var nodes = droot.DescendantNodesAndSelf().ToImmutableArray(); + [Benchmark] + public void DeserializeSyntaxNode() + { + for (var i = 0; i < _iterationCount; ++i) + { + var droot = CSharpSyntaxNode.DeserializeFrom(_stream); + _ = droot.DescendantNodesAndSelf().ToImmutableArray(); + } } } } From d87967a62229bbd78034febe67eac85854d3e5ac Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Fri, 8 May 2020 15:48:09 -0700 Subject: [PATCH 119/222] More fix --- src/Tools/AnalyzerRunner/Program.cs | 16 ++++++++-------- .../IdeCoreBenchmarks/IdeCoreBenchmarks.csproj | 5 +---- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Tools/AnalyzerRunner/Program.cs b/src/Tools/AnalyzerRunner/Program.cs index a18f2672c924b..cbacc400be242 100644 --- a/src/Tools/AnalyzerRunner/Program.cs +++ b/src/Tools/AnalyzerRunner/Program.cs @@ -55,14 +55,6 @@ public static async Task Main(string[] args) using var workspace = AnalyzerRunnerHelper.CreateWorkspace(); - foreach (var workspaceDiagnostic in workspace.Diagnostics) - { - if (workspaceDiagnostic.Kind == WorkspaceDiagnosticKind.Failure) - { - Console.WriteLine(workspaceDiagnostic.Message); - } - } - var incrementalAnalyzerRunner = new IncrementalAnalyzerRunner(workspace, options); var diagnosticAnalyzerRunner = new DiagnosticAnalyzerRunner(workspace, options); var codeRefactoringRunner = new CodeRefactoringRunner(workspace, options); @@ -83,6 +75,14 @@ public static async Task Main(string[] args) await workspace.OpenSolutionAsync(options.SolutionPath, progress: null, cancellationToken).ConfigureAwait(false); + foreach (var workspaceDiagnostic in workspace.Diagnostics) + { + if (workspaceDiagnostic.Kind == WorkspaceDiagnosticKind.Failure) + { + Console.WriteLine(workspaceDiagnostic.Message); + } + } + if (options.ShowStats) { stopwatch = PerformanceTracker.StartNew(); diff --git a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj index b04d7c1113a19..d0a8ce01adf4f 100644 --- a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj +++ b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj @@ -14,12 +14,9 @@ - - - - + From b1710c43919ff3f4db5f8bebce759934e19aa217 Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 8 May 2020 15:54:02 -0700 Subject: [PATCH 120/222] Move the MetadataAsSourceFileService down to the features layer None of this actually depended on the editor in any meaningful way. --- .../CSharpDecompiledSourceService.cs | 1 + .../CSharpDecompiledSourceServiceFactory.cs | 1 + .../Core/EditorFeaturesResources.resx | 9 --------- .../Peek/DefinitionPeekableItem.cs | 1 + .../Implementation/Peek/PeekableItemFactory.cs | 1 + .../Core/xlf/EditorFeaturesResources.cs.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.de.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.es.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.fr.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.it.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.ja.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.ko.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.pl.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.pt-BR.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.ru.xlf | 15 --------------- .../Core/xlf/EditorFeaturesResources.tr.xlf | 15 --------------- .../xlf/EditorFeaturesResources.zh-Hans.xlf | 15 --------------- .../xlf/EditorFeaturesResources.zh-Hant.xlf | 15 --------------- ...AbstractMetadataAsSourceTests.TestContext.cs | 12 ++++++------ src/EditorFeatures/Test2/Peek/PeekTests.vb | 12 ++++++------ .../TestUtilities/Workspaces/TestWorkspace.cs | 1 + .../IDecompiledSourceService.cs | 2 +- .../Core/Portable/FeaturesResources.resx | 9 +++++++++ .../IMetadataAsSourceFileService.cs | 6 +++--- .../MetadataAsSource}/MetadataAsSourceFile.cs | 3 +-- .../MetadataAsSourceFileService.cs | 17 ++++++++--------- .../MetadataAsSourceGeneratedFileInfo.cs | 2 +- .../MetadataAsSourceWorkspace.cs | 2 +- .../SymbolMappingServiceFactory.cs | 4 ++-- .../Core/Portable/xlf/FeaturesResources.cs.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.de.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.es.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.fr.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.it.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.ja.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.ko.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.pl.xlf | 15 +++++++++++++++ .../Portable/xlf/FeaturesResources.pt-BR.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.ru.xlf | 15 +++++++++++++++ .../Core/Portable/xlf/FeaturesResources.tr.xlf | 15 +++++++++++++++ .../Portable/xlf/FeaturesResources.zh-Hans.xlf | 15 +++++++++++++++ .../Portable/xlf/FeaturesResources.zh-Hant.xlf | 15 +++++++++++++++ .../Definitions/GoToDefinitionHandler.cs | 2 +- .../Definitions/GoToDefinitionHandlerBase.cs | 1 + .../Definitions/GoToTypeDefinitionHandler.cs | 2 +- .../MiscellaneousFilesWorkspace.cs | 4 ++-- ...lStudioMetadataAsSourceFileSupportService.cs | 1 + .../VisualStudioSymbolNavigationService.cs | 3 ++- ...oToDefinitionWithFindUsagesServiceHandler.cs | 8 ++++---- ...itionWithFindUsagesServiceHandler.Exports.cs | 2 +- 50 files changed, 251 insertions(+), 245 deletions(-) rename src/{EditorFeatures/Core => Features/Core/Portable/DecompiledSource}/IDecompiledSourceService.cs (96%) rename src/{EditorFeatures/Core => Features/Core/Portable/MetadataAsSource}/IMetadataAsSourceFileService.cs (90%) rename src/{EditorFeatures/Core => Features/Core/Portable/MetadataAsSource}/MetadataAsSourceFile.cs (95%) rename src/{EditorFeatures/Core/Implementation => Features/Core/Portable}/MetadataAsSource/MetadataAsSourceFileService.cs (97%) rename src/{EditorFeatures/Core/Implementation => Features/Core/Portable}/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs (98%) rename src/{EditorFeatures/Core/Implementation => Features/Core/Portable}/MetadataAsSource/MetadataAsSourceWorkspace.cs (89%) rename src/{EditorFeatures/Core/Implementation => Features/Core/Portable}/MetadataAsSource/SymbolMappingServiceFactory.cs (88%) diff --git a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs index e08b3127feeb8..9bf07a6956b0d 100644 --- a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs +++ b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs @@ -20,6 +20,7 @@ using ICSharpCode.Decompiler.TypeSystem; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.DocumentationComments; +using Microsoft.CodeAnalysis.DecompiledSource; using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Formatting; diff --git a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs index 8e44d2379a2f8..fc355bb5f406d 100644 --- a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs +++ b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceServiceFactory.cs @@ -4,6 +4,7 @@ using System; using System.Composition; +using Microsoft.CodeAnalysis.DecompiledSource; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; diff --git a/src/EditorFeatures/Core/EditorFeaturesResources.resx b/src/EditorFeatures/Core/EditorFeaturesResources.resx index b7547c24a72fb..fbdd2c647cb39 100644 --- a/src/EditorFeatures/Core/EditorFeaturesResources.resx +++ b/src/EditorFeatures/Core/EditorFeaturesResources.resx @@ -267,9 +267,6 @@ Given Workspace doesn't support Undo - - Document must be contained in the workspace that created this service - Searching... @@ -366,9 +363,6 @@ Preview Warning - - from metadata - Automatic Line Ender @@ -588,9 +582,6 @@ Peek - - 'symbol' cannot be a namespace. - _Apply diff --git a/src/EditorFeatures/Core/Implementation/Peek/DefinitionPeekableItem.cs b/src/EditorFeatures/Core/Implementation/Peek/DefinitionPeekableItem.cs index 06888aa499f2a..78df4d412e7c8 100644 --- a/src/EditorFeatures/Core/Implementation/Peek/DefinitionPeekableItem.cs +++ b/src/EditorFeatures/Core/Implementation/Peek/DefinitionPeekableItem.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.VisualStudio.Language.Intellisense; using Roslyn.Utilities; diff --git a/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs b/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs index 27ea061e1c0a5..6b38d69012bee 100644 --- a/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs +++ b/src/EditorFeatures/Core/Implementation/Peek/PeekableItemFactory.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.Editor.Peek; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Language.Intellisense; diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf index db346104b14e3..79f1231137c5a 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.cs.xlf @@ -487,11 +487,6 @@ Daný pracovní prostor nepodporuje vrácení akce zpátky. - - Document must be contained in the workspace that created this service - Dokument musí být obsažený v pracovním prostoru, který vytvořil tuto datovou službu - - Searching... Hledá se... @@ -657,11 +652,6 @@ (external) - - from metadata - z metadat - - Automatic Line Ender Automatický ukončovač řádků @@ -1017,11 +1007,6 @@ Náhled - - 'symbol' cannot be a namespace. - 'Symbol nemůže být obor názvů. - - _Apply _Aplikovat diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf index 1cfb58b2e9e69..bc96d0412bad8 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.de.xlf @@ -487,11 +487,6 @@ Angegebener Arbeitsbereich unterstützt die Funktion "Rückgängig" nicht - - Document must be contained in the workspace that created this service - Dokument muss in dem Arbeitsbereich enthalten sein, der diesen Dienst erstellt hat - - Searching... Suche läuft... @@ -657,11 +652,6 @@ (external) - - from metadata - aus Metadaten - - Automatic Line Ender Automatisches Zeilenende @@ -1017,11 +1007,6 @@ Vorschau - - 'symbol' cannot be a namespace. - '"symbol" kann kein Namespace sein. - - _Apply Ü_bernehmen diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf index ae54c76f41cf8..e536d93057783 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.es.xlf @@ -487,11 +487,6 @@ El área de trabajo dada no permite deshacer - - Document must be contained in the workspace that created this service - El documento debe estar contenido en el área de trabajo que creó este servicio - - Searching... Buscando... @@ -657,11 +652,6 @@ (external) - - from metadata - de metadatos - - Automatic Line Ender Finalizador de líneas automático @@ -1017,11 +1007,6 @@ Ver - - 'symbol' cannot be a namespace. - 'símbolo' no puede ser un espacio de nombres. - - _Apply _Aplicar diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf index d7db5431da5d4..99758b5aab927 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.fr.xlf @@ -487,11 +487,6 @@ L'espace de travail donné ne prend pas en charge la fonction Annuler - - Document must be contained in the workspace that created this service - Le document doit être contenu dans l'espace de travail qui a créé ce service - - Searching... Recherche... @@ -657,11 +652,6 @@ (external) - - from metadata - à partir des métadonnées - - Automatic Line Ender Fin de ligne automatique @@ -1017,11 +1007,6 @@ Aperçu - - 'symbol' cannot be a namespace. - 'symbol' ne peut pas être un espace de noms. - - _Apply _Appliquer diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf index f9032c421c7fb..626fb72a26e73 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.it.xlf @@ -487,11 +487,6 @@ L'area di lavoro specificata non supporta l'annullamento di operazioni - - Document must be contained in the workspace that created this service - Il documento deve essere contenuto nell'area di lavoro che ha creato il servizio - - Searching... Ricerca... @@ -657,11 +652,6 @@ (external) - - from metadata - da metadati - - Automatic Line Ender Fine riga automatico @@ -1017,11 +1007,6 @@ Anteprima - - 'symbol' cannot be a namespace. - 'L'elemento 'symbol' non può essere uno spazio dei nomi. - - _Apply _Applica diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf index 17ccb3e7d89e2..5cb0ef7fd7cba 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ja.xlf @@ -487,11 +487,6 @@ 指定されたワークスペースは元に戻す操作をサポートしていません - - Document must be contained in the workspace that created this service - このサービスを作成したワークスペースにドキュメントが含まれている必要があります - - Searching... 検索しています... @@ -657,11 +652,6 @@ (external) - - from metadata - メタデータから - - Automatic Line Ender 行の自動終了 @@ -1017,11 +1007,6 @@ ピーク - - 'symbol' cannot be a namespace. - 'symbol' は名前空間にすることはできません。 - - _Apply 適用(_A) diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf index a257075022332..6dfc253516dc4 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ko.xlf @@ -487,11 +487,6 @@ 지정한 작업 영역에서 실행을 취소할 수 없습니다. - - Document must be contained in the workspace that created this service - 문서가 이 서비스를 만든 작업 영역에 포함되어 있어야 합니다. - - Searching... 검색 중... @@ -657,11 +652,6 @@ (external) - - from metadata - 메타데이터에서 - - Automatic Line Ender 자동 줄 끝내기 @@ -1017,11 +1007,6 @@ 피킹 - - 'symbol' cannot be a namespace. - '기호'는 네임스페이스일 수 없습니다. - - _Apply 적용(_A) diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf index df62615a07981..d83743673db9c 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pl.xlf @@ -487,11 +487,6 @@ Dany obszar roboczy nie obsługuje operacji cofania - - Document must be contained in the workspace that created this service - Dokument musi się znajdować w obszarze roboczym użytym do utworzenia tej usługi - - Searching... Trwa wyszukiwanie... @@ -657,11 +652,6 @@ (external) - - from metadata - z metadanych - - Automatic Line Ender Automatyczne kończenie wiersza @@ -1017,11 +1007,6 @@ Wgląd - - 'symbol' cannot be a namespace. - 'Element „symbol” nie może być przestrzenią nazw. - - _Apply _Zastosuj diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf index 3f37e9a332ce8..b01a0687951ec 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.pt-BR.xlf @@ -487,11 +487,6 @@ Workspace fornecido não suporta Desfazer - - Document must be contained in the workspace that created this service - O Documento deve estar contido no workspace que criou este serviço - - Searching... Pesquisando... @@ -657,11 +652,6 @@ (external) - - from metadata - de metadados - - Automatic Line Ender Finalizador de Linha Automático @@ -1017,11 +1007,6 @@ Espiada - - 'symbol' cannot be a namespace. - '"símbolo" não pode ser um namespace. - - _Apply _Aplicar diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf index 636debb8f1f22..3c00d9badd792 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.ru.xlf @@ -487,11 +487,6 @@ Заданная рабочая область не поддерживает отмену - - Document must be contained in the workspace that created this service - Документ должен находиться в рабочей области, в которой была создана эта служба. - - Searching... Идет поиск... @@ -657,11 +652,6 @@ (external) - - from metadata - из метаданных - - Automatic Line Ender Автоматическое окончание строки @@ -1017,11 +1007,6 @@ Обзор - - 'symbol' cannot be a namespace. - '"символ" не может быть пространством имен. - - _Apply _Применить diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf index a064d2b3bc659..3a6557142bd37 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.tr.xlf @@ -487,11 +487,6 @@ Verilen Çalışma Alanı, Geri Alma'yı desteklemez - - Document must be contained in the workspace that created this service - Belge, bu hizmeti oluşturan çalışma alanında yer almalıdır - - Searching... Aranıyor... @@ -657,11 +652,6 @@ (external) - - from metadata - meta verilerden - - Automatic Line Ender Otomatik Satır Sonlandırıcısı @@ -1017,11 +1007,6 @@ Göz At - - 'symbol' cannot be a namespace. - 'symbol' bir ad alanı olamaz. - - _Apply _Uygula diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf index 11e14e4e87b82..2317a44e0a985 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hans.xlf @@ -487,11 +487,6 @@ 给定的工作区不支持撤销 - - Document must be contained in the workspace that created this service - 文件必须包含在创建此服务的工作区中 - - Searching... 正在搜索... @@ -657,11 +652,6 @@ (external) - - from metadata - 从元数据 - - Automatic Line Ender 最终自动行 @@ -1017,11 +1007,6 @@ 快速查看 - - 'symbol' cannot be a namespace. - '“symbol” 不能为命名空间。 - - _Apply 应用(_A) diff --git a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf index f87608676c14d..87cdeb6433019 100644 --- a/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf +++ b/src/EditorFeatures/Core/xlf/EditorFeaturesResources.zh-Hant.xlf @@ -487,11 +487,6 @@ 指定的工作區不支援復原 - - Document must be contained in the workspace that created this service - 文件必須包含在此服務所建立的工作區中 - - Searching... 正在搜尋... @@ -657,11 +652,6 @@ (external) - - from metadata - 來自中繼資料 - - Automatic Line Ender 自動加入行尾工具 @@ -1017,11 +1007,6 @@ 查看 - - 'symbol' cannot be a namespace. - 'symbol' 不可為命名空間。 - - _Apply 套用(_A) diff --git a/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs b/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs index 4206d8aab5f9f..56f6a6243ed1c 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; using Roslyn.Test.Utilities; @@ -27,7 +28,6 @@ internal class TestContext : IDisposable { private readonly TestWorkspace _workspace; private readonly IMetadataAsSourceFileService _metadataAsSourceService; - private readonly ITextBufferFactoryService _textBufferFactoryService; public static TestContext Create( string projectLanguage = null, @@ -53,7 +53,6 @@ public TestContext(TestWorkspace workspace) { _workspace = workspace; _metadataAsSourceService = _workspace.GetService(); - _textBufferFactoryService = _workspace.GetService(); } public Solution CurrentSolution @@ -255,12 +254,13 @@ private static TestWorkspace CreateWorkspace( internal Document GetDocument(MetadataAsSourceFile file) { - using var reader = new StreamReader(file.FilePath); - var textBuffer = _textBufferFactoryService.CreateTextBuffer(reader, _textBufferFactoryService.TextContentType); + using var reader = File.OpenRead(file.FilePath); + var stringText = EncodedStringText.Create(reader); - Assert.True(_metadataAsSourceService.TryAddDocumentToWorkspace(file.FilePath, textBuffer)); - return textBuffer.AsTextContainer().GetRelatedDocuments().Single(); + Assert.True(_metadataAsSourceService.TryAddDocumentToWorkspace(file.FilePath, stringText.Container)); + + return stringText.Container.GetRelatedDocuments().Single(); } internal async Task GetNavigationSymbolAsync() diff --git a/src/EditorFeatures/Test2/Peek/PeekTests.vb b/src/EditorFeatures/Test2/Peek/PeekTests.vb index d7058f44ddb5b..4036a19e7b4f7 100644 --- a/src/EditorFeatures/Test2/Peek/PeekTests.vb +++ b/src/EditorFeatures/Test2/Peek/PeekTests.vb @@ -57,8 +57,8 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Peek Dim result = GetPeekResultCollection(workspace) Assert.Equal(1, result.Items.Count) - Assert.Equal($"String [{EditorFeaturesResources.from_metadata}]", result(0).DisplayInfo.Label) - Assert.Equal($"String [{EditorFeaturesResources.from_metadata}]", result(0).DisplayInfo.Title) + Assert.Equal($"String [{FeaturesResources.from_metadata}]", result(0).DisplayInfo.Label) + Assert.Equal($"String [{FeaturesResources.from_metadata}]", result(0).DisplayInfo.Title) Assert.True(result.GetRemainingIdentifierLineTextOnDisk(index:=0).StartsWith("String", StringComparison.Ordinal)) End Using End Sub @@ -75,8 +75,8 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Peek Dim result = GetPeekResultCollection(workspace) Assert.Equal(1, result.Items.Count) - Assert.Equal($"Enumerable [{EditorFeaturesResources.from_metadata}]", result(0).DisplayInfo.Label) - Assert.Equal($"Enumerable [{EditorFeaturesResources.from_metadata}]", result(0).DisplayInfo.Title) + Assert.Equal($"Enumerable [{FeaturesResources.from_metadata}]", result(0).DisplayInfo.Label) + Assert.Equal($"Enumerable [{FeaturesResources.from_metadata}]", result(0).DisplayInfo.Title) Assert.True(result.GetRemainingIdentifierLineTextOnDisk(index:=0).StartsWith("Distinct", StringComparison.Ordinal)) End Using End Sub @@ -95,8 +95,8 @@ End Class Dim result = GetPeekResultCollection(workspace) Assert.Equal(1, result.Items.Count) - Assert.Equal($"SerializableAttribute [{EditorFeaturesResources.from_metadata}]", result(0).DisplayInfo.Label) - Assert.Equal($"SerializableAttribute [{EditorFeaturesResources.from_metadata}]", result(0).DisplayInfo.Title) + Assert.Equal($"SerializableAttribute [{FeaturesResources.from_metadata}]", result(0).DisplayInfo.Label) + Assert.Equal($"SerializableAttribute [{FeaturesResources.from_metadata}]", result(0).DisplayInfo.Title) Assert.True(result.GetRemainingIdentifierLineTextOnDisk(index:=0).StartsWith("New()", StringComparison.Ordinal)) ' Navigates to constructor End Using End Sub diff --git a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs index b64cba4842d2d..afeedcedc2856 100644 --- a/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs +++ b/src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs @@ -14,6 +14,7 @@ using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Notification; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; diff --git a/src/EditorFeatures/Core/IDecompiledSourceService.cs b/src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs similarity index 96% rename from src/EditorFeatures/Core/IDecompiledSourceService.cs rename to src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs index ee97a40f89a58..63983642153bc 100644 --- a/src/EditorFeatures/Core/IDecompiledSourceService.cs +++ b/src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Host; -namespace Microsoft.CodeAnalysis.Editor +namespace Microsoft.CodeAnalysis.DecompiledSource { internal interface IDecompiledSourceService : ILanguageService { diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx index 13f9b3c389281..75c6f891bbc9d 100644 --- a/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/Features/Core/Portable/FeaturesResources.resx @@ -2756,4 +2756,13 @@ Zero-width positive lookbehind assertions are typically used at the beginning of Convert type to '{0}' + + from metadata + + + 'symbol' cannot be a namespace. + + + Document must be contained in the workspace that created this service + \ No newline at end of file diff --git a/src/EditorFeatures/Core/IMetadataAsSourceFileService.cs b/src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileService.cs similarity index 90% rename from src/EditorFeatures/Core/IMetadataAsSourceFileService.cs rename to src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileService.cs index 72f322dac01ad..76b3aa7d0c7cc 100644 --- a/src/EditorFeatures/Core/IMetadataAsSourceFileService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileService.cs @@ -4,9 +4,9 @@ using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Text; +using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Editor +namespace Microsoft.CodeAnalysis.MetadataAsSource { internal interface IMetadataAsSourceFileService { @@ -24,7 +24,7 @@ internal interface IMetadataAsSourceFileService /// To cancel project and document operations Task GetGeneratedFileAsync(Project project, ISymbol symbol, bool allowDecompilation, CancellationToken cancellationToken = default); - bool TryAddDocumentToWorkspace(string filePath, ITextBuffer buffer); + bool TryAddDocumentToWorkspace(string filePath, SourceTextContainer buffer); bool TryRemoveDocumentFromWorkspace(string filePath); diff --git a/src/EditorFeatures/Core/MetadataAsSourceFile.cs b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFile.cs similarity index 95% rename from src/EditorFeatures/Core/MetadataAsSourceFile.cs rename to src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFile.cs index 855ccdcdfd55d..d8ee4f1b2ec5f 100644 --- a/src/EditorFeatures/Core/MetadataAsSourceFile.cs +++ b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFile.cs @@ -2,8 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - -namespace Microsoft.CodeAnalysis.Editor +namespace Microsoft.CodeAnalysis.MetadataAsSource { internal sealed class MetadataAsSourceFile { diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFileService.cs similarity index 97% rename from src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs rename to src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFileService.cs index 33b2683ab2147..8ff4ef0048bcc 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFileService.cs @@ -6,24 +6,23 @@ using System; using System.Collections.Generic; -using System.ComponentModel.Composition; +using System.Composition; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.DecompiledSource; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.SymbolMapping; using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.Text; using Roslyn.Utilities; -namespace Microsoft.CodeAnalysis.Editor.Implementation.MetadataAsSource +namespace Microsoft.CodeAnalysis.MetadataAsSource { - [Export(typeof(IMetadataAsSourceFileService))] + [Export(typeof(IMetadataAsSourceFileService)), Shared] internal class MetadataAsSourceFileService : IMetadataAsSourceFileService { /// @@ -85,7 +84,7 @@ public async Task GetGeneratedFileAsync(Project project, I if (symbol.Kind == SymbolKind.Namespace) { - throw new ArgumentException(EditorFeaturesResources.symbol_cannot_be_a_namespace, nameof(symbol)); + throw new ArgumentException(FeaturesResources.symbol_cannot_be_a_namespace, nameof(symbol)); } symbol = symbol.GetOriginalUnreducedDefinition(); @@ -191,7 +190,7 @@ public async Task GetGeneratedFileAsync(Project project, I var documentName = string.Format( "{0} [{1}]", topLevelNamedType.Name, - EditorFeaturesResources.from_metadata); + FeaturesResources.from_metadata); var documentTooltip = topLevelNamedType.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces)); @@ -220,7 +219,7 @@ private async Task RelocateSymbol_NoLockAsync(MetadataAsSourceGenerate return await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, temporaryDocument, cancellationToken).ConfigureAwait(false); } - public bool TryAddDocumentToWorkspace(string filePath, ITextBuffer buffer) + public bool TryAddDocumentToWorkspace(string filePath, SourceTextContainer sourceTextContainer) { using (_gate.DisposableWait()) { @@ -233,7 +232,7 @@ public bool TryAddDocumentToWorkspace(string filePath, ITextBuffer buffer) var newProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(_workspace, loadFileFromDisk: true); _workspace.OnProjectAdded(newProjectInfoAndDocumentId.Item1); - _workspace.OnDocumentOpened(newProjectInfoAndDocumentId.Item2, buffer.AsTextContainer()); + _workspace.OnDocumentOpened(newProjectInfoAndDocumentId.Item2, sourceTextContainer); _openedDocumentIds = _openedDocumentIds.Add(fileInfo, newProjectInfoAndDocumentId.Item2); diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs similarity index 98% rename from src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs rename to src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs index aa59e964fbf3b..af2398e5d2b87 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs +++ b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceGeneratedFileInfo.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Text; -namespace Microsoft.CodeAnalysis.Editor.Implementation.MetadataAsSource +namespace Microsoft.CodeAnalysis.MetadataAsSource { internal sealed class MetadataAsSourceGeneratedFileInfo { diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceWorkspace.cs b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceWorkspace.cs similarity index 89% rename from src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceWorkspace.cs rename to src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceWorkspace.cs index cc52d52211d04..92db103c2339e 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceWorkspace.cs +++ b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceWorkspace.cs @@ -6,7 +6,7 @@ using Microsoft.CodeAnalysis.Host; -namespace Microsoft.CodeAnalysis.Editor.Implementation.MetadataAsSource +namespace Microsoft.CodeAnalysis.MetadataAsSource { internal class MetadataAsSourceWorkspace : Workspace { diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs b/src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs similarity index 88% rename from src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs rename to src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs index 6672c30f9a72f..e5c577885a8f5 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/SymbolMappingServiceFactory.cs +++ b/src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs @@ -12,7 +12,7 @@ using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.SymbolMapping; -namespace Microsoft.CodeAnalysis.Editor.Implementation.MetadataAsSource +namespace Microsoft.CodeAnalysis.MetadataAsSource { [ExportWorkspaceServiceFactory(typeof(ISymbolMappingService), WorkspaceKind.MetadataAsSource)] [Shared] @@ -33,7 +33,7 @@ private sealed class SymbolMappingService : ISymbolMappingService { if (!(document.Project.Solution.Workspace is MetadataAsSourceWorkspace workspace)) { - throw new ArgumentException(EditorFeaturesResources.Document_must_be_contained_in_the_workspace_that_created_this_service, nameof(document)); + throw new ArgumentException(FeaturesResources.Document_must_be_contained_in_the_workspace_that_created_this_service, nameof(document)); } return workspace.FileService.MapSymbolAsync(document, symbolId, cancellationToken); diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index 9d14b00fe66fe..48151c7bfe8bf 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Aktuální obsah zdrojového souboru {0} se neshoduje se sestaveným zdrojem. Případné změny provedené v tomto souboru během ladění se nepoužijí, dokud se jeho obsah nebude shodovat se sestaveným zdrojem. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Upravit a pokračovat @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's proměnná typu discard + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index 8748b8429fdaa..9f31cb1bbb6fb 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Der aktuelle Inhalt der Quelldatei "{0}" stimmt nicht mit der erstellten Quelle überein. Alle Änderungen, die während des Debuggens an dieser Datei vorgenommen wurden, werden erst angewendet, wenn der Inhalt der erstellten Quelle entspricht. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Bearbeiten und Fortfahren @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's Ausschussvariable + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index 4b1013c8f800d..15f9ffca3e396 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma El contenido actual del archivo de origen "{0}" no coincide con el del origen compilado, así que los cambios realizados en este archivo durante la depuración no se aplicarán hasta que coincida. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Editar y continuar @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's descartar + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index c0efeec1d727d..909ba50aa1366 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Le contenu actuel du fichier source '{0}' ne correspond pas à la source générée. Les changements apportés à ce fichier durant le débogage ne seront pas appliqués tant que son contenu ne correspondra pas à la source générée. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Modifier et continuer @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's discard + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index 802b7b9fa73d1..c7dad94a66702 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Il contenuto corrente del file di origine '{0}' non corrisponde all'origine compilata. Tutte le modifiche apportate a questo file durante il debug non verranno applicate finché il relativo contenuto non corrisponde all'origine compilata. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Modifica e continuazione @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's variabile discard + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index 3e5ef5d1ab10f..4b7126563c5b5 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma ソース ファイル '{0}' の現在のコンテンツが、ビルドされたソースと一致しません。デバッグ中にこのファイルに加えられた変更は、そのコンテンツがビルドされたソースと一致するまで適用されません。 + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue エディット コンティニュ @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's 破棄 + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index e1203194ac10e..ee62f42f7b439 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 소스 파일 '{0}'의 현재 콘텐츠가 빌드된 소스와 일치하지 않습니다. 디버그하는 동안 이 파일의 변경된 모든 내용은 해당 콘텐츠가 빌드된 소스와 일치할 때까지 적용되지 않습니다. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue 편집하며 계속하기 @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's 무시 항목 + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index 2c5a57857bde2..3f9cf0e7b3d41 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Bieżąca zawartość pliku źródłowego „{0}” nie pasuje do skompilowanego źródła. Wszystkie zmiany wprowadzone w tym pliku podczas debugowania nie zostaną zastosowane do czasu, aż jego zawartość będzie zgodna ze skompilowanym źródłem. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Edytuj i kontynuuj @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's odrzuć + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index 7f294c77bbd56..a720c70a27521 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma O conteúdo atual do arquivo de origem '{0}' não corresponde à origem criada. Todas as alterações feitas neste arquivo durante a depuração não serão aplicadas até que o conteúdo corresponda à origem criada. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Editar e Continuar @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's discard + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index db2fcc96a927b..e5fe5488a774d 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Текущее содержимое исходного файла "{0}" не соответствует скомпилированному исходному коду. Все изменения, внесенные в этот файл во время отладки, не будут применены, пока содержимое файла не будет соответствовать скомпилированному исходному коду. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Операция "Изменить и продолжить" @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's отменить + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index a546af7a51713..22db8fdf3020a 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma '{0}' kaynak dosyasının geçerli içeriği, oluşturulan kaynakla eşleşmiyor. Hata ayıklama işlemi sırasında bu dosyada yapılan değişiklikler, dosyanın içeriği oluşturulan kaynakla eşleşene kadar uygulanmaz. + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue Düzenle ve Devam Et @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's at + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index 2131f80e6c8a3..df6b18762793f 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 源文件 "{0}" 的当前内容与生成的源不匹配。在调试期间对此文件所做的任何更改都不会应用,直到其内容与生成的源匹配为止。 + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue 编辑并继续 @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's 放弃 + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index 4e336deb5b5ab..de69f45e5f78b 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -305,6 +305,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 來源檔案 '{0}' 目前的內容與已建置的來源不一致。等到此檔案的內容與已建置的來源一致後,才會套用於偵錯期間對此檔案所做的所有變更。 + + Document must be contained in the workspace that created this service + Document must be contained in the workspace that created this service + + Edit and Continue 編輯並繼續 @@ -2323,6 +2328,11 @@ If the "d" format specifier is used without other custom format specifiers, it's 捨棄 + + from metadata + from metadata + + full long date/time full long date/time @@ -3575,6 +3585,11 @@ The purpose of the "s" format specifier is to produce result strings that sort c When this standard format specifier is used, the formatting or parsing operation always uses the invariant culture. + + 'symbol' cannot be a namespace. + 'symbol' cannot be a namespace. + + time separator time separator diff --git a/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandler.cs b/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandler.cs index 128dc48536f8e..ea45bec1794b4 100644 --- a/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandler.cs +++ b/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandler.cs @@ -6,8 +6,8 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.MetadataAsSource; using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.LanguageServer.Handler diff --git a/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandlerBase.cs b/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandlerBase.cs index 57f8bade31238..53e8ca87489fb 100644 --- a/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandlerBase.cs +++ b/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToDefinitionHandlerBase.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.PooledObjects; using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; diff --git a/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToTypeDefinitionHandler.cs b/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToTypeDefinitionHandler.cs index f50247bda568a..32735c9122e54 100644 --- a/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToTypeDefinitionHandler.cs +++ b/src/Features/LanguageServer/Protocol/Handler/Definitions/GoToTypeDefinitionHandler.cs @@ -6,8 +6,8 @@ using System.Composition; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.MetadataAsSource; using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.CodeAnalysis.LanguageServer.Handler diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/MiscellaneousFilesWorkspace.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/MiscellaneousFilesWorkspace.cs index 8521b6f5f9786..ce8259c734284 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/MiscellaneousFilesWorkspace.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/MiscellaneousFilesWorkspace.cs @@ -9,10 +9,10 @@ using System.IO; using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Scripting; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Editor; @@ -249,7 +249,7 @@ private void AttachToDocument(string moniker, ITextBuffer textBuffer) { _foregroundThreadAffinitization.AssertIsForeground(); - if (_fileTrackingMetadataAsSourceService.TryAddDocumentToWorkspace(moniker, textBuffer)) + if (_fileTrackingMetadataAsSourceService.TryAddDocumentToWorkspace(moniker, textBuffer.AsTextContainer())) { // We already added it, so we will keep it excluded from the misc files workspace return; diff --git a/src/VisualStudio/Core/Def/Implementation/VisualStudioMetadataAsSourceFileSupportService.cs b/src/VisualStudio/Core/Def/Implementation/VisualStudioMetadataAsSourceFileSupportService.cs index f7d45d25f6bf4..aeeb770d1f9ac 100644 --- a/src/VisualStudio/Core/Def/Implementation/VisualStudioMetadataAsSourceFileSupportService.cs +++ b/src/VisualStudio/Core/Def/Implementation/VisualStudioMetadataAsSourceFileSupportService.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; diff --git a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs index d0dc05ec05208..a1e3a045c5adf 100644 --- a/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs +++ b/src/VisualStudio/Core/Def/Implementation/Workspace/VisualStudioSymbolNavigationService.cs @@ -5,17 +5,18 @@ #nullable enable using System; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.DecompiledSource; using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Implementation.Structure; using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.FindUsages; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.Navigation; using Microsoft.CodeAnalysis.Notification; using Microsoft.CodeAnalysis.Options; diff --git a/src/VisualStudio/LiveShare/Impl/AbstractGoToDefinitionWithFindUsagesServiceHandler.cs b/src/VisualStudio/LiveShare/Impl/AbstractGoToDefinitionWithFindUsagesServiceHandler.cs index 7b039d7f6b729..76a8ee85e8e31 100644 --- a/src/VisualStudio/LiveShare/Impl/AbstractGoToDefinitionWithFindUsagesServiceHandler.cs +++ b/src/VisualStudio/LiveShare/Impl/AbstractGoToDefinitionWithFindUsagesServiceHandler.cs @@ -4,17 +4,17 @@ using System; using System.Collections.Generic; -using System.ComponentModel.Composition; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.LiveShare.LanguageServices; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor; -using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Editor.FindUsages; -using Microsoft.VisualStudio.Shell; +using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.LanguageServer; +using Microsoft.CodeAnalysis.MetadataAsSource; +using Microsoft.VisualStudio.LiveShare.LanguageServices; +using Microsoft.VisualStudio.Shell; using LSP = Microsoft.VisualStudio.LanguageServer.Protocol; namespace Microsoft.VisualStudio.LanguageServices.LiveShare diff --git a/src/VisualStudio/LiveShare/Impl/GotoDefinitionWithFindUsagesServiceHandler.Exports.cs b/src/VisualStudio/LiveShare/Impl/GotoDefinitionWithFindUsagesServiceHandler.Exports.cs index e211094e92d1e..0b6f1ed5f6ac9 100644 --- a/src/VisualStudio/LiveShare/Impl/GotoDefinitionWithFindUsagesServiceHandler.Exports.cs +++ b/src/VisualStudio/LiveShare/Impl/GotoDefinitionWithFindUsagesServiceHandler.Exports.cs @@ -4,8 +4,8 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.VisualStudio.LanguageServer.Protocol; using Microsoft.VisualStudio.LiveShare.LanguageServices; From 004160e93ab8f678e1aa68281efa84c4ffa7ba7d Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Fri, 8 May 2020 16:02:03 -0700 Subject: [PATCH 121/222] Null annotate AbstractMetadataSourceTests.TestContext.cs --- ...stractMetadataAsSourceTests.TestContext.cs | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs b/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs index 56f6a6243ed1c..94f2d6c84f8c2 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/AbstractMetadataAsSourceTests.TestContext.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.IO; @@ -11,8 +13,8 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.MetadataAsSource; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; -using Microsoft.VisualStudio.Text; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; @@ -30,12 +32,12 @@ internal class TestContext : IDisposable private readonly IMetadataAsSourceFileService _metadataAsSourceService; public static TestContext Create( - string projectLanguage = null, - IEnumerable metadataSources = null, + string? projectLanguage = null, + IEnumerable? metadataSources = null, bool includeXmlDocComments = false, - string sourceWithSymbolReference = null, - string languageVersion = null, - string metadataLanguageVersion = null) + string? sourceWithSymbolReference = null, + string? languageVersion = null, + string? metadataLanguageVersion = null) { projectLanguage ??= LanguageNames.CSharp; metadataSources ??= SpecializedCollections.EmptyEnumerable(); @@ -65,7 +67,7 @@ public Project DefaultProject get { return this.CurrentSolution.Projects.First(); } } - public Task GenerateSourceAsync(ISymbol symbol, Project project = null, bool allowDecompilation = false) + public Task GenerateSourceAsync(ISymbol symbol, Project? project = null, bool allowDecompilation = false) { project ??= this.DefaultProject; @@ -73,13 +75,13 @@ public Task GenerateSourceAsync(ISymbol symbol, Project pr return _metadataAsSourceService.GetGeneratedFileAsync(project, symbol, allowDecompilation); } - public async Task GenerateSourceAsync(string symbolMetadataName = null, Project project = null, bool allowDecompilation = false) + public async Task GenerateSourceAsync(string? symbolMetadataName = null, Project? project = null, bool allowDecompilation = false) { symbolMetadataName ??= AbstractMetadataAsSourceTests.DefaultSymbolMetadataName; project ??= this.DefaultProject; // Get an ISymbol corresponding to the metadata name - var compilation = await project.GetCompilationAsync(); + var compilation = await project.GetRequiredCompilationAsync(CancellationToken.None); var diagnostics = compilation.GetDiagnostics().ToArray(); Assert.Equal(0, diagnostics.Length); var symbol = await ResolveSymbolAsync(symbolMetadataName, compilation); @@ -90,12 +92,6 @@ public async Task GenerateSourceAsync(string symbolMetadat return result; } - private static string GetSpaceSeparatedTokens(string source) - { - var tokens = source.Split(new[] { ' ', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).Where(s => s != string.Empty); - return string.Join(" ", tokens); - } - public void VerifyResult(MetadataAsSourceFile file, string expected) { var actual = File.ReadAllText(file.FilePath).Trim(); @@ -109,7 +105,7 @@ public void VerifyResult(MetadataAsSourceFile file, string expected) Assert.Equal(expectedSpan.End, actualSpan.End); } - public async Task GenerateAndVerifySourceAsync(string symbolMetadataName, string expected, Project project = null) + public async Task GenerateAndVerifySourceAsync(string symbolMetadataName, string expected, Project? project = null) { var result = await GenerateSourceAsync(symbolMetadataName, project); VerifyResult(result, expected); @@ -133,18 +129,19 @@ public void Dispose() } } - public async Task ResolveSymbolAsync(string symbolMetadataName, Compilation compilation = null) + public async Task ResolveSymbolAsync(string symbolMetadataName, Compilation? compilation = null) { if (compilation == null) { - compilation = await this.DefaultProject.GetCompilationAsync(); + compilation = await this.DefaultProject.GetRequiredCompilationAsync(CancellationToken.None); var diagnostics = compilation.GetDiagnostics().ToArray(); Assert.Equal(0, diagnostics.Length); } foreach (var reference in compilation.References) { - var assemblySymbol = (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(reference); + var assemblySymbol = (IAssemblySymbol?)compilation.GetAssemblyOrModuleSymbol(reference); + Contract.ThrowIfNull(assemblySymbol); var namedTypeSymbol = assemblySymbol.GetTypeByMetadataName(symbolMetadataName); if (namedTypeSymbol != null) @@ -210,9 +207,12 @@ private static string DeduceLanguageString(string input) } private static TestWorkspace CreateWorkspace( - string projectLanguage, IEnumerable metadataSources, - bool includeXmlDocComments, string sourceWithSymbolReference, - string languageVersion, string metadataLanguageVersion) + string projectLanguage, + IEnumerable? metadataSources, + bool includeXmlDocComments, + string? sourceWithSymbolReference, + string? languageVersion, + string? metadataLanguageVersion) { var languageVersionAttribute = languageVersion is null ? "" : $@" LanguageVersion=""{languageVersion}"""; @@ -266,11 +266,13 @@ internal Document GetDocument(MetadataAsSourceFile file) internal async Task GetNavigationSymbolAsync() { var testDocument = _workspace.Documents.Single(d => d.FilePath == "SourceDocument"); - var document = _workspace.CurrentSolution.GetDocument(testDocument.Id); + var document = _workspace.CurrentSolution.GetRequiredDocument(testDocument.Id); - var syntaxRoot = await document.GetSyntaxRootAsync(); - var semanticModel = await document.GetSemanticModelAsync(); - return semanticModel.GetSymbolInfo(syntaxRoot.FindNode(testDocument.SelectedSpans.Single())).Symbol; + var syntaxRoot = await document.GetRequiredSyntaxRootAsync(CancellationToken.None); + var semanticModel = await document.GetRequiredSemanticModelAsync(CancellationToken.None); + var symbol = semanticModel.GetSymbolInfo(syntaxRoot.FindNode(testDocument.SelectedSpans.Single())).Symbol; + Contract.ThrowIfNull(symbol); + return symbol; } } } From 91c6b154373d0835c69c889ecd27fa6e6cf29dc2 Mon Sep 17 00:00:00 2001 From: Neal Gafter Date: Fri, 8 May 2020 20:20:17 -0700 Subject: [PATCH 122/222] Move PROTOTYPE comment to an issue (#44104) Relates to #44102 --- .../CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs index 215ed65b081cc..f1c621a338c17 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs @@ -3194,7 +3194,6 @@ static void Main() { if (o is <= 10U and var i) M(i); } // System.UInt32 // 6. If P is an or pattern, the narrowed type is the common type of the narrowed type of the left pattern and the narrowed type of the right pattern if such a common type exists. -// This test blocked until https://github.com/dotnet/roslyn/pull/42109 is integrated. o = 1; { if (o is (1 or 2) and var i) M(i); } // System.Int32 @@ -3204,7 +3203,6 @@ static void Main() // 8. Otherwise the narrowed type of P is P's input type. o = new Q(); - // PROTOTYPE(ngafter): we need a rule that explains this. { if (o is (3, 4) and var i) M(i); } // System.Runtime.CompilerServices.ITuple o = null; From 8746846a7130c55f2184de4880d32ecf62382160 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Fri, 8 May 2020 20:24:18 -0700 Subject: [PATCH 123/222] Add formatter benchmark --- .../IdeCoreBenchmarks/FormatterBenchmarks.cs | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/Tools/IdeCoreBenchmarks/FormatterBenchmarks.cs diff --git a/src/Tools/IdeCoreBenchmarks/FormatterBenchmarks.cs b/src/Tools/IdeCoreBenchmarks/FormatterBenchmarks.cs new file mode 100644 index 0000000000000..1c162eafc47b9 --- /dev/null +++ b/src/Tools/IdeCoreBenchmarks/FormatterBenchmarks.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.IO; +using System.Threading; +using BenchmarkDotNet.Attributes; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Formatting; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; + +namespace IdeCoreBenchmarks +{ + [MemoryDiagnoser] + public class FormatterBenchmarks + { + private readonly int _iterationCount = 5; + + private Document _document; + private OptionSet _options; + + [GlobalSetup] + public void GlobalSetup() + { + var roslynRoot = Environment.GetEnvironmentVariable(Program.RoslynRootPathEnvVariableName); + var csFilePath = Path.Combine(roslynRoot, @"src\Compilers\CSharp\Portable\Generated\Syntax.xml.Syntax.Generated.cs"); + + if (!File.Exists(csFilePath)) + { + throw new ArgumentException(); + } + + // Remove some newlines + var text = File.ReadAllText(csFilePath).Replace("", "") + .Replace($"{{{Environment.NewLine}{Environment.NewLine}", "{") + .Replace($"}}{Environment.NewLine}{Environment.NewLine}", "}") + .Replace($"{{{Environment.NewLine}", "{") + .Replace($"}}{Environment.NewLine}", "}") + .Replace($";{Environment.NewLine}", ";"); + + var projectId = ProjectId.CreateNewId(); + var documentId = DocumentId.CreateNewId(projectId); + + var solution = new AdhocWorkspace(MefHostServices.Create(MefHostServices.DefaultAssemblies)).CurrentSolution + .AddProject(projectId, "ProjectName", "AssemblyName", LanguageNames.CSharp) + .AddDocument(documentId, "DocumentName", text); + + var document = solution.GetDocument(documentId); + var root = document.GetSyntaxRootAsync(CancellationToken.None).Result.WithAdditionalAnnotations(Formatter.Annotation); + solution = solution.WithDocumentSyntaxRoot(documentId, root); + + _document = solution.GetDocument(documentId); + _options = _document.GetOptionsAsync().Result + .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInTypes, true) + .WithChangedOption(CSharpFormattingOptions.WrappingKeepStatementsOnSingleLine, false) + .WithChangedOption(CSharpFormattingOptions.WrappingPreserveSingleLine, false); + } + + [Benchmark] + public void FormatSyntaxNode() + { + for (int i = 0; i < _iterationCount; ++i) + { + var formattedDoc = Formatter.FormatAsync(_document, Formatter.Annotation, _options, CancellationToken.None).Result; + var formattedRoot = formattedDoc.GetSyntaxRootAsync(CancellationToken.None).Result; + _ = formattedRoot.DescendantNodesAndSelf().ToImmutableArray(); + } + } + } +} From e94ed8e2fb253fac952cd1277b7a61bce6faf6be Mon Sep 17 00:00:00 2001 From: Yair Halberstadt Date: Sun, 10 May 2020 20:03:25 +0300 Subject: [PATCH 124/222] document that TaskMethodBuilder cannot be a nested type (#43635) --- docs/features/task-types.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/features/task-types.md b/docs/features/task-types.md index 5c49ce23b7258..83343b3e2a5b5 100644 --- a/docs/features/task-types.md +++ b/docs/features/task-types.md @@ -26,6 +26,7 @@ class Awaiter : INotifyCompletion ``` ## Builder Type The _builder type_ is a `class` or `struct` that corresponds to the specific _task type_. +The _builder type_ can have at most 1 type parameter and must not be nested in a generic type. The _builder type_ has the following `public` methods. For non-generic _builder types_, `SetResult()` has no parameters. ```cs From 057e94f21585fe7855872e359ba95d57d7705346 Mon Sep 17 00:00:00 2001 From: Shimmy Weitzhandler <2716316+weitzhandler@users.noreply.github.com> Date: Sun, 10 May 2020 06:32:47 +0300 Subject: [PATCH 125/222] Add 'using' misplacement fixer to code-cleanup --- .../CSharpTest/Formatting/CodeCleanupTests.cs | 295 +++++++++++++++++- .../Portable/CSharpFeaturesResources.resx | 4 + .../CodeCleanup/CSharpCodeCleanupService.cs | 5 +- .../xlf/CSharpFeaturesResources.cs.xlf | 5 + .../xlf/CSharpFeaturesResources.de.xlf | 5 + .../xlf/CSharpFeaturesResources.es.xlf | 5 + .../xlf/CSharpFeaturesResources.fr.xlf | 5 + .../xlf/CSharpFeaturesResources.it.xlf | 5 + .../xlf/CSharpFeaturesResources.ja.xlf | 5 + .../xlf/CSharpFeaturesResources.ko.xlf | 5 + .../xlf/CSharpFeaturesResources.pl.xlf | 5 + .../xlf/CSharpFeaturesResources.pt-BR.xlf | 5 + .../xlf/CSharpFeaturesResources.ru.xlf | 5 + .../xlf/CSharpFeaturesResources.tr.xlf | 5 + .../xlf/CSharpFeaturesResources.zh-Hans.xlf | 5 + .../xlf/CSharpFeaturesResources.zh-Hant.xlf | 5 + 16 files changed, 360 insertions(+), 9 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index c1232c87e24eb..fb4145b252e27 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -2,22 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.ComponentModel.Composition; using System.Linq; -using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.AddImports; using Microsoft.CodeAnalysis.CodeCleanup; +using Microsoft.CodeAnalysis.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.UseExpressionBody; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Diagnostics.CSharp; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; -using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.SolutionCrawler; @@ -252,7 +249,276 @@ private void Method() return AssertCodeCleanupResult(expected, code); } - protected static async Task AssertCodeCleanupResult(string expected, string code, bool systemUsingsFirst = true, bool separateUsingGroups = false) + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementPreferOutside() + { + var code = @"namespace A +{ + using System; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + } + } +} +"; + + var expected = @"using System; + +namespace A +{ + internal class Program + { + private void Method() + { + Console.WriteLine(); + } + } +} +"; + + return AssertCodeCleanupResult(expected, code); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementPreferInside() + { + var code = @"using System; + +namespace A +{ + internal class Program + { + private void Method() + { + Console.WriteLine(); + } + } +} +"; + + var expected = @"namespace A +{ + using System; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + } + } +} +"; + + return AssertCodeCleanupResult(expected, code, InsideNamespaceOption); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementPreferInsidePreserve() + { + var code = @"using System; + +namespace A +{ + internal class Program + { + private void Method() + { + Console.WriteLine(); + } + } +} +"; + + var expected = code; + + return AssertCodeCleanupResult(expected, code, InsidePreferPreservationOption); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementPreferOutsidePreserve() + { + var code = @"namespace A +{ + using System; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + } + } +} +"; + + var expected = code; + + return AssertCodeCleanupResult(expected, code, OutsidePreferPreservationOption); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementMixedPreferOutside() + { + var code = @"using System; + +namespace A +{ + using System.Collections.Generic; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + List list = new List(); + } + } +} +"; + + var expected = @"using System; +using System.Collections.Generic; + +namespace A +{ + internal class Program + { + private void Method() + { + Console.WriteLine(); + List list = new List(); + } + } +} +"; + + return AssertCodeCleanupResult(expected, code, OutsideNamespaceOption); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementMixedPreferInside() + { + var code = @"using System; + +namespace A +{ + using System.Collections.Generic; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + List list = new List(); + } + } +} +"; + + var expected = @"namespace A +{ + using System; + using System.Collections.Generic; + + + internal class Program + { + private void Method() + { + Console.WriteLine(); + List list = new List(); + } + } +} +"; + + return AssertCodeCleanupResult(expected, code, InsideNamespaceOption); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementMixedPreferInsidePreserve() + { + var code = @"using System; + +namespace A +{ + using System.Collections.Generic; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + List list = new List(); + } + } +} +"; + + var expected = code; + + return AssertCodeCleanupResult(expected, code, InsidePreferPreservationOption); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + public Task FixUsingPlacementMixedPreferOutsidePreserve() + { + var code = @"using System; + +namespace A +{ + using System.Collections.Generic; + + internal class Program + { + private void Method() + { + Console.WriteLine(); + List list = new List(); + } + } +} +"; + + var expected = code; + + return AssertCodeCleanupResult(expected, code, OutsidePreferPreservationOption); + } + + /// + /// Assert the expected code value equals the actual processed input . + /// + /// The actual processed code to verify against. + /// The input code to be processed and tested. + /// Indicates whether .* 'using' directives should preceed others. Default is true. + /// Indicates whether 'using' directives should be organized into separated groups. Default is true. + /// The to test code cleanup. + private protected static Task AssertCodeCleanupResult(string expected, string code, bool systemUsingsFirst = true, bool separateUsingGroups = false) + => AssertCodeCleanupResult(expected, code, CSharpCodeStyleOptions.PreferOutsidePlacementWithSilentEnforcement, systemUsingsFirst, separateUsingGroups); + + /// + /// Assert the expected code value equals the actual processed input . + /// + /// The actual processed code to verify against. + /// The input code to be processed and tested. + /// Indicates the code style option for the preferred 'using' directives placement. + /// Indicates whether .* 'using' directives should preceed others. Default is true. + /// Indicates whether 'using' directives should be organized into separated groups. Default is true. + /// The to test code cleanup. + private protected static async Task AssertCodeCleanupResult(string expected, string code, CodeStyleOption2 preferredImportPlacement, bool systemUsingsFirst = true, bool separateUsingGroups = false) { var exportProvider = ExportProviderCache.GetOrCreateExportProviderFactory(TestExportProvider.EntireAssemblyCatalogWithCSharpAndVisualBasic).CreateExportProvider(); @@ -261,7 +527,8 @@ protected static async Task AssertCodeCleanupResult(string expected, string code var solution = workspace.CurrentSolution .WithOptions(workspace.Options .WithChangedOption(GenerationOptions.PlaceSystemNamespaceFirst, LanguageNames.CSharp, systemUsingsFirst) - .WithChangedOption(GenerationOptions.SeparateImportDirectiveGroups, LanguageNames.CSharp, separateUsingGroups)) + .WithChangedOption(GenerationOptions.SeparateImportDirectiveGroups, LanguageNames.CSharp, separateUsingGroups) + .WithChangedOption(CSharpCodeStyleOptions.PreferredUsingDirectivePlacement, preferredImportPlacement)) .WithAnalyzerReferences(new[] { new AnalyzerFileReference(typeof(CSharpCompilerDiagnosticAnalyzer).Assembly.Location, TestAnalyzerAssemblyLoader.LoadFromFile), @@ -288,5 +555,17 @@ protected static async Task AssertCodeCleanupResult(string expected, string code Assert.Equal(expected, actual.ToString()); } + + private static readonly CodeStyleOption2 InsideNamespaceOption = + new CodeStyleOption2(AddImportPlacement.InsideNamespace, NotificationOption2.Error); + + private static readonly CodeStyleOption2 OutsideNamespaceOption = + new CodeStyleOption2(AddImportPlacement.OutsideNamespace, NotificationOption2.Error); + + private static readonly CodeStyleOption2 InsidePreferPreservationOption = + new CodeStyleOption2(AddImportPlacement.InsideNamespace, NotificationOption2.None); + + private static readonly CodeStyleOption2 OutsidePreferPreservationOption = + new CodeStyleOption2(AddImportPlacement.OutsideNamespace, NotificationOption2.None); } } diff --git a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx index df1550b5aa1aa..33a74e30152be 100644 --- a/src/Features/CSharp/Portable/CSharpFeaturesResources.resx +++ b/src/Features/CSharp/Portable/CSharpFeaturesResources.resx @@ -614,4 +614,8 @@ Compare to '{0}' + + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + \ No newline at end of file diff --git a/src/Features/CSharp/Portable/CodeCleanup/CSharpCodeCleanupService.cs b/src/Features/CSharp/Portable/CodeCleanup/CSharpCodeCleanupService.cs index 2689d8f69b683..30f3dd9a17738 100644 --- a/src/Features/CSharp/Portable/CodeCleanup/CSharpCodeCleanupService.cs +++ b/src/Features/CSharp/Portable/CodeCleanup/CSharpCodeCleanupService.cs @@ -81,7 +81,10 @@ public CSharpCodeCleanupService( new[] { CSharpRemoveUnusedVariableCodeFixProvider.CS0168, CSharpRemoveUnusedVariableCodeFixProvider.CS0219 }), new DiagnosticSet(CSharpFeaturesResources.Apply_object_collection_initialization_preferences, - new[] { IDEDiagnosticIds.UseObjectInitializerDiagnosticId, IDEDiagnosticIds.UseCollectionInitializerDiagnosticId }) + new[] { IDEDiagnosticIds.UseObjectInitializerDiagnosticId, IDEDiagnosticIds.UseCollectionInitializerDiagnosticId }), + + new DiagnosticSet(CSharpFeaturesResources.Apply_using_directive_placement_preferences, + new[] { IDEDiagnosticIds.MoveMisplacedUsingDirectivesDiagnosticId }) ); public async Task CleanupAsync( diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf index 2bed8fc321274..1d8ce22babbf3 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.cs.xlf @@ -57,6 +57,11 @@ Použít předvolby kvalifikace this. + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Přiřadit parametry out diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf index d4ed045b13f48..4ea9e8272d636 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.de.xlf @@ -57,6 +57,11 @@ Einstellungen zur Qualifikation "this." anwenden + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters out-Parameter zuweisen diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf index 305b078f362a5..1cf87792029d8 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.es.xlf @@ -57,6 +57,11 @@ Aplicar preferencias de calificación “this.” + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Asignar parámetros "out" diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf index c2ae017043e88..5558acc15f8fb 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.fr.xlf @@ -57,6 +57,11 @@ Appliquer les préférences de qualification 'this.' + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Assigner des paramètres 'out' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf index fdf01d10e6d11..67f06b3083cc6 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.it.xlf @@ -57,6 +57,11 @@ Applica le preferenze relative alla qualificazione 'this.' + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Assegnare parametri 'out' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf index e729a70d45bfc..8407cfb3c9503 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ja.xlf @@ -57,6 +57,11 @@ 'this.' 修飾の基本設定を適用します + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters 'out' パラメーターの割り当て diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf index ee4defc88bfed..19d4e3d1cee7f 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ko.xlf @@ -57,6 +57,11 @@ 'this.' 한정자 기본 설정 적용 + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters 'out' 매개 변수 할당 diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf index bb8503841777d..5b05eaed4907c 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pl.xlf @@ -57,6 +57,11 @@ Zastosuj preferencje kwalifikacji „this.” + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Przypisz parametry „out” diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf index 609c42bb54dc4..78cd515d6312a 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.pt-BR.xlf @@ -57,6 +57,11 @@ Aplicar as preferências de qualificação 'this.' + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Atribuir parâmetros 'out' diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf index a4a95ee733258..66b923b2cab3d 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.ru.xlf @@ -57,6 +57,11 @@ Применять предпочтения для квалификации this. + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters Присвоение значений параметров "out" diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf index b869a3698e639..a0ab8e7415d21 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.tr.xlf @@ -57,6 +57,11 @@ 'this.' nitelemesi tercihlerini uygula + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters 'out' parametreleri ata diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf index fecb3281a5d13..a1762aefead51 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hans.xlf @@ -57,6 +57,11 @@ 应用 “this.” 资格首选项 + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters 分配 "out" 参数 diff --git a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf index 461dcd83d6fa0..8ae1483042e80 100644 --- a/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf +++ b/src/Features/CSharp/Portable/xlf/CSharpFeaturesResources.zh-Hant.xlf @@ -57,6 +57,11 @@ 套用 'this.' 資格喜好設定 + + Apply preferred 'using' placement preferences + Apply preferred 'using' placement preferences + 'using' is a C# keyword and should not be localized + Assign 'out' parameters 指派 'out' 參數 From c4bd5a0fa147a2cf7733d339a1ed5084baa24f5b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 11 May 2020 13:49:41 +0000 Subject: [PATCH 126/222] Update dependencies from https://github.com/dotnet/roslyn build 20200509.1 (#44128) - Microsoft.Net.Compilers.Toolset: 3.7.0-1.20254.1 -> 3.7.0-2.20259.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b47636b1762e3..7442c3cfe227b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -7,9 +7,9 @@ https://github.com/dotnet/arcade 5fd50687c9a9f39bd2ee8221165ea9c1b3f565d9 - + https://github.com/dotnet/roslyn - 87e2b1e95e030928b33d6a54341ea342efbbdafa + d0ef8687ce735c8aa32035396f521705a8ff7392 diff --git a/eng/Versions.props b/eng/Versions.props index d9bdd3af440f3..e303de8352add 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -23,7 +23,7 @@ - 3.7.0-1.20254.1 + 3.7.0-2.20259.1 From a8f6b30e8849ab290bb3e2b86b78bced0f53cbe1 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 11 May 2020 08:17:43 -0700 Subject: [PATCH 127/222] Remove pooled Stopwatch SharedStopwatch already offers a more efficient alternative. --- .../Compiler/Core/ObjectPools/Extensions.cs | 23 ------------------- .../Compiler/Core/ObjectPools/PooledObject.cs | 15 ------------ 2 files changed, 38 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/Extensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/Extensions.cs index 9d920fce93382..7ba604a45f261 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/Extensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/Extensions.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Diagnostics; using System.Text; using Microsoft.CodeAnalysis.PooledObjects; @@ -16,9 +15,6 @@ internal static class SharedPoolExtensions public static PooledObject GetPooledObject(this ObjectPool pool) => PooledObject.Create(pool); - public static PooledObject GetPooledObject(this ObjectPool pool) - => PooledObject.Create(pool); - public static PooledObject> GetPooledObject(this ObjectPool> pool) => PooledObject>.Create(pool); @@ -52,14 +48,6 @@ public static StringBuilder AllocateAndClear(this ObjectPool pool return sb; } - public static Stopwatch AllocateAndClear(this ObjectPool pool) - { - var watch = pool.Allocate(); - watch.Reset(); - - return watch; - } - public static Stack AllocateAndClear(this ObjectPool> pool) { var set = pool.Allocate(); @@ -117,17 +105,6 @@ public static void ClearAndFree(this ObjectPool pool, StringBuild pool.Free(sb); } - public static void ClearAndFree(this ObjectPool pool, Stopwatch watch) - { - if (watch == null) - { - return; - } - - watch.Reset(); - pool.Free(watch); - } - public static void ClearAndFree(this ObjectPool> pool, HashSet set) { if (set == null) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledObject.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledObject.cs index ed6aa428d5258..c897517b7dc67 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledObject.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/ObjectPools/PooledObject.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Text; using Microsoft.CodeAnalysis.PooledObjects; @@ -46,14 +45,6 @@ public static PooledObject Create(ObjectPool pool) (p, sb) => Releaser(p, sb)); } - public static PooledObject Create(ObjectPool pool) - { - return new PooledObject( - pool, - p => Allocator(p), - (p, sb) => Releaser(p, sb)); - } - public static PooledObject> Create(ObjectPool> pool) { return new PooledObject>( @@ -102,12 +93,6 @@ private static StringBuilder Allocator(ObjectPool pool) private static void Releaser(ObjectPool pool, StringBuilder sb) => pool.ClearAndFree(sb); - private static Stopwatch Allocator(ObjectPool pool) - => pool.AllocateAndClear(); - - private static void Releaser(ObjectPool pool, Stopwatch sb) - => pool.ClearAndFree(sb); - private static Stack Allocator(ObjectPool> pool) => pool.AllocateAndClear(); From 7dbe283d47b7ffbc178fadf5ef391eae9d76226d Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 11 May 2020 11:28:05 -0700 Subject: [PATCH 128/222] Run iterations of CSharpLanguageServiceTest_MultipleResults to demonstrate stability --- .../Core/Test.Next/Services/LanguageServiceTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs b/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs index 8405e31e7c36c..223b38ac7ae81 100644 --- a/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs @@ -41,9 +41,11 @@ public async Task CSharpLanguageServiceTest() } } - [Fact(Skip = "https://github.com/dotnet/roslyn/issues/43255"), Trait(Traits.Feature, Traits.Features.RemoteHost)] - public async Task CSharpLanguageServiceTest_MultipleResults() + [Theory, Trait(Traits.Feature, Traits.Features.RemoteHost)] + [CombinatorialData] + public async Task CSharpLanguageServiceTest_MultipleResults([CombinatorialRange(0, 1000)] int iteration) { + _ = iteration; var code = @"class Test { void Method() { } From 9d66056c1a3e81bedd6f61e3d06d785f8dd4b27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Mon, 11 May 2020 11:29:31 -0700 Subject: [PATCH 129/222] Ignore cancelled/faulted tasks in GlobalNotificationRemoteDeliveryService (#44105) --- .../Remote/GlobalNotificationRemoteDeliveryService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Remote/GlobalNotificationRemoteDeliveryService.cs b/src/VisualStudio/Core/Def/Implementation/Remote/GlobalNotificationRemoteDeliveryService.cs index 3fb2a341b9340..ee73b4112e7f5 100644 --- a/src/VisualStudio/Core/Def/Implementation/Remote/GlobalNotificationRemoteDeliveryService.cs +++ b/src/VisualStudio/Core/Def/Implementation/Remote/GlobalNotificationRemoteDeliveryService.cs @@ -76,7 +76,7 @@ private void OnGlobalOperationStarted(object sender, EventArgs e) lock (_globalNotificationsGate) { _globalNotificationsTask = _globalNotificationsTask.SafeContinueWithFromAsync( - SendStartNotificationAsync, _cancellationToken, TaskContinuationOptions.None, TaskScheduler.Default); + SendStartNotificationAsync, _cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default); } } @@ -111,7 +111,7 @@ private void OnGlobalOperationStopped(object sender, GlobalOperationEventArgs e) lock (_globalNotificationsGate) { _globalNotificationsTask = _globalNotificationsTask.SafeContinueWithFromAsync( - previous => SendStoppedNotificationAsync(previous, e), _cancellationToken, TaskContinuationOptions.None, TaskScheduler.Default); + previous => SendStoppedNotificationAsync(previous, e), _cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default); } } From 1a8cdb0848eb272738c93d6a0c39bb8bcebbf3a2 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 11 May 2020 11:31:21 -0700 Subject: [PATCH 130/222] Enable CSharpLanguageServiceTest_MultipleResults Closes #43255 --- .../Core/Test.Next/Services/LanguageServiceTests.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs b/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs index 223b38ac7ae81..170b46b5eeff8 100644 --- a/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/LanguageServiceTests.cs @@ -41,11 +41,9 @@ public async Task CSharpLanguageServiceTest() } } - [Theory, Trait(Traits.Feature, Traits.Features.RemoteHost)] - [CombinatorialData] - public async Task CSharpLanguageServiceTest_MultipleResults([CombinatorialRange(0, 1000)] int iteration) + [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] + public async Task CSharpLanguageServiceTest_MultipleResults() { - _ = iteration; var code = @"class Test { void Method() { } From 9e10e607e637379b0dc8fa24ed7dfcd1f9851b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Mon, 11 May 2020 13:25:23 -0700 Subject: [PATCH 131/222] Avoid NRE from TryCreateUnitTestingKeepAliveSessionWrapperAsync (#44137) --- .../Api/UnitTestingKeepAliveSessionWrapper.cs | 19 +++++++++++-------- .../UnitTestingSessionWithSolutionWrapper.cs | 13 ++++++++----- .../Portable/Remote/SessionWithSolution.cs | 1 - 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingKeepAliveSessionWrapper.cs b/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingKeepAliveSessionWrapper.cs index 40cceb61ebe17..b20c735ead3e3 100644 --- a/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingKeepAliveSessionWrapper.cs +++ b/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingKeepAliveSessionWrapper.cs @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable + using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -12,27 +13,29 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api { internal readonly struct UnitTestingKeepAliveSessionWrapper { - internal UnitTestingKeepAliveSessionWrapper(KeepAliveSession underlyingObject) - => UnderlyingObject = underlyingObject ?? throw new ArgumentNullException(nameof(underlyingObject)); + internal KeepAliveSession? UnderlyingObject { get; } + + internal UnitTestingKeepAliveSessionWrapper(KeepAliveSession? underlyingObject) + => UnderlyingObject = underlyingObject; - internal KeepAliveSession UnderlyingObject { get; } + public bool IsDefault => UnderlyingObject == null; public Task TryInvokeAsync(string targetName, Solution solution, IReadOnlyList arguments, CancellationToken cancellationToken) - => UnderlyingObject.RunRemoteAsync(targetName, solution, arguments, cancellationToken); + => UnderlyingObject!.RunRemoteAsync(targetName, solution, arguments, cancellationToken); public async Task TryInvokeAsync(string targetName, IReadOnlyList arguments, CancellationToken cancellationToken) { - await UnderlyingObject.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken).ConfigureAwait(false); + await UnderlyingObject!.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken).ConfigureAwait(false); return true; } public async Task TryInvokeAsync(string targetName, Solution solution, IReadOnlyList arguments, CancellationToken cancellationToken) { - await UnderlyingObject.RunRemoteAsync(targetName, solution, arguments, cancellationToken).ConfigureAwait(false); + await UnderlyingObject!.RunRemoteAsync(targetName, solution, arguments, cancellationToken).ConfigureAwait(false); return true; } public Task TryInvokeAsync(string targetName, IReadOnlyList arguments, CancellationToken cancellationToken) - => UnderlyingObject.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken); + => UnderlyingObject!.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken); } } diff --git a/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingSessionWithSolutionWrapper.cs b/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingSessionWithSolutionWrapper.cs index c8ab61c870f99..daf056f351ced 100644 --- a/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingSessionWithSolutionWrapper.cs +++ b/src/Workspaces/Core/Portable/ExternalAccess/UnitTesting/Api/UnitTestingSessionWithSolutionWrapper.cs @@ -2,28 +2,31 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable +#pragma warning disable CS0618 // Type or member is obsolete + using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Remote; -#pragma warning disable CS0618 // Type or member is obsolete - namespace Microsoft.CodeAnalysis.ExternalAccess.UnitTesting.Api { internal readonly struct UnitTestingSessionWithSolutionWrapper : IDisposable { - internal SessionWithSolution UnderlyingObject { get; } + internal SessionWithSolution? UnderlyingObject { get; } + + public bool IsDefault => UnderlyingObject == null; public UnitTestingSessionWithSolutionWrapper(SessionWithSolution underlyingObject) => UnderlyingObject = underlyingObject; public Task InvokeAsync(string targetName, IReadOnlyList arguments, CancellationToken cancellationToken) - => UnderlyingObject?.KeepAliveSession.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken) ?? Task.CompletedTask; + => UnderlyingObject!.KeepAliveSession.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken); public Task InvokeAsync(string targetName, IReadOnlyList arguments, CancellationToken cancellationToken) - => UnderlyingObject?.KeepAliveSession.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken); + => UnderlyingObject!.KeepAliveSession.RunRemoteAsync(targetName, solution: null, arguments, cancellationToken); public void Dispose() => UnderlyingObject?.Dispose(); diff --git a/src/Workspaces/Core/Portable/Remote/SessionWithSolution.cs b/src/Workspaces/Core/Portable/Remote/SessionWithSolution.cs index ac09ff526bf7d..91564a8f40d04 100644 --- a/src/Workspaces/Core/Portable/Remote/SessionWithSolution.cs +++ b/src/Workspaces/Core/Portable/Remote/SessionWithSolution.cs @@ -18,7 +18,6 @@ internal sealed class SessionWithSolution : IDisposable internal readonly KeepAliveSession KeepAliveSession; private readonly PinnedRemotableDataScope _scope; - public static async Task CreateAsync(KeepAliveSession keepAliveSession, Solution solution, CancellationToken cancellationToken) { Contract.ThrowIfNull(keepAliveSession); From 424efa48385f29c3bc31b75148218b2d142bd678 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Mon, 11 May 2020 11:24:04 -0700 Subject: [PATCH 132/222] Show status for "Running code analysis on " execution 1. Now we show the progress bar, which is useful for running this command on a solution with large number of projects 2. Periodically refresh the status bar text + progress, as opening any source file/background nuget restore operations overwrite the status bar text. --- .../Diagnostics/DiagnosticAnalyzerService.cs | 10 +- .../Diagnostics/IDiagnosticAnalyzerService.cs | 2 +- .../VisualStudioDiagnosticAnalyzerService.cs | 100 ++++++++++++++++-- .../ExternalDiagnosticUpdateSourceTests.vb | 2 +- 4 files changed, 98 insertions(+), 16 deletions(-) diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs index 87ae59a11961d..d0b1593c678c2 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService.cs @@ -131,7 +131,7 @@ public Task> GetDiagnosticsAsync(Solution solutio return SpecializedTasks.EmptyImmutableArray(); } - public async Task ForceAnalyzeAsync(Solution solution, ProjectId? projectId = null, CancellationToken cancellationToken = default) + public async Task ForceAnalyzeAsync(Solution solution, Action onProjectAnalyzed, ProjectId? projectId = null, CancellationToken cancellationToken = default) { if (_map.TryGetValue(solution.Workspace, out var analyzer)) { @@ -141,6 +141,7 @@ public async Task ForceAnalyzeAsync(Solution solution, ProjectId? projectId = nu if (project != null) { await analyzer.ForceAnalyzeProjectAsync(project, cancellationToken).ConfigureAwait(false); + onProjectAnalyzed(project); } } else @@ -149,8 +150,11 @@ public async Task ForceAnalyzeAsync(Solution solution, ProjectId? projectId = nu var index = 0; foreach (var project in solution.Projects) { - tasks[index++] = Task.Run( - () => analyzer.ForceAnalyzeProjectAsync(project, cancellationToken)); + tasks[index++] = Task.Run(async () => + { + await analyzer.ForceAnalyzeProjectAsync(project, cancellationToken).ConfigureAwait(false); + onProjectAnalyzed(project); + }); } await Task.WhenAll(tasks).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index af93211a5910a..497ed10b6b4d3 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -43,7 +43,7 @@ internal interface IDiagnosticAnalyzerService /// /// Force computes diagnostics and raises diagnostic events for the given project or solution. all diagnostics returned should be up-to-date with respect to the given project or solution. /// - Task ForceAnalyzeAsync(Solution solution, ProjectId? projectId = null, CancellationToken cancellationToken = default); + Task ForceAnalyzeAsync(Solution solution, Action onProjectAnalyzed, ProjectId? projectId = null, CancellationToken cancellationToken = default); /// /// True if given project has any diagnostics diff --git a/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs b/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs index b90aeffad7aad..d0a2cb3a4541b 100644 --- a/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs +++ b/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs @@ -199,29 +199,25 @@ public void RunAnalyzers(IVsHierarchy? hierarchy) string? projectOrSolutionName = project?.Name ?? PathUtilities.GetFileName(solution.FilePath); // Add a message to VS status bar that we are running code analysis. - var statusMessage = projectOrSolutionName != null - ? string.Format(ServicesVSResources.Running_code_analysis_for_0, projectOrSolutionName) - : ServicesVSResources.Running_code_analysis_for_Solution; var statusBar = _serviceProvider?.GetService(typeof(SVsStatusbar)) as IVsStatusbar; - statusBar?.SetText(statusMessage); + var totalProjectCount = project != null ? 1 : (uint)solution.ProjectIds.Count; + var statusBarUpdater = statusBar != null ? + new StatusBarUpdater(statusBar, _threadingContext, projectOrSolutionName, totalProjectCount) : + null; // Force complete analyzer execution in background. var asyncToken = _listener.BeginAsyncOperation($"{nameof(VisualStudioDiagnosticAnalyzerService)}_{nameof(RunAnalyzers)}"); Task.Run(async () => { - await _diagnosticService.ForceAnalyzeAsync(solution, project?.Id, CancellationToken.None).ConfigureAwait(false); + var onProjectAnalyzed = statusBarUpdater != null ? statusBarUpdater.OnProjectAnalyzed : (Action)((Project _) => { }); + await _diagnosticService.ForceAnalyzeAsync(solution, onProjectAnalyzed, project?.Id, CancellationToken.None).ConfigureAwait(false); // If user has disabled live analyzer execution for any project(s), i.e. set RunAnalyzersDuringLiveAnalysis = false, // then ForceAnalyzeAsync will not cause analyzers to execute. // We explicitly fetch diagnostics for such projects and report these as "Host" diagnostics. HandleProjectsWithDisabledAnalysis(); - // Add a message to VS status bar that we completed executing code analysis. - await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); - var notificationMesage = projectOrSolutionName != null - ? string.Format(ServicesVSResources.Code_analysis_completed_for_0, projectOrSolutionName) - : ServicesVSResources.Code_analysis_completed_for_Solution; - statusBar?.SetText(notificationMesage); + statusBarUpdater?.Dispose(); }).CompletesAsyncOperation(asyncToken); return; @@ -348,5 +344,87 @@ private bool IsBuildActive() } } } + + private sealed class StatusBarUpdater : IDisposable + { + private readonly IVsStatusbar _statusBar; + private readonly IThreadingContext _threadingContext; + private readonly uint _totalProjectCount; + private readonly string _statusMessageWhileRunning; + private readonly string _statusMesageOnCompleted; + private readonly Timer _timer; + + private int _analyzedProjectCount; + private bool _disposed; + private uint _statusBarCookie; + + public StatusBarUpdater(IVsStatusbar statusBar, IThreadingContext threadingContext, string? projectOrSolutionName, uint totalProjectCount) + { + Contract.ThrowIfFalse(threadingContext.HasMainThread); + _statusBar = statusBar; + _threadingContext = threadingContext; + _totalProjectCount = totalProjectCount; + + _statusMessageWhileRunning = projectOrSolutionName != null + ? string.Format(ServicesVSResources.Running_code_analysis_for_0, projectOrSolutionName) + : ServicesVSResources.Running_code_analysis_for_Solution; + _statusMesageOnCompleted = projectOrSolutionName != null + ? string.Format(ServicesVSResources.Code_analysis_completed_for_0, projectOrSolutionName) + : ServicesVSResources.Code_analysis_completed_for_Solution; + + // Set the initial status bar progress and text. + _statusBar.Progress(ref _statusBarCookie, fInProgress: 1, _statusMessageWhileRunning, nComplete: 0, nTotal: totalProjectCount); + _statusBar.SetText(_statusMessageWhileRunning); + + // Create a timer to periodically update the status message while running analysis. + _timer = new Timer(new TimerCallback(UpdateStatusOnTimer), new AutoResetEvent(false), + dueTime: TimeSpan.FromSeconds(5), period: TimeSpan.FromSeconds(5)); + } + + internal void OnProjectAnalyzed(Project _) + { + var analyzedProjectCount = Interlocked.Increment(ref _analyzedProjectCount); + UpdateStatus(isRunning: analyzedProjectCount < _totalProjectCount); + } + + // Add a message to VS status bar that we are running code analysis. + private void UpdateStatusOnTimer(object state) + => UpdateStatus(isRunning: true); + + public void Dispose() + { + _timer.Dispose(); + _disposed = true; + UpdateStatus(isRunning: false); + } + + private void UpdateStatus(bool isRunning) + { + Task.Run(async () => + { + await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); + + string message; + uint analyzedCount; + int fInProgress; + if (isRunning && !_disposed && _analyzedProjectCount != _totalProjectCount) + { + message = _statusMessageWhileRunning; + analyzedCount = (uint)_analyzedProjectCount; + fInProgress = 1; + } + else + { + message = _statusMesageOnCompleted; + analyzedCount = _totalProjectCount; + fInProgress = 0; + } + + // Update the status bar progress and text. + _statusBar.Progress(ref _statusBarCookie, fInProgress, message, analyzedCount, _totalProjectCount); + _statusBar.SetText(message); + }); + } + } } } diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index c0b1f83161ada..781c62b0ec1e9 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -508,7 +508,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Throw New NotImplementedException() End Function - Public Function ForceAnalyzeAsync(solution As Solution, Optional projectId As ProjectId = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task Implements IDiagnosticAnalyzerService.ForceAnalyzeAsync + Public Function ForceAnalyzeAsync(solution As Solution, onProjectAnalyzed As Action(Of Project), Optional projectId As ProjectId = Nothing, Optional cancellationToken As CancellationToken = Nothing) As Task Implements IDiagnosticAnalyzerService.ForceAnalyzeAsync Throw New NotImplementedException() End Function End Class From 7b359804a5435384b550dc0771b785fa697fadf3 Mon Sep 17 00:00:00 2001 From: Charles Stoner Date: Mon, 11 May 2020 14:08:18 -0700 Subject: [PATCH 133/222] Pass basesBeingResolved to BindTupleType (#44098) --- .../CSharp/Portable/Binder/Binder_Symbols.cs | 6 +-- .../Symbol/Symbols/Source/BaseClassTests.cs | 53 +++++++++++++++++++ .../SymbolsTests/Source/BaseClassTests.vb | 48 +++++++++++++++++ 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs index edcbab91fbaa9..907c48e3632a4 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs @@ -441,7 +441,7 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS case SyntaxKind.TupleType: { var tupleTypeSyntax = (TupleTypeSyntax)syntax; - return TypeWithAnnotations.Create(AreNullableAnnotationsEnabled(tupleTypeSyntax.CloseParenToken), BindTupleType(tupleTypeSyntax, diagnostics)); + return TypeWithAnnotations.Create(AreNullableAnnotationsEnabled(tupleTypeSyntax.CloseParenToken), BindTupleType(tupleTypeSyntax, diagnostics, basesBeingResolved)); } case SyntaxKind.RefType: @@ -596,7 +596,7 @@ private TypeWithAnnotations BindArrayType( return type; } - private TypeSymbol BindTupleType(TupleTypeSyntax syntax, DiagnosticBag diagnostics) + private TypeSymbol BindTupleType(TupleTypeSyntax syntax, DiagnosticBag diagnostics, ConsList basesBeingResolved) { int numElements = syntax.Elements.Count; var types = ArrayBuilder.GetInstance(numElements); @@ -611,7 +611,7 @@ private TypeSymbol BindTupleType(TupleTypeSyntax syntax, DiagnosticBag diagnosti { var argumentSyntax = syntax.Elements[i]; - var argumentType = BindType(argumentSyntax.Type, diagnostics); + var argumentType = BindType(argumentSyntax.Type, diagnostics, basesBeingResolved); types.Add(argumentType); string name = null; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs index 705fbeec206bf..964a0f2587d75 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs @@ -2301,5 +2301,58 @@ class F : A.B { } // class E : A.B { } Diagnostic(ErrorCode.ERR_ManagedAddr, "E").WithArguments("Base.C").WithLocation(12, 11)); } + + [Fact] + [WorkItem(1107185, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1107185")] + public void Tuple_MissingNestedTypeArgument_01() + { + var source = +@"interface I +{ +} +class A : I<(object, A.B)> +{ +}"; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (4,24): error CS0146: Circular base class dependency involving 'A' and 'A' + // class A : I<(object, A.B)> + Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("A", "A").WithLocation(4, 24)); + } + + [Fact] + [WorkItem(1107185, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1107185")] + public void Tuple_MissingNestedTypeArgument_02() + { + var source = +@"class A +{ +} +class B : A<(object, B.C)> +{ +}"; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (4,24): error CS0146: Circular base class dependency involving 'B' and 'B' + // class B : A<(object, B.C)> + Diagnostic(ErrorCode.ERR_CircularBase, "C").WithArguments("B", "B").WithLocation(4, 24)); + } + + [Fact] + public void Tuple_MissingNestedTypeArgument_03() + { + var source = +@"interface I +{ +} +class A : I> +{ +}"; + var comp = CreateCompilation(source); + comp.VerifyDiagnostics( + // (4,41): error CS0146: Circular base class dependency involving 'A' and 'A' + // class A : I> + Diagnostic(ErrorCode.ERR_CircularBase, "B").WithArguments("A", "A").WithLocation(4, 41)); + } } } diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BaseClassTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BaseClassTests.vb index f5fa58009206d..ac7a3fa1ffed4 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BaseClassTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BaseClassTests.vb @@ -2434,6 +2434,54 @@ BC30296: Interface 'A(Of T)' cannot inherit from itself: ]]>) End Sub + + Public Sub Tuple_MissingNestedTypeArgument_01() + Dim source = +"Interface I(Of T) +End Interface +Class A + Implements I(Of (Object, A.B)) +End Class" + Dim comp = CreateCompilation(source) + comp.AssertTheseDiagnostics() + End Sub + + + Public Sub Tuple_MissingNestedTypeArgument_02() + Dim source = +"Class A(Of T) +End Class +Class B + Inherits A(Of (Object, B.C)) +End Class" + Dim comp = CreateCompilation(source) + comp.AssertTheseDiagnostics() + End Sub + + + Public Sub Tuple_MissingNestedTypeArgument_03() + Dim source = +"Interface I(Of T) +End Interface +Class A + Implements I(Of System.ValueTuple(Of Object, A.B)) +End Class" + Dim comp = CreateCompilation(source) + comp.AssertTheseDiagnostics() + End Sub + End Class End Namespace From dc1d2e15b2e822e81cba16a53da029f12d03bcc4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 May 2020 11:58:12 -0700 Subject: [PATCH 134/222] Specialized serialization for options and naming preferences. --- .../Portable/CodeStyle/CodeStyleOption.cs | 13 ++++ .../Portable/Options/SerializableOptionSet.cs | 21 ++++-- .../Core/CodeStyle/CodeStyleOption2`1.cs | 30 +++++++- .../Core/CompilerExtensions.projitems | 1 + .../Core/Extensions/ObjectWriterExtensions.cs | 35 +++++++++ .../Compiler/Core/NamingStyles/NamingStyle.cs | 25 ++++++- .../Serialization/NamingStylePreferences.cs | 25 ++++++- .../Serialization/SerializableNamingRule.cs | 21 +++++- .../Serialization/SymbolSpecification.cs | 72 ++++++++++++++++++- 9 files changed, 230 insertions(+), 13 deletions(-) create mode 100644 src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ObjectWriterExtensions.cs diff --git a/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOption.cs b/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOption.cs index f91f4aa928302..0ac3d930fae7a 100644 --- a/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOption.cs +++ b/src/Workspaces/Core/Portable/CodeStyle/CodeStyleOption.cs @@ -4,12 +4,18 @@ using System; using System.Xml.Linq; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeStyle { /// public class CodeStyleOption : ICodeStyleOption, IEquatable> { + static CodeStyleOption() + { + ObjectBinder.RegisterTypeReader(typeof(CodeStyleOption), ReadFrom); + } + private readonly CodeStyleOption2 _codeStyleOptionImpl; public static CodeStyleOption Default => new CodeStyleOption(default, NotificationOption.Silent); @@ -27,6 +33,7 @@ public T Value set => _codeStyleOptionImpl.Value = value; } + bool IObjectWritable.ShouldReuseInSerialization => _codeStyleOptionImpl.ShouldReuseInSerialization; object ICodeStyleOption.Value => this.Value; NotificationOption2 ICodeStyleOption.Notification => _codeStyleOptionImpl.Notification; ICodeStyleOption ICodeStyleOption.WithValue(object value) => new CodeStyleOption((T)value, Notification); @@ -48,6 +55,12 @@ public NotificationOption Notification public static CodeStyleOption FromXElement(XElement element) => new CodeStyleOption(CodeStyleOption2.FromXElement(element)); + void IObjectWritable.WriteTo(ObjectWriter writer) + => _codeStyleOptionImpl.WriteTo(writer); + + internal static CodeStyleOption ReadFrom(ObjectReader reader) + => new CodeStyleOption(CodeStyleOption2.ReadFrom(reader)); + public bool Equals(CodeStyleOption other) => _codeStyleOptionImpl.Equals(other?._codeStyleOptionImpl); diff --git a/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs b/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs index eb30322d46b3a..53ea1b5961243 100644 --- a/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs +++ b/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs @@ -11,7 +11,6 @@ using System.Diagnostics; using System.Linq; using System.Threading; -using System.Xml.Linq; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles; using Roslyn.Utilities; @@ -206,12 +205,12 @@ public void Serialize(ObjectWriter writer, CancellationToken cancellationToken) } kind = OptionValueKind.CodeStyleOption; - valueToWrite = codeStyleOption.ToXElement().ToString(); + valueToWrite = codeStyleOption; break; case NamingStylePreferences stylePreferences: kind = OptionValueKind.NamingStylePreferences; - valueToWrite = stylePreferences.CreateXElement().ToString(); + valueToWrite = stylePreferences; break; case string str: @@ -253,6 +252,10 @@ public void Serialize(ObjectWriter writer, CancellationToken cancellationToken) RoslynDebug.Assert(value != null); writer.WriteInt32((int)value); } + else if (kind == OptionValueKind.CodeStyleOption || kind == OptionValueKind.NamingStylePreferences) + { + ((IObjectWritable)value!).WriteTo(writer); + } else { writer.WriteValue(value); @@ -308,7 +311,13 @@ public static SerializableOptionSet Deserialize(ObjectReader reader, IOptionServ { var optionKey = DeserializeOptionKey(reader, lookup); var kind = (OptionValueKind)reader.ReadInt32(); - var readValue = kind == OptionValueKind.Enum ? reader.ReadInt32() : reader.ReadValue(); + var readValue = kind switch + { + OptionValueKind.Enum => reader.ReadInt32(), + OptionValueKind.CodeStyleOption => CodeStyleOption2.ReadFrom(reader), + OptionValueKind.NamingStylePreferences => NamingStylePreferences.ReadFrom(reader), + _ => reader.ReadValue(), + }; if (optionKey == default || !serializableOptions.Contains(optionKey.Option)) @@ -327,7 +336,7 @@ public static SerializableOptionSet Deserialize(ObjectReader reader, IOptionServ continue; } - var parsedCodeStyleOption = CodeStyleOption2.FromXElement(XElement.Parse((string)readValue)); + var parsedCodeStyleOption = (CodeStyleOption2)readValue; var value = parsedCodeStyleOption.Value; var type = optionKey.Option.Type.GenericTypeArguments[0]; var convertedValue = type.IsEnum ? Enum.ToObject(type, value) : Convert.ChangeType(value, type); @@ -335,7 +344,7 @@ public static SerializableOptionSet Deserialize(ObjectReader reader, IOptionServ break; case OptionValueKind.NamingStylePreferences: - optionValue = NamingStylePreferences.FromXElement(XElement.Parse((string)readValue)); + optionValue = (NamingStylePreferences)readValue; break; case OptionValueKind.Enum: diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/CodeStyleOption2`1.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/CodeStyleOption2`1.cs index 2bf2edee3893d..65c8af814b457 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/CodeStyleOption2`1.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/CodeStyleOption2`1.cs @@ -6,10 +6,11 @@ using System.Collections.Generic; using System.Xml.Linq; using Microsoft.CodeAnalysis.Diagnostics; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CodeStyle { - internal interface ICodeStyleOption + internal interface ICodeStyleOption : IObjectWritable { XElement ToXElement(); object Value { get; } @@ -38,6 +39,11 @@ internal interface ICodeStyleOption /// internal partial class CodeStyleOption2 : ICodeStyleOption, IEquatable> { + static CodeStyleOption2() + { + ObjectBinder.RegisterTypeReader(typeof(CodeStyleOption2), ReadFrom); + } + public static CodeStyleOption2 Default => new CodeStyleOption2(default, NotificationOption2.Silent); private const int SerializationVersion = 1; @@ -153,6 +159,28 @@ public static CodeStyleOption2 FromXElement(XElement element) }); } + public bool ShouldReuseInSerialization => false; + + public void WriteTo(ObjectWriter writer) + { + writer.WriteValue(GetValueForSerialization()); + writer.WriteInt32((int)(Notification.Severity.ToDiagnosticSeverity() ?? DiagnosticSeverity.Hidden)); + } + + public static CodeStyleOption2 ReadFrom(ObjectReader reader) + { + return new CodeStyleOption2( + reader.ReadValue(), + (DiagnosticSeverity)reader.ReadInt32() switch + { + DiagnosticSeverity.Hidden => NotificationOption2.Silent, + DiagnosticSeverity.Info => NotificationOption2.Suggestion, + DiagnosticSeverity.Warning => NotificationOption2.Warning, + DiagnosticSeverity.Error => NotificationOption2.Error, + var v => throw ExceptionUtilities.UnexpectedValue(v), + }); + } + private static Func GetParser(string type) => type switch { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems index 3bbc78457b7ae..9ff4f7dfcf947 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems @@ -189,6 +189,7 @@ + diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ObjectWriterExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ObjectWriterExtensions.cs new file mode 100644 index 0000000000000..9153c27f7b56c --- /dev/null +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ObjectWriterExtensions.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.PooledObjects; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Shared.Extensions +{ + internal static class ObjectWriterExtensions + { + public static void WriteArray(this ObjectWriter writer, ImmutableArray values, Action write) + { + writer.WriteInt32(values.Length); + foreach (var val in values) + write(writer, val); + } + } + + internal static class ObjectReaderExtensions + { + public static ImmutableArray ReadArray(this ObjectReader reader, Func read) + { + var length = reader.ReadInt32(); + using var _ = ArrayBuilder.GetInstance(length, out var builder); + + for (var i = 0; i < length; i++) + builder.Add(read(reader)); + + return builder.ToImmutable(); + } + } +} diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyle.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyle.cs index 7ff97cb53d914..576e9ac9c7893 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyle.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/NamingStyle.cs @@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.NamingStyles { - internal partial struct NamingStyle : IEquatable + internal partial struct NamingStyle : IEquatable, IObjectWritable { public Guid ID { get; } public string Name { get; } @@ -493,5 +493,28 @@ internal static NamingStyle FromXElement(XElement namingStyleElement) suffix: namingStyleElement.Attribute(nameof(Suffix)).Value, wordSeparator: namingStyleElement.Attribute(nameof(WordSeparator)).Value, capitalizationScheme: (Capitalization)Enum.Parse(typeof(Capitalization), namingStyleElement.Attribute(nameof(CapitalizationScheme)).Value)); + + public bool ShouldReuseInSerialization => false; + + public void WriteTo(ObjectWriter writer) + { + writer.WriteGuid(ID); + writer.WriteString(Name); + writer.WriteString(Prefix ?? string.Empty); + writer.WriteString(Suffix ?? string.Empty); + writer.WriteString(WordSeparator ?? string.Empty); + writer.WriteInt32((int)CapitalizationScheme); + } + + public static NamingStyle ReadFrom(ObjectReader reader) + { + return new NamingStyle( + reader.ReadGuid(), + reader.ReadString(), + reader.ReadString(), + reader.ReadString(), + reader.ReadString(), + (Capitalization)reader.ReadInt32()); + } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/NamingStylePreferences.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/NamingStylePreferences.cs index 99ffd45f7c00b..8dc932d0d1a66 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/NamingStylePreferences.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/NamingStylePreferences.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Xml.Linq; using Microsoft.CodeAnalysis.NamingStyles; +using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles @@ -18,8 +19,13 @@ namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles /// 2. Name Style /// 3. Naming Rule (points to Symbol Specification IDs) /// - internal sealed class NamingStylePreferences : IEquatable + internal sealed class NamingStylePreferences : IEquatable, IObjectWritable { + static NamingStylePreferences() + { + ObjectBinder.RegisterTypeReader(typeof(NamingStylePreferences), ReadFrom); + } + private const int s_serializationVersion = 5; public readonly ImmutableArray SymbolSpecifications; @@ -77,6 +83,23 @@ internal static NamingStylePreferences FromXElement(XElement element) .Select(SerializableNamingRule.FromXElement).ToImmutableArray()); } + public bool ShouldReuseInSerialization => false; + + public void WriteTo(ObjectWriter writer) + { + writer.WriteArray(SymbolSpecifications, (w, v) => v.WriteTo(w)); + writer.WriteArray(NamingStyles, (w, v) => v.WriteTo(w)); + writer.WriteArray(NamingRules, (w, v) => v.WriteTo(w)); + } + + public static NamingStylePreferences ReadFrom(ObjectReader reader) + { + return new NamingStylePreferences( + reader.ReadArray(r => SymbolSpecification.ReadFrom(r)), + reader.ReadArray(r => NamingStyle.ReadFrom(r)), + reader.ReadArray(r => SerializableNamingRule.ReadFrom(r))); + } + public override bool Equals(object obj) => Equals(obj as NamingStylePreferences); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SerializableNamingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SerializableNamingRule.cs index df2f911648232..929a9f65944d8 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SerializableNamingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SerializableNamingRule.cs @@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles { - internal sealed class SerializableNamingRule : IEquatable + internal sealed class SerializableNamingRule : IEquatable, IObjectWritable { public Guid SymbolSpecificationID; public Guid NamingStyleID; @@ -42,6 +42,25 @@ internal static SerializableNamingRule FromXElement(XElement namingRuleElement) }; } + public bool ShouldReuseInSerialization => false; + + public void WriteTo(ObjectWriter writer) + { + writer.WriteGuid(SymbolSpecificationID); + writer.WriteGuid(NamingStyleID); + writer.WriteInt32((int)(EnforcementLevel.ToDiagnosticSeverity() ?? DiagnosticSeverity.Hidden)); + } + + public static SerializableNamingRule ReadFrom(ObjectReader reader) + { + return new SerializableNamingRule + { + SymbolSpecificationID = reader.ReadGuid(), + NamingStyleID = reader.ReadGuid(), + EnforcementLevel = ((DiagnosticSeverity)reader.ReadInt32()).ToReportDiagnostic(), + }; + } + public override bool Equals(object obj) { return Equals(obj as SerializableNamingRule); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs index c0543c03d141f..4e3449cfe6af1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs @@ -19,7 +19,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles { - internal sealed class SymbolSpecification : IEquatable + internal sealed class SymbolSpecification : IEquatable, IObjectWritable { private static readonly SymbolSpecification DefaultSymbolSpecificationTemplate = CreateDefaultSymbolSpecification(); @@ -218,6 +218,27 @@ internal XElement CreateXElement() CreateModifiersXElement()); } + public bool ShouldReuseInSerialization => false; + + public void WriteTo(ObjectWriter writer) + { + writer.WriteGuid(ID); + writer.WriteString(Name); + writer.WriteArray(ApplicableSymbolKindList, (w, v) => v.WriteTo(w)); + writer.WriteArray(ApplicableAccessibilityList, (w, v) => w.WriteInt32((int)v)); + writer.WriteArray(RequiredModifierList, (w, v) => v.WriteTo(w)); + } + + public static SymbolSpecification ReadFrom(ObjectReader reader) + { + return new SymbolSpecification( + reader.ReadGuid(), + reader.ReadString(), + reader.ReadArray(r => SymbolKindOrTypeKind.ReadFrom(r)), + reader.ReadArray(r => (Accessibility)r.ReadInt32()), + reader.ReadArray(r => ModifierKind.ReadFrom(r))); + } + private XElement CreateSymbolKindsXElement() { var symbolKindsElement = new XElement(nameof(ApplicableSymbolKindList)); @@ -309,7 +330,7 @@ private interface ISymbolMatcher bool MatchesSymbol(ISymbol symbol); } - public struct SymbolKindOrTypeKind : IEquatable, ISymbolMatcher + public struct SymbolKindOrTypeKind : IEquatable, ISymbolMatcher, IObjectWritable { public SymbolKind? SymbolKind { get; } public TypeKind? TypeKind { get; } @@ -348,6 +369,43 @@ internal XElement CreateXElement() MethodKind.HasValue ? new XElement(nameof(MethodKind), MethodKind) : throw ExceptionUtilities.Unreachable; + public bool ShouldReuseInSerialization => throw new NotImplementedException(); + + public void WriteTo(ObjectWriter writer) + { + if (SymbolKind != null) + { + writer.WriteInt32(1); + writer.WriteInt32((int)SymbolKind); + } + else if (TypeKind != null) + { + writer.WriteInt32(2); + writer.WriteInt32((int)TypeKind); + } + else if (MethodKind != null) + { + writer.WriteInt32(3); + writer.WriteInt32((int)MethodKind); + } + else + { + writer.WriteInt32(0); + } + } + + public static SymbolKindOrTypeKind ReadFrom(ObjectReader reader) + { + return reader.ReadInt32() switch + { + 0 => default, + 1 => new SymbolKindOrTypeKind((SymbolKind)reader.ReadInt32()), + 2 => new SymbolKindOrTypeKind((TypeKind)reader.ReadInt32()), + 3 => new SymbolKindOrTypeKind((MethodKind)reader.ReadInt32()), + var v => throw ExceptionUtilities.UnexpectedValue(v), + }; + } + internal static SymbolKindOrTypeKind AddSymbolKindFromXElement(XElement symbolKindElement) => new SymbolKindOrTypeKind((SymbolKind)Enum.Parse(typeof(SymbolKind), symbolKindElement.Value)); @@ -370,7 +428,7 @@ public override int GetHashCode() } } - public struct ModifierKind : ISymbolMatcher, IEquatable + public struct ModifierKind : ISymbolMatcher, IEquatable, IObjectWritable { public ModifierKindEnum ModifierKindWrapper; @@ -458,6 +516,14 @@ internal XElement CreateXElement() internal static ModifierKind FromXElement(XElement modifierElement) => new ModifierKind((ModifierKindEnum)Enum.Parse(typeof(ModifierKindEnum), modifierElement.Value)); + public bool ShouldReuseInSerialization => false; + + public void WriteTo(ObjectWriter writer) + => writer.WriteInt32((int)ModifierKindWrapper); + + public static ModifierKind ReadFrom(ObjectReader reader) + => new ModifierKind((ModifierKindEnum)reader.ReadInt32()); + public override bool Equals(object obj) => obj is ModifierKind kind && Equals(kind); From af28ba6afc606fcc70c6f06068894da60ad8bf35 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Mon, 11 May 2020 15:02:16 -0700 Subject: [PATCH 135/222] Use assert --- src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs b/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs index 53ea1b5961243..a53c7f486f74c 100644 --- a/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs +++ b/src/Workspaces/Core/Portable/Options/SerializableOptionSet.cs @@ -254,7 +254,8 @@ public void Serialize(ObjectWriter writer, CancellationToken cancellationToken) } else if (kind == OptionValueKind.CodeStyleOption || kind == OptionValueKind.NamingStylePreferences) { - ((IObjectWritable)value!).WriteTo(writer); + RoslynDebug.Assert(value != null); + ((IObjectWritable)value).WriteTo(writer); } else { From c4aa5fe2c590523fb1fb0d175a26b2d58a160af1 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Mon, 11 May 2020 15:14:35 -0700 Subject: [PATCH 136/222] Update src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs --- .../Core/NamingStyles/Serialization/SymbolSpecification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs index 4e3449cfe6af1..76ca282826bb6 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/Serialization/SymbolSpecification.cs @@ -369,7 +369,7 @@ internal XElement CreateXElement() MethodKind.HasValue ? new XElement(nameof(MethodKind), MethodKind) : throw ExceptionUtilities.Unreachable; - public bool ShouldReuseInSerialization => throw new NotImplementedException(); + public bool ShouldReuseInSerialization => false; public void WriteTo(ObjectWriter writer) { From ced80acaf5220cea6b28b2810ca7fea8698e8e72 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Mon, 11 May 2020 15:41:57 -0700 Subject: [PATCH 137/222] Address feedback --- .../VisualStudioDiagnosticAnalyzerService.cs | 58 +++++++++++-------- .../Core/Def/ServicesVSResources.resx | 6 ++ .../Core/Def/xlf/ServicesVSResources.cs.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.de.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.es.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.fr.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.it.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.ja.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.ko.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.pl.xlf | 10 ++++ .../Def/xlf/ServicesVSResources.pt-BR.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.ru.xlf | 10 ++++ .../Core/Def/xlf/ServicesVSResources.tr.xlf | 10 ++++ .../Def/xlf/ServicesVSResources.zh-Hans.xlf | 10 ++++ .../Def/xlf/ServicesVSResources.zh-Hant.xlf | 10 ++++ 15 files changed, 171 insertions(+), 23 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs b/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs index d0a2cb3a4541b..073c30c9f4765 100644 --- a/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs +++ b/src/VisualStudio/Core/Def/Implementation/Diagnostics/VisualStudioDiagnosticAnalyzerService.cs @@ -209,15 +209,20 @@ public void RunAnalyzers(IVsHierarchy? hierarchy) var asyncToken = _listener.BeginAsyncOperation($"{nameof(VisualStudioDiagnosticAnalyzerService)}_{nameof(RunAnalyzers)}"); Task.Run(async () => { - var onProjectAnalyzed = statusBarUpdater != null ? statusBarUpdater.OnProjectAnalyzed : (Action)((Project _) => { }); - await _diagnosticService.ForceAnalyzeAsync(solution, onProjectAnalyzed, project?.Id, CancellationToken.None).ConfigureAwait(false); - - // If user has disabled live analyzer execution for any project(s), i.e. set RunAnalyzersDuringLiveAnalysis = false, - // then ForceAnalyzeAsync will not cause analyzers to execute. - // We explicitly fetch diagnostics for such projects and report these as "Host" diagnostics. - HandleProjectsWithDisabledAnalysis(); + try + { + var onProjectAnalyzed = statusBarUpdater != null ? statusBarUpdater.OnProjectAnalyzed : (Action)((Project _) => { }); + await _diagnosticService.ForceAnalyzeAsync(solution, onProjectAnalyzed, project?.Id, CancellationToken.None).ConfigureAwait(false); - statusBarUpdater?.Dispose(); + // If user has disabled live analyzer execution for any project(s), i.e. set RunAnalyzersDuringLiveAnalysis = false, + // then ForceAnalyzeAsync will not cause analyzers to execute. + // We explicitly fetch diagnostics for such projects and report these as "Host" diagnostics. + HandleProjectsWithDisabledAnalysis(); + } + finally + { + statusBarUpdater?.Dispose(); + } }).CompletesAsyncOperation(asyncToken); return; @@ -352,6 +357,7 @@ private sealed class StatusBarUpdater : IDisposable private readonly uint _totalProjectCount; private readonly string _statusMessageWhileRunning; private readonly string _statusMesageOnCompleted; + private readonly string _statusMesageOnTerminated; private readonly Timer _timer; private int _analyzedProjectCount; @@ -371,6 +377,9 @@ public StatusBarUpdater(IVsStatusbar statusBar, IThreadingContext threadingConte _statusMesageOnCompleted = projectOrSolutionName != null ? string.Format(ServicesVSResources.Code_analysis_completed_for_0, projectOrSolutionName) : ServicesVSResources.Code_analysis_completed_for_Solution; + _statusMesageOnTerminated = projectOrSolutionName != null + ? string.Format(ServicesVSResources.Code_analysis_terminated_before_completion_for_0, projectOrSolutionName) + : ServicesVSResources.Code_analysis_terminated_before_completion_for_Solution; // Set the initial status bar progress and text. _statusBar.Progress(ref _statusBarCookie, fInProgress: 1, _statusMessageWhileRunning, nComplete: 0, nTotal: totalProjectCount); @@ -383,45 +392,48 @@ public StatusBarUpdater(IVsStatusbar statusBar, IThreadingContext threadingConte internal void OnProjectAnalyzed(Project _) { - var analyzedProjectCount = Interlocked.Increment(ref _analyzedProjectCount); - UpdateStatus(isRunning: analyzedProjectCount < _totalProjectCount); + Interlocked.Increment(ref _analyzedProjectCount); + UpdateStatusCore(); } // Add a message to VS status bar that we are running code analysis. private void UpdateStatusOnTimer(object state) - => UpdateStatus(isRunning: true); + => UpdateStatusCore(); public void Dispose() { _timer.Dispose(); _disposed = true; - UpdateStatus(isRunning: false); + UpdateStatusCore(); } - private void UpdateStatus(bool isRunning) + private void UpdateStatusCore() { - Task.Run(async () => + _threadingContext.JoinableTaskFactory.RunAsync(async () => { await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(); string message; - uint analyzedCount; int fInProgress; - if (isRunning && !_disposed && _analyzedProjectCount != _totalProjectCount) + var analyzedProjectCount = (uint)_analyzedProjectCount; + if (analyzedProjectCount == _totalProjectCount) { - message = _statusMessageWhileRunning; - analyzedCount = (uint)_analyzedProjectCount; - fInProgress = 1; + message = _statusMesageOnCompleted; + fInProgress = 0; } - else + else if (_disposed) { - message = _statusMesageOnCompleted; - analyzedCount = _totalProjectCount; + message = _statusMesageOnTerminated; fInProgress = 0; } + else + { + message = _statusMessageWhileRunning; + fInProgress = 1; + } // Update the status bar progress and text. - _statusBar.Progress(ref _statusBarCookie, fInProgress, message, analyzedCount, _totalProjectCount); + _statusBar.Progress(ref _statusBarCookie, fInProgress, message, analyzedProjectCount, _totalProjectCount); _statusBar.SetText(message); }); } diff --git a/src/VisualStudio/Core/Def/ServicesVSResources.resx b/src/VisualStudio/Core/Def/ServicesVSResources.resx index e32bb13a3b71b..afcfbaf0f8e8c 100644 --- a/src/VisualStudio/Core/Def/ServicesVSResources.resx +++ b/src/VisualStudio/Core/Def/ServicesVSResources.resx @@ -1344,6 +1344,12 @@ I agree to all of the foregoing: Code analysis completed for Solution. + + Code analysis terminated before completion for '{0}'. + + + Code analysis terminated before completion for Solution. + Background analysis scope: diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf index d199bed06b19e..2b4e696a41de1 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf @@ -122,6 +122,16 @@ Dokončila se analýza kódu pro řešení. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Obarvit regulární výrazy diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf index 4082320d477cf..9f40b40c57c90 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf @@ -122,6 +122,16 @@ Die Codeanalyse für die Projektmappe wurde abgeschlossen. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Reguläre Ausdrücke farbig hervorheben diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf index 13ca1750ad6de..078f844135122 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf @@ -122,6 +122,16 @@ El análisis de código se ha completado para la solución. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Colorear expresiones regulares diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf index f6a5ffa0869d6..cdf9da2a5c047 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf @@ -122,6 +122,16 @@ Analyse du code effectuée pour la solution. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Coloriser les expressions régulières diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf index 0a9c6ded5b5ba..d1a00cd67d2ea 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf @@ -122,6 +122,16 @@ Analisi codice completata per la soluzione. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Colora espressioni regolari diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf index f9fbc799b498a..1490adfd2d5f2 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf @@ -122,6 +122,16 @@ ソリューションのコード分析が完了しました。 + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions 正規表現をカラー化 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf index 590948605229b..ee403020bad5b 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf @@ -122,6 +122,16 @@ 솔루션에 대한 코드 분석이 완료되었습니다. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions 정규식 색 지정 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf index fffa631f39350..6f55c48766b98 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf @@ -122,6 +122,16 @@ Ukończono analizę kodu dla rozwiązania. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Koloruj wyrażenia regularne diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf index 654e37c865692..42a71dc4e0f4f 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf @@ -122,6 +122,16 @@ Análise de código concluída para a Solução. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Colorir expressões regulares diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf index bee4ec9a68756..c70b48ebe9379 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.ru.xlf @@ -122,6 +122,16 @@ Анализ кода для решения выполнен. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Выделить регулярные выражения цветом diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf index a04fb04637fb1..9ccb0f8e2284f 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.tr.xlf @@ -122,6 +122,16 @@ Çözüm için kod analizi tamamlandı. + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions Normal ifadeleri renklendir diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf index d35b7079dc55b..53a1ad5d94ab5 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hans.xlf @@ -122,6 +122,16 @@ 解决方案的代码分析已完成。 + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions 为正规表达式着色 diff --git a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf index 460e875d4bf90..a20376a6e8a39 100644 --- a/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf +++ b/src/VisualStudio/Core/Def/xlf/ServicesVSResources.zh-Hant.xlf @@ -122,6 +122,16 @@ 解決方案的程式碼分析已完成。 + + Code analysis terminated before completion for '{0}'. + Code analysis terminated before completion for '{0}'. + + + + Code analysis terminated before completion for Solution. + Code analysis terminated before completion for Solution. + + Colorize regular expressions 為規則運算式添加色彩 From 7606d598e9435d2d32b286e9137a362db85f7577 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Mon, 11 May 2020 15:48:49 -0700 Subject: [PATCH 138/222] Make transitive project references explicit --- .../IdeCoreBenchmarks/IdeCoreBenchmarks.csproj | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj index d0a8ce01adf4f..6c0ce1ce453b4 100644 --- a/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj +++ b/src/Tools/IdeCoreBenchmarks/IdeCoreBenchmarks.csproj @@ -22,12 +22,28 @@ + + + + + + + + - + + + + + + + + + From 71796882613092550b3a0b1ee6dbf893826a6898 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Mon, 11 May 2020 16:14:54 -0700 Subject: [PATCH 139/222] FAR for target-typed new (#43645) --- .../Collections/ImmutableArrayExtensions.cs | 19 +++++ .../ChangeSignature/AddParameterTests.cs | 39 ++++++++++ .../IDefinitionsAndReferencesFactory.cs | 4 +- .../FindReferencesTests.ConstructorSymbols.vb | 75 +++++++++++++++++++ .../Finders/AbstractReferenceFinder.cs | 31 +++++++- .../ConstructorSymbolReferenceFinder.cs | 9 ++- .../SyntaxTree/SyntaxTreeIndex.ContextInfo.cs | 14 +++- .../SyntaxTree/SyntaxTreeIndex_Create.cs | 5 +- .../SyntaxTree/SyntaxTreeIndex_Forwarders.cs | 1 + .../SyntaxTree/SyntaxTreeIndex_Persistence.cs | 2 +- .../CSharp/Formatting/Rules/SyntaxKindEx.cs | 5 +- .../Services/SyntaxFacts/CSharpSyntaxFacts.cs | 11 ++- .../Core/Services/SyntaxFacts/ISyntaxFacts.cs | 2 + .../SyntaxFacts/ISyntaxFactsExtensions.cs | 3 + .../SyntaxFacts/VisualBasicSyntaxFacts.vb | 4 + 15 files changed, 212 insertions(+), 12 deletions(-) diff --git a/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs b/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs index c0549d75634b6..5fc661581f61a 100644 --- a/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs +++ b/src/Compilers/Core/Portable/Collections/ImmutableArrayExtensions.cs @@ -497,6 +497,25 @@ internal static ImmutableArray Concat(this ImmutableArray first, Immuta return first.AddRange(second); } + internal static ImmutableArray Concat(this ImmutableArray first, ImmutableArray second, ImmutableArray third) + { + var builder = ArrayBuilder.GetInstance(first.Length + second.Length + third.Length); + builder.AddRange(first); + builder.AddRange(second); + builder.AddRange(third); + return builder.ToImmutableAndFree(); + } + + internal static ImmutableArray Concat(this ImmutableArray first, ImmutableArray second, ImmutableArray third, ImmutableArray fourth) + { + var builder = ArrayBuilder.GetInstance(first.Length + second.Length + third.Length + fourth.Length); + builder.AddRange(first); + builder.AddRange(second); + builder.AddRange(third); + builder.AddRange(fourth); + return builder.ToImmutableAndFree(); + } + internal static ImmutableArray Concat(this ImmutableArray first, T second) { return first.Add(second); diff --git a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs index 0ed55446c08f8..d450682fa6cab 100644 --- a/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs +++ b/src/EditorFeatures/CSharpTest/ChangeSignature/AddParameterTests.cs @@ -1222,5 +1222,44 @@ static void M(string[] args) await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); } + + [WpfFact, Trait(Traits.Feature, Traits.Features.ChangeSignature)] + [WorkItem(44126, "https://github.com/dotnet/roslyn/issues/44126")] + public async Task AddAndReorderImplicitObjectCreationParameter() + { + var markup = @" +using System; +class C +{ + $$C(int x, string y) + { + } + + public void M() + { + _ = new(1, 2); + } +}"; + var permutation = new[] { + new AddedParameterOrExistingIndex(1), + new AddedParameterOrExistingIndex(new AddedParameter(null, "byte", "b", "34"), "byte"), + new AddedParameterOrExistingIndex(0)}; + var updatedCode = @" +using System; +class C +{ + C(string y, byte b, int x) + { + } + + public void M() + { + _ = new(1, 2); + } +}"; + // Expect: _ = new(2, 34, 1); + // Tracked by https://github.com/dotnet/roslyn/issues/44126 + await TestChangeSignatureViaCommandAsync(LanguageNames.CSharp, markup, updatedSignature: permutation, expectedUpdatedInvocationDocumentCode: updatedCode); + } } } diff --git a/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs b/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs index 3d39fd81de161..3b6ca9de3d824 100644 --- a/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs +++ b/src/EditorFeatures/Core/FindUsages/IDefinitionsAndReferencesFactory.cs @@ -115,8 +115,6 @@ private static async Task ToDefinitionItemAsync( var properties = GetProperties(definition, isPrimary); - var displayableProperties = AbstractReferenceFinder.GetAdditionalFindUsagesProperties(definition); - // If it's a namespace, don't create any normal location. Namespaces // come from many different sources, but we'll only show a single // root definition node for it. That node won't be navigable. @@ -162,6 +160,8 @@ private static async Task ToDefinitionItemAsync( properties, displayIfNoReferences); } + var displayableProperties = AbstractReferenceFinder.GetAdditionalFindUsagesProperties(definition); + return DefinitionItem.Create( tags, displayParts, sourceLocations.ToImmutable(), nameDisplayParts, properties, displayableProperties, displayIfNoReferences); diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb index 90da0066bd077..911fb2dfbc4ff 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb @@ -815,6 +815,81 @@ public class A } + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestConstructor_TargetTypedNew_Local(kind As TestKind, host As TestHost) As Task + Dim input = + + + +class D +{ + public {|Definition:$$D|}() { } +} + + +class C +{ + void M() + { + D d = [|new|](); + D d2 = [|new|](); + } +} + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestConstructor_TargetTypedNew_Local_WithArguments(kind As TestKind, host As TestHost) As Task + Dim input = + + + +class D +{ + public {|Definition:$$D|}(int i, int j) { } +} + + +class C +{ + void M() + { + D d = [|new|](1, 2); + D d2 = [|new|](3, 4); + } +} + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestConstructor_TargetTypedNew_Field(kind As TestKind, host As TestHost) As Task + Dim input = + + + +class D +{ + public {|Definition:$$D|}() { } +} + + +class C +{ + D d = [|new|](); + D d2 = [|new|](); +} + + Await TestAPIAndFeature(input, kind, host) End Function diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs index 4aed46cd3912f..87a98b6571a93 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs @@ -263,7 +263,6 @@ protected static ImmutableArray FindReferencesInTokens( var location = token.GetLocation(); var symbolUsageInfo = GetSymbolUsageInfo(token.Parent, semanticModel, syntaxFacts, semanticFacts, cancellationToken); - var isWrittenTo = symbolUsageInfo.IsWrittenTo(); locations.Add(new FinderLocation(token.Parent, new ReferenceLocation( document, alias, location, isImplicit: false, symbolUsageInfo, GetAdditionalFindUsagesProperties(token.Parent, semanticModel, syntaxFacts), candidateReason: reason))); @@ -433,6 +432,9 @@ protected Task> FindDocumentsWithDeconstructionAsync(Pr protected Task> FindDocumentsWithAwaitExpressionAsync(Project project, IImmutableSet documents, CancellationToken cancellationToken) => FindDocumentsWithPredicateAsync(project, documents, predicate: sti => sti.ContainsAwait, cancellationToken); + protected Task> FindDocumentsWithImplicitObjectCreationExpressionAsync(Project project, IImmutableSet documents, CancellationToken cancellationToken) + => FindDocumentsWithPredicateAsync(project, documents, predicate: sti => sti.ContainsImplicitObjectCreation, cancellationToken); + /// /// If the `node` implicitly matches the `symbol`, then it will be added to `locations`. /// @@ -564,6 +566,33 @@ void CollectMatchingReferences(ISymbol originalUnreducedSymbolDefinition, Syntax } } + protected Task> FindReferencesInImplicitObjectCreationExpressionAsync( + ISymbol symbol, + Document document, + SemanticModel semanticModel, + CancellationToken cancellationToken) + { + return FindReferencesInDocumentAsync(symbol, document, IsRelevantDocument, CollectMatchingReferences, cancellationToken); + + static bool IsRelevantDocument(SyntaxTreeIndex syntaxTreeInfo) + => syntaxTreeInfo.ContainsImplicitObjectCreation; + + void CollectMatchingReferences(ISymbol originalUnreducedSymbolDefinition, SyntaxNode node, + ISyntaxFactsService syntaxFacts, ISemanticFactsService semanticFacts, ArrayBuilder locations) + { + var constructor = semanticModel.GetSymbolInfo(node).Symbol; + + if (Matches(constructor, originalUnreducedSymbolDefinition)) + { + var location = node.GetFirstToken().GetLocation(); + var symbolUsageInfo = GetSymbolUsageInfo(node, semanticModel, syntaxFacts, semanticFacts, cancellationToken); + + locations.Add(new FinderLocation(node, new ReferenceLocation( + document, alias: null, location, isImplicit: true, symbolUsageInfo, GetAdditionalFindUsagesProperties(node, semanticModel, syntaxFacts), CandidateReason.None))); + } + } + } + private static bool Matches(ISymbol symbol1, ISymbol notNulloriginalUnreducedSymbol2) { return symbol1 != null && SymbolEquivalenceComparer.Instance.Equals( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 18cedc26cf2a7..d6a180e876e8d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -40,7 +40,11 @@ protected override async Task> DetermineDocumentsToSear ? await FindDocumentsAsync(project, documents, cancellationToken, simpleName).ConfigureAwait(false) : SpecializedCollections.EmptyEnumerable(); - return documentsWithName.Concat(documentsWithType) + var documentsWithImplicitObjectCreations = symbol.MethodKind == MethodKind.Constructor + ? await FindDocumentsWithImplicitObjectCreationExpressionAsync(project, documents, cancellationToken).ConfigureAwait(false) + : ImmutableArray.Empty; + + return documentsWithName.Concat(documentsWithType, documentsWithImplicitObjectCreations) .Concat(documentsWithAttribute) .Distinct() .ToImmutableArray(); @@ -96,8 +100,9 @@ private async Task> FindReferencesInDocumentWorke var ordinaryRefs = await FindOrdinaryReferencesAsync(symbol, document, semanticModel, findParentNode, cancellationToken).ConfigureAwait(false); var attributeRefs = await FindAttributeReferencesAsync(symbol, document, semanticModel, cancellationToken).ConfigureAwait(false); var predefinedTypeRefs = await FindPredefinedTypeReferencesAsync(symbol, document, semanticModel, cancellationToken).ConfigureAwait(false); + var implicitObjectCreationMatches = await FindReferencesInImplicitObjectCreationExpressionAsync(symbol, document, semanticModel, cancellationToken).ConfigureAwait(false); - return ordinaryRefs.Concat(attributeRefs).Concat(predefinedTypeRefs); + return ordinaryRefs.Concat(attributeRefs, predefinedTypeRefs, implicitObjectCreationMatches); } private Task> FindOrdinaryReferencesAsync( diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ContextInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ContextInfo.cs index 4f63dc596f96a..a6b1fed241638 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ContextInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex.ContextInfo.cs @@ -29,7 +29,8 @@ public ContextInfo( bool containsIndexerMemberCref, bool containsDeconstruction, bool containsAwait, - bool containsTupleExpressionOrTupleType) + bool containsTupleExpressionOrTupleType, + bool containsImplicitObjectCreation) : this(predefinedTypes, predefinedOperators, ConvertToContainingNodeFlag( containsForEachStatement, @@ -42,7 +43,8 @@ public ContextInfo( containsIndexerMemberCref, containsDeconstruction, containsAwait, - containsTupleExpressionOrTupleType)) + containsTupleExpressionOrTupleType, + containsImplicitObjectCreation)) { } @@ -64,7 +66,8 @@ private static ContainingNodes ConvertToContainingNodeFlag( bool containsIndexerMemberCref, bool containsDeconstruction, bool containsAwait, - bool containsTupleExpressionOrTupleType) + bool containsTupleExpressionOrTupleType, + bool containsImplicitObjectCreation) { var containingNodes = ContainingNodes.None; @@ -79,6 +82,7 @@ private static ContainingNodes ConvertToContainingNodeFlag( containingNodes |= containsDeconstruction ? ContainingNodes.ContainsDeconstruction : 0; containingNodes |= containsAwait ? ContainingNodes.ContainsAwait : 0; containingNodes |= containsTupleExpressionOrTupleType ? ContainingNodes.ContainsTupleExpressionOrTupleType : 0; + containingNodes |= containsImplicitObjectCreation ? ContainingNodes.ContainsImplicitObjectCreation : 0; return containingNodes; } @@ -98,6 +102,9 @@ public bool ContainsDeconstruction public bool ContainsAwait => (_containingNodes & ContainingNodes.ContainsAwait) == ContainingNodes.ContainsAwait; + public bool ContainsImplicitObjectCreation + => (_containingNodes & ContainingNodes.ContainsImplicitObjectCreation) == ContainingNodes.ContainsImplicitObjectCreation; + public bool ContainsLockStatement => (_containingNodes & ContainingNodes.ContainsLockStatement) == ContainingNodes.ContainsLockStatement; @@ -161,6 +168,7 @@ private enum ContainingNodes ContainsDeconstruction = 1 << 8, ContainsAwait = 1 << 9, ContainsTupleExpressionOrTupleType = 1 << 10, + ContainsImplicitObjectCreation = 1 << 11, } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs index 1f06a758c3535..017d2f1bd561c 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Create.cs @@ -88,6 +88,7 @@ private static async Task CreateIndexAsync( var containsDeconstruction = false; var containsAwait = false; var containsTupleExpressionOrTupleType = false; + var containsImplicitObjectCreation = false; var predefinedTypes = (int)PredefinedType.None; var predefinedOperators = (int)PredefinedOperator.None; @@ -116,6 +117,7 @@ private static async Task CreateIndexAsync( containsAwait = containsAwait || syntaxFacts.IsAwaitExpression(node); containsTupleExpressionOrTupleType = containsTupleExpressionOrTupleType || syntaxFacts.IsTupleExpression(node) || syntaxFacts.IsTupleType(node); + containsImplicitObjectCreation = containsImplicitObjectCreation || syntaxFacts.IsImplicitObjectCreationExpression(node); if (syntaxFacts.IsUsingAliasDirective(node) && infoFactory.TryGetAliasesFromUsingDirective(node, out var aliases)) { @@ -263,7 +265,8 @@ private static async Task CreateIndexAsync( containsIndexerMemberCref, containsDeconstruction, containsAwait, - containsTupleExpressionOrTupleType), + containsTupleExpressionOrTupleType, + containsImplicitObjectCreation), new DeclarationInfo( declaredSymbolInfos.ToImmutable()), new ExtensionMethodInfo( diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs index 97af75a6f4104..43c9da9c0744f 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Forwarders.cs @@ -31,6 +31,7 @@ public ImmutableArray ComplexExtensionMethodInfo public bool ContainsForEachStatement => _contextInfo.ContainsForEachStatement; public bool ContainsDeconstruction => _contextInfo.ContainsDeconstruction; public bool ContainsAwait => _contextInfo.ContainsAwait; + public bool ContainsImplicitObjectCreation => _contextInfo.ContainsImplicitObjectCreation; public bool ContainsLockStatement => _contextInfo.ContainsLockStatement; public bool ContainsUsingStatement => _contextInfo.ContainsUsingStatement; public bool ContainsQueryExpression => _contextInfo.ContainsQueryExpression; diff --git a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs index 07e0ac09b6396..1d6df83b9d510 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SyntaxTree/SyntaxTreeIndex_Persistence.cs @@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.FindSymbols internal sealed partial class SyntaxTreeIndex : IObjectWritable { private const string PersistenceName = ""; - private static readonly Checksum SerializationFormatChecksum = Checksum.Create("17"); + private static readonly Checksum SerializationFormatChecksum = Checksum.Create("18"); public readonly Checksum Checksum; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SyntaxKindEx.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SyntaxKindEx.cs index 1a91d33dc4c5c..7d108ad9bd330 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SyntaxKindEx.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SyntaxKindEx.cs @@ -17,6 +17,7 @@ internal static class SyntaxKindEx { // The code style layer does not currently need access to any syntax defined in newer versions of Roslyn. This // type is included as an example should this change in future updates. + public const SyntaxKind ImplicitObjectCreationExpression = (SyntaxKind)8659; public const SyntaxKind RelationalPattern = (SyntaxKind)9029; public const SyntaxKind ParenthesizedPattern = (SyntaxKind)9028; public const SyntaxKind AndPattern = (SyntaxKind)9032; @@ -26,12 +27,14 @@ internal static class SyntaxKindEx public const SyntaxKind OrKeyword = (SyntaxKind)8438; #if !CODE_STYLE + private const uint ImplicitObjectCreationExpressionAssertion = -(ImplicitObjectCreationExpression - SyntaxKind.ImplicitObjectCreationExpression); + /// /// This will only compile if and have the same /// value. /// /// - /// The subtraction will overflow if is greater, and the conversion + /// The subtraction will overflow if is greater, and the conversion /// to an unsigned value after negation will overflow if is greater. /// private const uint RelationalPatternValueAssertion = -(RelationalPattern - SyntaxKind.RelationalPattern); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs index fccaace6963b5..270178a4fb395 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Text; using System.Threading; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.LanguageServices; @@ -17,7 +18,6 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; -using Microsoft.CodeAnalysis; #if CODE_STYLE using Microsoft.CodeAnalysis.Internal.Editing; @@ -2145,5 +2145,14 @@ public SyntaxNode GetTypeOfTypePattern(SyntaxNode node) => ((TypePatternSyntax)node).Type; #endif + + public bool IsImplicitObjectCreation(SyntaxNode node) + { +#if CODE_STYLE + return ((CSharpSyntaxNode)node).Kind() == Formatting.SyntaxKindEx.ImplicitObjectCreationExpression; +#else + return ((CSharpSyntaxNode)node).Kind() == SyntaxKind.ImplicitObjectCreationExpression; +#endif + } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFacts.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFacts.cs index 4d8419ecd5923..3ee16cb99b5e8 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFacts.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFacts.cs @@ -482,6 +482,8 @@ void GetPartsOfTupleExpression(SyntaxNode node, /// Gets the for the declaration. /// DeclarationKind GetDeclarationKind(SyntaxNode declaration); + + bool IsImplicitObjectCreation(SyntaxNode node); } [Flags] diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFactsExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFactsExtensions.cs index 43bb8b1ecf6dd..bb4a5ba46e780 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFactsExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxFactsExtensions.cs @@ -333,6 +333,9 @@ public static bool IsTrueLiteralExpression(this ISyntaxFacts syntaxFacts, [NotNu public static bool IsAwaitExpression(this ISyntaxFacts syntaxFacts, [NotNullWhen(true)] SyntaxNode? node) => node?.RawKind == syntaxFacts.SyntaxKinds.AwaitExpression; + public static bool IsImplicitObjectCreationExpression(this ISyntaxFacts syntaxFacts, [NotNullWhen(true)] SyntaxNode? node) + => syntaxFacts.IsImplicitObjectCreation(node); + public static bool IsBaseExpression(this ISyntaxFacts syntaxFacts, [NotNullWhen(true)] SyntaxNode? node) => node?.RawKind == syntaxFacts.SyntaxKinds.BaseExpression; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxFacts.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxFacts.vb index af1d512696497..4714ec010624f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxFacts.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxFacts.vb @@ -2291,6 +2291,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.LanguageServices Return False End Function + Public Function IsImplicitObjectCreation(node As SyntaxNode) As Boolean Implements ISyntaxFacts.IsImplicitObjectCreation + Return False + End Function + Public Function SupportsNotPattern(options As ParseOptions) As Boolean Implements ISyntaxFacts.SupportsNotPattern Return False End Function From 51926c6320ea058acefcf25352dd4fb73ffd6abc Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Thu, 16 Apr 2020 16:34:59 -0700 Subject: [PATCH 140/222] Enable IDE0043 (Format string contains invalid placeholder) as build warning for IDE projects (CodeStyle, Features and Workspaces layers) --- .editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index 7e1d9cec4136e..67c51e144f679 100644 --- a/.editorconfig +++ b/.editorconfig @@ -235,6 +235,9 @@ dotnet_diagnostic.IDE0036.severity = warning # IDE0040: Add accessibility modifiers dotnet_diagnostic.IDE0040.severity = warning +# IDE0043: Format string contains invalid placeholder +dotnet_diagnostic.IDE0043.severity = warning + # IDE0044: Make field readonly dotnet_diagnostic.IDE0044.severity = warning From 986d98bd766da0d8b1c6a6536b78609c4b006925 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Wed, 22 Apr 2020 06:29:36 -0700 Subject: [PATCH 141/222] Enable few more code style rules in IDE projects: # IDE0011: Add braces csharp_prefer_braces = when_multiline:warning # IDE0035: Remove unreachable code dotnet_diagnostic.IDE0035.severity = warning # IDE0059: Unnecessary assignment to a value dotnet_diagnostic.IDE0059.severity = warning --- .editorconfig | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.editorconfig b/.editorconfig index 67c51e144f679..dc7b06ed952fe 100644 --- a/.editorconfig +++ b/.editorconfig @@ -225,10 +225,20 @@ dotnet_diagnostic.RS0037.severity = none # warning RS0005: Do not use generic CodeAction.Create to create CodeAction dotnet_diagnostic.RS0005.severity = none +[*.{cs,vb}] +# Temporary workaround to enable FixAll in solution +dotnet_diagnostic.IDE0059.severity = none + [src/{Analyzers,CodeStyle,Features,Workspaces}/**/*.{cs,vb}] # IDE0005: Remove unnecessary usings/imports dotnet_diagnostic.IDE0005.severity = warning +# IDE0011: Add braces +csharp_prefer_braces = when_multiline:warning + +# IDE0035: Remove unreachable code +dotnet_diagnostic.IDE0035.severity = warning + # IDE0036: Order modifiers dotnet_diagnostic.IDE0036.severity = warning @@ -247,3 +257,6 @@ dotnet_diagnostic.IDE0051.severity = warning # IDE0052: Remove unread private member dotnet_diagnostic.IDE0052.severity = warning + +# IDE0059: Unnecessary assignment to a value +dotnet_diagnostic.IDE0059.severity = warning From 58b2daba726a63a0e80a2c4b87588c92d7d9c0c4 Mon Sep 17 00:00:00 2001 From: dotnet-bot Date: Fri, 24 Apr 2020 16:29:14 -0700 Subject: [PATCH 142/222] Apply FixAll in solution for IDE0059 (C# projects) --- .../CSharpIsAndCastCheckDiagnosticAnalyzer.cs | 1 - .../UseConditionalExpressionForAssignmentHelpers.cs | 1 - .../CompletionProviders/OverrideCompletionProvider.cs | 1 - .../XmlDocCommentCompletionProvider.cs | 3 +-- ...ximityExpressionsService_ExpressionTermCollector.cs | 1 - ...ctor.CSharpCodeGenerator.ExpressionCodeGenerator.cs | 3 ++- .../Portable/GenerateType/CSharpGenerateTypeService.cs | 1 - .../Rename/CSharpRenameRewriterLanguageService.cs | 2 +- .../CSharpSimplificationService.Expander.cs | 10 ++-------- .../Portable/Rename/ConflictEngine/ConflictResolver.cs | 4 +--- .../Portable/Shared/Extensions/ISymbolExtensions.cs | 2 +- .../Shared/Extensions/SyntaxGeneratorExtensions.cs | 6 ++---- .../CodeStyle/EditorConfigCodeStyleParserTests.cs | 5 ----- .../EditorConfigNamingStyleParser_SymbolSpec.cs | 1 - 14 files changed, 10 insertions(+), 31 deletions(-) diff --git a/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs index 0821ef1774e0a..63df3ce2efc90 100644 --- a/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UsePatternMatching/CSharpIsAndCastCheckDiagnosticAnalyzer.cs @@ -155,7 +155,6 @@ public bool TryGetPatternPieces( out VariableDeclaratorSyntax declarator, out CastExpressionSyntax castExpression) { - ifStatement = null; localDeclarationStatement = null; declarator = null; castExpression = null; diff --git a/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/UseConditionalExpressionForAssignmentHelpers.cs b/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/UseConditionalExpressionForAssignmentHelpers.cs index 45ffe2bf6c3b7..46cc30e36ea78 100644 --- a/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/UseConditionalExpressionForAssignmentHelpers.cs +++ b/src/Analyzers/Core/Analyzers/UseConditionalExpression/ForAssignment/UseConditionalExpressionForAssignmentHelpers.cs @@ -20,7 +20,6 @@ public static bool TryMatchPattern( out ISimpleAssignmentOperation? trueAssignment, out ISimpleAssignmentOperation? falseAssignment) { - trueAssignment = null; falseAssignment = null; trueStatement = ifOperation.WhenTrue; diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/OverrideCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/OverrideCompletionProvider.cs index 02eaf20c7621f..d17a3f417a965 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/OverrideCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/OverrideCompletionProvider.cs @@ -172,7 +172,6 @@ public override bool TryDetermineModifiers(SyntaxToken startToken, SourceText te token = previousToken; } - startToken = token; modifiers = new DeclarationModifiers(isUnsafe: isUnsafe, isAbstract: isAbstract, isOverride: true, isSealed: isSealed); return overrideToken.IsKind(SyntaxKind.OverrideKeyword) && IsOnStartLine(overrideToken.Parent.SpanStart, text, startLine); } diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs index 5d2e3a6cc0225..758da0e40b58e 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/XmlDocCommentCompletionProvider.cs @@ -257,8 +257,7 @@ private bool IsAttributeNameContext(SyntaxToken token, int position, out string private bool IsAttributeValueContext(SyntaxToken token, out string tagName, out string attributeName) { - XmlAttributeSyntax attributeSyntax = null; - + XmlAttributeSyntax attributeSyntax; if (token.Parent.IsKind(SyntaxKind.IdentifierName) && token.Parent.IsParentKind(SyntaxKind.XmlNameAttribute, out XmlNameAttributeSyntax xmlName)) { diff --git a/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs b/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs index a0b61a5444ac4..51295eb7fbaa1 100644 --- a/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs +++ b/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs @@ -253,7 +253,6 @@ private static void AddInvocationExpressionTerms(InvocationExpressionSyntax invo { // Invocations definitely have side effects. So we assume this // is invalid initially; - expressionType = ExpressionType.Invalid; ExpressionType leftFlags = ExpressionType.Invalid, rightFlags = ExpressionType.Invalid; AddSubExpressionTerms(invocationExpression.Expression, terms, ref leftFlags); diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs index 99e0452cf78b3..11d9faa249cd5 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs @@ -95,12 +95,13 @@ protected override IEnumerable GetInitialStatementsForMethodDef { Contract.ThrowIfFalse(IsExtractMethodOnExpression(CSharpSelectionResult)); - ExpressionSyntax expression = null; // special case for array initializer var returnType = AnalyzerResult.ReturnType; var containingScope = CSharpSelectionResult.GetContainingScope(); + + ExpressionSyntax expression; if (returnType.TypeKind == TypeKind.Array && containingScope is InitializerExpressionSyntax) { var typeSyntax = returnType.GenerateTypeSyntax(); diff --git a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs index cb1a58abb8130..de8b28fc30842 100644 --- a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs +++ b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs @@ -871,7 +871,6 @@ internal override bool TryGenerateProperty( CancellationToken cancellationToken, out IPropertySymbol property) { - property = null; var propertyType = GetPropertyType(propertyName, semanticModel, typeInference, cancellationToken); if (propertyType == null || propertyType is IErrorTypeSymbol) { diff --git a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs index 8291d4c4d5ef7..e83231514763e 100644 --- a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs +++ b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs @@ -431,7 +431,7 @@ private RenameActionAnnotation GetAnnotationForInvocationExpression(InvocationEx if (identifierToken != default && !_annotatedIdentifierTokens.Contains(identifierToken)) { var symbolInfo = _semanticModel.GetSymbolInfo(invocationExpression, _cancellationToken); - IEnumerable symbols = null; + IEnumerable symbols; if (symbolInfo.Symbol == null) { return null; diff --git a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs index 10fb37b1ae780..2f8d78e4d6168 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs @@ -300,7 +300,7 @@ private static bool CanMakeNameExplicitInTuple(TupleExpressionSyntax tuple, stri var found = false; foreach (var argument in tuple.Arguments) { - string elementName = null; + string elementName; if (argument.NameColon != null) { elementName = argument.NameColon.Name.Identifier.ValueText; @@ -919,8 +919,6 @@ private ExpressionSyntax FullyQualifyIdentifierName( { ImmutableArray displayParts; - ExpressionSyntax left = null; - // we either need to create an AliasQualifiedName if the symbol is directly contained in the global namespace, // otherwise it a QualifiedName. if (!replaceNode && symbol.ContainingType == null && symbol.ContainingNamespace.IsGlobalNamespace) @@ -944,7 +942,7 @@ private ExpressionSyntax FullyQualifyIdentifierName( if (!omitLeftHandSide) { - left = SyntaxFactory.ParseTypeName(displayParts.ToDisplayString()); + ExpressionSyntax left = SyntaxFactory.ParseTypeName(displayParts.ToDisplayString()); // Replaces the '<' token with the '{' token since we are inside crefs left = TryReplaceAngleBracesWithCurlyBraces(left, isInsideCref); @@ -964,8 +962,6 @@ private ExpressionSyntax FullyQualifyIdentifierName( switch (parent.Kind()) { case SyntaxKind.QualifiedName: - var qualifiedParent = (QualifiedNameSyntax)parent; - result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.QualifiedName( (NameSyntax)left, @@ -974,8 +970,6 @@ private ExpressionSyntax FullyQualifyIdentifierName( break; case SyntaxKind.SimpleMemberAccessExpression: - var memberAccessParent = (MemberAccessExpressionSyntax)parent; - result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index 7240d31279d10..b6816b8917683 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -398,9 +398,7 @@ private static bool HeuristicMetadataNameEquivalenceCheck( { return true; } - - var index = 0; - index = newMetadataName.IndexOf(replacementText, 0); + var index = newMetadataName.IndexOf(replacementText, 0); var newMetadataNameBuilder = new StringBuilder(); // Every loop updates the newMetadataName to resemble the oldMetadataName diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs index 1b131e2512bdd..ca7cb84b8bbc6 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs @@ -210,11 +210,11 @@ private static bool IsBrowsingProhibitedByTypeLibAttributeWorker( { if (Equals(attribute.AttributeConstructor, constructor)) { - var actualFlags = 0; // Check for both constructor signatures. The constructor that takes a TypeLib*Flags reports an int argument. var argumentValue = attribute.ConstructorArguments.First().Value; + int actualFlags; if (argumentValue is int i) { actualFlags = i; diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs index 06c161948b724..4d1ee85cb9d86 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs @@ -278,10 +278,8 @@ public static async Task OverridePropertyAsync( { var getAccessibility = overriddenProperty.GetMethod.ComputeResultantAccessibility(containingType); var setAccessibility = overriddenProperty.SetMethod.ComputeResultantAccessibility(containingType); - - SyntaxNode getBody = null; - SyntaxNode setBody = null; - + SyntaxNode getBody; + SyntaxNode setBody; // Implement an abstract property by throwing not implemented in accessors. if (overriddenProperty.IsAbstract) { diff --git a/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs b/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs index bd5a54f943c3e..6b8185419a784 100644 --- a/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs +++ b/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs @@ -41,20 +41,15 @@ public class EditorConfigCodeStyleParserTests [InlineData("false : error", false, ReportDiagnostic.Error)] public void TestParseEditorConfigCodeStyleOption(string args, bool isEnabled, ReportDiagnostic severity) { - var notificationOption = NotificationOption.Silent; switch (severity) { case ReportDiagnostic.Hidden: - notificationOption = NotificationOption.Silent; break; case ReportDiagnostic.Info: - notificationOption = NotificationOption.Suggestion; break; case ReportDiagnostic.Warn: - notificationOption = NotificationOption.Warning; break; case ReportDiagnostic.Error: - notificationOption = NotificationOption.Error; break; } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/EditorConfig/EditorConfigNamingStyleParser_SymbolSpec.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/EditorConfig/EditorConfigNamingStyleParser_SymbolSpec.cs index 5e16d36db9fa4..066d0b6790234 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/EditorConfig/EditorConfigNamingStyleParser_SymbolSpec.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/NamingStyles/EditorConfig/EditorConfigNamingStyleParser_SymbolSpec.cs @@ -42,7 +42,6 @@ private static bool TryGetSymbolSpecNameForNamingRule( IReadOnlyDictionary conventionsDictionary, out string symbolSpecName) { - symbolSpecName = null; if (conventionsDictionary.TryGetValue($"dotnet_naming_rule.{namingRuleName}.symbols", out symbolSpecName)) { return symbolSpecName != null; From b26eccf8d9de9d37d28329e196405f683c328403 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 28 Apr 2020 08:33:09 -0700 Subject: [PATCH 143/222] Manual fixes for IDE0059 violations for assignments of a non-constant value (we do not offer code fixes to remove such assignments which could have side effects) --- .../CSharpRemoveUnreachableCodeDiagnosticAnalyzer.cs | 1 - .../CSharpUseDeconstructionDiagnosticAnalyzer.cs | 6 ++---- .../CSharpUseInferredMemberNameDiagnosticAnalyzer.cs | 1 - .../CSharpInlineDeclarationCodeFixProvider.cs | 1 - .../CSharpRemoveUnreachableCodeCodeFixProvider.cs | 2 -- .../AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs | 4 ++-- .../AbstractQualifyMemberAccessCodeFixProvider.cs | 6 +++--- .../UseExplicitTupleNameCodeFixProvider.cs | 1 - .../Core/Portable/InternalUtilities/ConcurrentSet.cs | 2 +- .../InternalUtilities/EnumerableExtensions.cs | 2 +- .../Portable/InternalUtilities/StreamExtensions.cs | 2 +- .../Portable/InternalUtilities/StringExtensions.cs | 2 +- .../InternalUtilities/WeakReferenceExtensions.cs | 2 +- .../GenerateType/GenerateTypeCodeFixProvider.cs | 4 ++-- ...CSharpMakeStatementAsynchronousCodeFixProvider.cs | 2 -- .../AbstractSyntacticSingleKeywordRecommender.cs | 1 - .../KeywordRecommenders/DynamicKeywordRecommender.cs | 1 - .../KeywordRecommenders/UsingKeywordRecommender.cs | 2 +- .../CSharpSuggestionModeCompletionProvider.cs | 2 -- ...oPropertyToFullPropertyCodeRefactoringProvider.cs | 2 +- ...mityExpressionsService_ExpressionTermCollector.cs | 3 +++ .../Portable/EditAndContinue/TopSyntaxComparer.cs | 4 ++-- ...or.CSharpCodeGenerator.ExpressionCodeGenerator.cs | 2 -- .../CSharpSelectionResult.StatementResult.cs | 2 +- .../GenerateType/CSharpGenerateTypeService.cs | 1 - .../MoveToNamespace/CSharpMoveToNamespaceService.cs | 2 +- .../ElementAccessExpressionSignatureHelpProvider.cs | 1 - .../GenericNameSignatureHelpProvider.cs | 2 +- .../CSharpUseAutoPropertyCodeFixProvider.cs | 2 -- .../Portable/CodeLens/CodeLensReferencesService.cs | 2 -- .../Completion/Providers/SymbolCompletionItem.cs | 2 -- .../Diagnostics/DiagnosticEventTaskScheduler.cs | 2 +- .../AbstractRegexDiagnosticAnalyzer.cs | 1 - .../AbstractFullyQualifyCodeFixProvider.cs | 2 +- .../GenerateConstructorHelpers.cs | 3 --- .../AbstractGenerateVariableService.State.cs | 2 +- .../AbstractGenerateTypeService.Editor.cs | 1 - .../AbstractGenerateTypeService.State.cs | 2 +- ...ractInitializeParameterCodeRefactoringProvider.cs | 4 +--- .../AddImport/VisualBasicAddImportFeatureService.vb | 2 +- .../CorrectNextControlVariableCodeFixProvider.vb | 2 +- .../VisualBasicConvertToIteratorCodeFixProvider.vb | 2 +- .../CodeLens/VisualBasicDisplayInfoService.vb | 2 +- .../VisualBasicEditAndContinueAnalyzer.vb | 3 +-- .../ExtractMethod/VisualBasicMethodExtractor.vb | 2 -- .../ExtractMethod/VisualBasicSelectionResult.vb | 2 +- .../GenerateType/VisualBasicGenerateTypeService.vb | 2 -- .../Portable/Classification/ClassificationHelpers.cs | 2 +- .../SyntaxClassification/NameSyntaxClassifier.cs | 6 +++--- .../CSharp/Portable/Classification/Worker.cs | 1 - .../Portable/CodeGeneration/ConversionGenerator.cs | 1 - .../Portable/CodeGeneration/ExpressionGenerator.cs | 2 +- .../CSharp/Portable/Editing/CSharpImportAdder.cs | 2 +- .../Portable/Indentation/CSharpIndentationService.cs | 1 - .../Rename/CSharpRenameRewriterLanguageService.cs | 4 ++-- .../CSharpSimplificationService.Expander.cs | 2 -- .../Simplification/Reducers/CSharpNameReducer.cs | 6 ++---- .../Simplifiers/AbstractCSharpSimplifier.cs | 2 +- .../Simplifiers/ExpressionSimplifier.cs | 2 +- .../CSharpTest/Formatting/FormattingTests.cs | 2 +- .../Core/MSBuild/MSBuild/MSBuildWorkspace.cs | 2 +- .../Core/MSBuild/MSBuild/ProjectFile/ProjectFile.cs | 1 - .../Core/Portable/CaseCorrection/CaseCorrector.cs | 1 - .../CodeCleanup/AbstractCodeCleanerService.cs | 2 +- .../FixAllOccurrences/BatchFixAllProvider.cs | 2 +- .../AbstractCodeGenerationService_FindDeclaration.cs | 2 +- .../Differencing/LongestCommonSubsequence.cs | 1 - src/Workspaces/Core/Portable/Differencing/Match.cs | 4 ++-- .../Portable/Execution/SerializerService_Asset.cs | 2 +- .../FindLiterals/FindLiteralsSearchEngine.cs | 4 ++-- .../Finders/AbstractReferenceFinder.cs | 1 - .../FindSymbols/SymbolTree/SymbolTreeInfo.cs | 1 - .../Rename/ConflictEngine/ConflictResolver.cs | 1 + .../Portable/Shared/Extensions/ISymbolExtensions.cs | 1 - .../Shared/Extensions/SyntaxGeneratorExtensions.cs | 3 ++- src/Workspaces/Core/Portable/Workspace/Workspace.cs | 4 +--- .../CodeStyle/EditorConfigCodeStyleParserTests.cs | 12 ------------ .../Differencing/LongestCommonSubsequenceTests.cs | 1 - ...tylePreferenceEditorConfigStorageLocationTests.cs | 4 ++-- .../CoreTest/SolutionTests/SolutionTests.cs | 12 ++++++------ src/Workspaces/CoreTest/SyntaxNodeTests.cs | 2 -- src/Workspaces/CoreTest/SyntaxPathTests.cs | 12 ++++++------ src/Workspaces/CoreTest/UtilityTest/BKTreeTests.cs | 1 - .../DesktopTest/CommandLineProjectTests.cs | 2 +- src/Workspaces/MSBuildTest/MSBuildWorkspaceTests.cs | 1 - src/Workspaces/MSBuildTest/WorkspaceTestBase.cs | 2 -- .../CSharp/Extensions/SyntaxNodeExtensions.cs | 2 +- .../CSharp/Extensions/SyntaxTreeExtensions.cs | 1 - .../CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs | 2 +- .../Simplification/Simplifiers/CastSimplifier.cs | 4 ++-- .../CSharp/Utilities/FormattingRangeHelper.cs | 2 +- .../OperatorPlacementWhenWrappingPreference.cs | 2 +- .../Extensions/ISymbolExtensions_Accessibility.cs | 9 ++++----- .../Core/Formatting/Engine/TokenStream.Changes.cs | 2 +- .../Compiler/Core/Formatting/FormattingExtensions.cs | 1 - .../Core/Services/SyntaxFacts/AbstractSyntaxFacts.cs | 4 ++-- .../Compiler/Core/Utilities/CancellableLazy`1.cs | 2 +- .../Core/Utilities/CommonFormattingHelpers.cs | 3 --- .../Compiler/Core/Utilities/WordSimilarityChecker.cs | 4 ++-- .../VisualBasic/Extensions/SyntaxNodeExtensions.vb | 2 -- .../Extensions/ContextQuery/CSharpSyntaxContext.cs | 2 +- .../CSharp/Extensions/SemanticModelExtensions.cs | 2 +- .../CSharp/Extensions/SyntaxTreeExtensions.cs | 4 ++-- .../CSharpTypeInferenceService.TypeInferrer.cs | 2 +- .../AddImports/AbstractAddImportsService.cs | 3 ++- .../VisualBasicRenameRewriterLanguageService.vb | 2 +- ...ctVisualBasicReducer.AbstractReductionRewriter.vb | 2 +- .../VisualBasicSimplificationService.Expander.vb | 4 +--- .../CodeGeneration/SyntaxGeneratorTests.vb | 2 -- .../Formatting/VisualBasicFormattingTestBase.vb | 1 - 110 files changed, 102 insertions(+), 179 deletions(-) diff --git a/src/Analyzers/CSharp/Analyzers/RemoveUnreachableCode/CSharpRemoveUnreachableCodeDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/RemoveUnreachableCode/CSharpRemoveUnreachableCodeDiagnosticAnalyzer.cs index 8cf994e1a9ea7..f83aa838cf356 100644 --- a/src/Analyzers/CSharp/Analyzers/RemoveUnreachableCode/CSharpRemoveUnreachableCodeDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/RemoveUnreachableCode/CSharpRemoveUnreachableCodeDiagnosticAnalyzer.cs @@ -40,7 +40,6 @@ private void AnalyzeSemanticModel(SemanticModelAnalysisContext context) { var fadeCode = context.GetOption(FadingOptions.FadeOutUnreachableCode, LanguageNames.CSharp); - var tree = context.SemanticModel.SyntaxTree; var semanticModel = context.SemanticModel; var cancellationToken = context.CancellationToken; diff --git a/src/Analyzers/CSharp/Analyzers/UseDeconstruction/CSharpUseDeconstructionDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseDeconstruction/CSharpUseDeconstructionDiagnosticAnalyzer.cs index 391a7e2d21d7e..b0aa81d5e8a62 100644 --- a/src/Analyzers/CSharp/Analyzers/UseDeconstruction/CSharpUseDeconstructionDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseDeconstruction/CSharpUseDeconstructionDiagnosticAnalyzer.cs @@ -63,7 +63,7 @@ private void AnalyzeVariableDeclaration( { if (!TryAnalyzeVariableDeclaration( context.SemanticModel, variableDeclaration, out _, - out var memberAccessExpressions, context.CancellationToken)) + out _, context.CancellationToken)) { return; } @@ -81,7 +81,7 @@ private void AnalyzeForEachStatement( { if (!TryAnalyzeForEachStatement( context.SemanticModel, forEachStatement, out _, - out var memberAccessExpressions, context.CancellationToken)) + out _, context.CancellationToken)) { return; } @@ -205,8 +205,6 @@ private static bool TryAnalyze( } } - var variableName = identifier.ValueText; - using var _ = ArrayBuilder.GetInstance(out var references); // If the user actually uses the tuple local for anything other than accessing diff --git a/src/Analyzers/CSharp/Analyzers/UseInferredMemberName/CSharpUseInferredMemberNameDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/UseInferredMemberName/CSharpUseInferredMemberNameDiagnosticAnalyzer.cs index db3fe5a075cb9..90bfeb02cad30 100644 --- a/src/Analyzers/CSharp/Analyzers/UseInferredMemberName/CSharpUseInferredMemberNameDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/UseInferredMemberName/CSharpUseInferredMemberNameDiagnosticAnalyzer.cs @@ -24,7 +24,6 @@ protected override void InitializeWorker(AnalysisContext context) protected override void LanguageSpecificAnalyzeSyntax(SyntaxNodeAnalysisContext context, SyntaxTree syntaxTree, AnalyzerOptions options, CancellationToken cancellationToken) { - var parseOptions = (CSharpParseOptions)syntaxTree.Options; switch (context.Node.Kind()) { case SyntaxKind.NameColon: diff --git a/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs index 456653f17e97d..7fcfc144841cc 100644 --- a/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs @@ -106,7 +106,6 @@ await editor.ApplyExpressionLevelSemanticEditsAsync( var declaratorLocation = diagnostic.AdditionalLocations[0]; var identifierLocation = diagnostic.AdditionalLocations[1]; var invocationOrCreationLocation = diagnostic.AdditionalLocations[2]; - var outArgumentContainingStatementLocation = diagnostic.AdditionalLocations[3]; var declarator = (VariableDeclaratorSyntax)declaratorLocation.FindNode(cancellationToken); var identifier = (IdentifierNameSyntax)identifierLocation.FindNode(cancellationToken); diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs index 4d5a6a082a39c..3535f335b797c 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnreachableCode/CSharpRemoveUnreachableCodeCodeFixProvider.cs @@ -73,8 +73,6 @@ protected override Task FixAllAsync( SyntaxEditor editor, CancellationToken cancellationToken) { - var syntaxRoot = editor.OriginalRoot; - foreach (var diagnostic in diagnostics) { var firstUnreachableStatementLocation = diagnostic.AdditionalLocations.Single(); diff --git a/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs b/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs index 48479de085b39..afb830bb92ce9 100644 --- a/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/RemoveUnusedMembers/AbstractRemoveUnusedMembersDiagnosticAnalyzer.cs @@ -542,8 +542,8 @@ private void AddDebuggerDisplayAttributeArguments(INamedTypeSymbol namedTypeSymb AddDebuggerDisplayAttributeArguments(nestedType, builder); break; - case IPropertySymbol property: - case IFieldSymbol field: + case IPropertySymbol _: + case IFieldSymbol _: AddDebuggerDisplayAttributeArgumentsCore(member, builder); break; } diff --git a/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs index 6f7014afe4680..7d74efecfb2b9 100644 --- a/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/QualifyMemberAccess/AbstractQualifyMemberAccessCodeFixProvider.cs @@ -35,12 +35,10 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } - protected override async Task FixAllAsync( + protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { - var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var generator = document.GetLanguageService(); foreach (var diagnostic in diagnostics) @@ -57,6 +55,8 @@ protected override async Task FixAllAsync( editor.ReplaceNode(node, qualifiedAccess); } } + + return Task.CompletedTask; } protected abstract TSimpleNameSyntax GetNode(Diagnostic diagnostic, CancellationToken cancellationToken); diff --git a/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs b/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs index 24054d51cd1a8..2ba6305927a47 100644 --- a/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs +++ b/src/Analyzers/Core/CodeFixes/UseExplicitTupleName/UseExplicitTupleNameCodeFixProvider.cs @@ -42,7 +42,6 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { - var root = editor.OriginalRoot; var generator = editor.Generator; foreach (var diagnostic in diagnostics) diff --git a/src/Compilers/Core/Portable/InternalUtilities/ConcurrentSet.cs b/src/Compilers/Core/Portable/InternalUtilities/ConcurrentSet.cs index bf23405bf7252..8c31b2448f729 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ConcurrentSet.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ConcurrentSet.cs @@ -105,7 +105,7 @@ public void AddRange(IEnumerable? values) /// true if the value was removed successfully; otherwise false. public bool Remove(T value) { - return _dictionary.TryRemove(value, out var b); + return _dictionary.TryRemove(value, out _); } /// diff --git a/src/Compilers/Core/Portable/InternalUtilities/EnumerableExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/EnumerableExtensions.cs index 13f6e7e017144..9d806a3e71b57 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/EnumerableExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/EnumerableExtensions.cs @@ -198,7 +198,7 @@ public static bool IsEmpty(this IEnumerable source) return str.Length == 0; } - foreach (var t in source) + foreach (var _ in source) { return false; } diff --git a/src/Compilers/Core/Portable/InternalUtilities/StreamExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/StreamExtensions.cs index 069c40f80551f..203f1b1fe136e 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/StreamExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/StreamExtensions.cs @@ -37,7 +37,7 @@ public static int TryReadAll( Debug.Assert(count > 0); int totalBytesRead; - int bytesRead = 0; + int bytesRead; for (totalBytesRead = 0; totalBytesRead < count; totalBytesRead += bytesRead) { // Note: Don't attempt to save state in-between calls to .Read as it would diff --git a/src/Compilers/Core/Portable/InternalUtilities/StringExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/StringExtensions.cs index 2900115035799..3c4fc10fa3377 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/StringExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/StringExtensions.cs @@ -211,7 +211,7 @@ internal static bool IsValidUnicodeString(this string str) /// internal static string Unquote(this string arg) { - return Unquote(arg, out var quoted); + return Unquote(arg, out _); } internal static string Unquote(this string arg, out bool quoted) diff --git a/src/Compilers/Core/Portable/InternalUtilities/WeakReferenceExtensions.cs b/src/Compilers/Core/Portable/InternalUtilities/WeakReferenceExtensions.cs index 5edda6e6a8d0e..e1dffcbac9aef 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/WeakReferenceExtensions.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/WeakReferenceExtensions.cs @@ -21,7 +21,7 @@ public static T GetTarget(this WeakReference reference) where T : class? public static bool IsNull(this WeakReference reference) where T : class? { - return !reference.TryGetTarget(out var target); + return !reference.TryGetTarget(out _); } } } diff --git a/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs index c90cb067ddb5b..113fde89cd4cd 100644 --- a/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/GenerateType/GenerateTypeCodeFixProvider.cs @@ -48,11 +48,11 @@ protected override bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnost { switch (node) { - case QualifiedNameSyntax qualified: + case QualifiedNameSyntax _: return true; case SimpleNameSyntax simple: return !simple.IsParentKind(SyntaxKind.QualifiedName); - case MemberAccessExpressionSyntax memberAccess: + case MemberAccessExpressionSyntax _: return true; } diff --git a/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs index fe81d3570c267..7e27247515a60 100644 --- a/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/MakeStatementAsynchronous/CSharpMakeStatementAsynchronousCodeFixProvider.cs @@ -55,8 +55,6 @@ protected override Task FixAllAsync( Document document, ImmutableArray diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { - var root = editor.OriginalRoot; - foreach (var diagnostic in diagnostics) { var node = diagnostic.Location.FindNode(getInnermostNodeForTie: true, cancellationToken); diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractSyntacticSingleKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractSyntacticSingleKeywordRecommender.cs index eaa3226b07d1a..4c88fc8c518e6 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractSyntacticSingleKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/AbstractSyntacticSingleKeywordRecommender.cs @@ -58,7 +58,6 @@ public async Task> RecommendKeywordsAsync( { // NOTE: The collector ensures that we're not in "NonUserCode" like comments, strings, inactive code // for perf reasons. - var syntaxTree = context.SemanticModel.SyntaxTree; if (!_isValidInPreprocessorContext && context.IsPreProcessorDirectiveContext) { diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs index de0de9bb1a9d4..62e20da2ca7a2 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/DynamicKeywordRecommender.cs @@ -17,7 +17,6 @@ internal class DynamicKeywordRecommender : IKeywordRecommender GetSuggestionModeItemAsync( { if (trigger.Kind != CompletionTriggerKind.Snippets) { - var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = tree .FindTokenOnLeftOfPosition(position, cancellationToken) diff --git a/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs index 3fa9f051c0365..a477c1ffcc7c5 100644 --- a/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertAutoPropertyToFullProperty/CSharpConvertAutoPropertyToFullPropertyCodeRefactoringProvider.cs @@ -86,7 +86,7 @@ private SyntaxNode GetUpdatedAccessor(DocumentOptionSet options, if (!accessorDeclarationSyntax.Body.TryConvertToArrowExpressionBody( accessorDeclarationSyntax.Kind(), accessor.SyntaxTree.Options, preference, - out var arrowExpression, out var semicolonToken)) + out var arrowExpression, out _)) { return accessorDeclarationSyntax.WithSemicolonToken(default); }; diff --git a/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs b/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs index 51295eb7fbaa1..1572d4eaa74e9 100644 --- a/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs +++ b/src/Features/CSharp/Portable/Debugging/CSharpProximityExpressionsService_ExpressionTermCollector.cs @@ -251,8 +251,11 @@ private static void AddArrayCreationExpressionTerms( private static void AddInvocationExpressionTerms(InvocationExpressionSyntax invocationExpression, IList terms, ref ExpressionType expressionType) { +#pragma warning disable IDE0059 // Unnecessary assignment of a value // Invocations definitely have side effects. So we assume this // is invalid initially; + expressionType = ExpressionType.Invalid; +#pragma warning restore IDE0059 // Unnecessary assignment of a value ExpressionType leftFlags = ExpressionType.Invalid, rightFlags = ExpressionType.Invalid; AddSubExpressionTerms(invocationExpression.Expression, terms, ref leftFlags); diff --git a/src/Features/CSharp/Portable/EditAndContinue/TopSyntaxComparer.cs b/src/Features/CSharp/Portable/EditAndContinue/TopSyntaxComparer.cs index 11957bd0f0d1d..65005e0471fe5 100644 --- a/src/Features/CSharp/Portable/EditAndContinue/TopSyntaxComparer.cs +++ b/src/Features/CSharp/Portable/EditAndContinue/TopSyntaxComparer.cs @@ -306,11 +306,11 @@ protected internal override int GetLabel(SyntaxNode node) => (int)GetLabel(node.Kind()); internal static Label GetLabel(SyntaxKind kind) - => Classify(kind, out var isLeaf); + => Classify(kind, out _); // internal for testing internal static bool HasLabel(SyntaxKind kind) - => Classify(kind, out var isLeaf) != Label.Ignored; + => Classify(kind, out _) != Label.Ignored; protected internal override int LabelCount { diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs index 11d9faa249cd5..d5f29f2cf9768 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.ExpressionCodeGenerator.cs @@ -95,12 +95,10 @@ protected override IEnumerable GetInitialStatementsForMethodDef { Contract.ThrowIfFalse(IsExtractMethodOnExpression(CSharpSelectionResult)); - // special case for array initializer var returnType = AnalyzerResult.ReturnType; var containingScope = CSharpSelectionResult.GetContainingScope(); - ExpressionSyntax expression; if (returnType.TypeKind == TypeKind.Array && containingScope is InitializerExpressionSyntax) { diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs index 7f0416d1ac0ce..bd795a1307f51 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpSelectionResult.StatementResult.cs @@ -35,7 +35,7 @@ public override bool ContainingScopeHasAsyncKeyword() return node switch { - AccessorDeclarationSyntax access => false, + AccessorDeclarationSyntax _ => false, MethodDeclarationSyntax method => method.Modifiers.Any(SyntaxKind.AsyncKeyword), ParenthesizedLambdaExpressionSyntax lambda => lambda.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword, SimpleLambdaExpressionSyntax lambda => lambda.AsyncKeyword.Kind() == SyntaxKind.AsyncKeyword, diff --git a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs index de8b28fc30842..77d10f2bd0bf6 100644 --- a/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs +++ b/src/Features/CSharp/Portable/GenerateType/CSharpGenerateTypeService.cs @@ -122,7 +122,6 @@ expression.Parent is BaseTypeSyntax baseType && protected override bool TryGetNameParts(ExpressionSyntax expression, out IList nameParts) { - nameParts = new List(); return expression.TryGetNameParts(out nameParts); } diff --git a/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs b/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs index ff38becf339e1..f76ac49398170 100644 --- a/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs +++ b/src/Features/CSharp/Portable/MoveToNamespace/CSharpMoveToNamespaceService.cs @@ -27,7 +27,7 @@ protected override string GetNamespaceName(SyntaxNode container) => container switch { NamespaceDeclarationSyntax namespaceSyntax => namespaceSyntax.Name.ToString(), - CompilationUnitSyntax compilationUnit => string.Empty, + CompilationUnitSyntax _ => string.Empty, _ => throw ExceptionUtilities.UnexpectedValue(container) }; diff --git a/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs index 03e14273acc84..614dad3df1aa2 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs @@ -155,7 +155,6 @@ public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int if (expression.Parent is ConditionalAccessExpressionSyntax) { // The typed code looks like: ?[ - var conditional = (ConditionalAccessExpressionSyntax)expression.Parent; var elementBinding = SyntaxFactory.ElementBindingExpression(newBracketedArgumentList); var conditionalAccessExpression = SyntaxFactory.ConditionalAccessExpression(expression, elementBinding); offset = expression.SpanStart - conditionalAccessExpression.SpanStart; diff --git a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs index e1739147e046e..90601df6c5213 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs @@ -138,7 +138,7 @@ protected override async Task GetItemsWorkerAsync(Document d public override SignatureHelpState GetCurrentArgumentState(SyntaxNode root, int position, ISyntaxFactsService syntaxFacts, TextSpan currentSpan, CancellationToken cancellationToken) { if (!TryGetGenericIdentifier(root, position, syntaxFacts, SignatureHelpTriggerReason.InvokeSignatureHelpCommand, cancellationToken, - out var genericIdentifier, out var lessThanToken)) + out var genericIdentifier, out _)) { return null; } diff --git a/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs b/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs index 00117bf993414..c8fb36b644d7c 100644 --- a/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/UseAutoProperty/CSharpUseAutoPropertyCodeFixProvider.cs @@ -39,8 +39,6 @@ protected override async Task UpdatePropertyAsync( PropertyDeclarationSyntax propertyDeclaration, bool isWrittenOutsideOfConstructor, CancellationToken cancellationToken) { var project = propertyDocument.Project; - var sourceText = await propertyDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); - var trailingTrivia = propertyDeclaration.GetTrailingTrivia(); var updatedProperty = propertyDeclaration.WithAccessorList(UpdateAccessorList(propertyDeclaration.AccessorList)) diff --git a/src/Features/Core/Portable/CodeLens/CodeLensReferencesService.cs b/src/Features/Core/Portable/CodeLens/CodeLensReferencesService.cs index 1294db9846063..50ce17b5f9451 100644 --- a/src/Features/Core/Portable/CodeLens/CodeLensReferencesService.cs +++ b/src/Features/Core/Portable/CodeLens/CodeLensReferencesService.cs @@ -33,8 +33,6 @@ private static async Task FindAsync(Solution solution, DocumentId document return null; } - var cacheService = solution.Services.CacheService; - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/Features/Core/Portable/Completion/Providers/SymbolCompletionItem.cs b/src/Features/Core/Portable/Completion/Providers/SymbolCompletionItem.cs index 62378d3d921c8..76d956b953249 100644 --- a/src/Features/Core/Portable/Completion/Providers/SymbolCompletionItem.cs +++ b/src/Features/Core/Portable/Completion/Providers/SymbolCompletionItem.cs @@ -323,8 +323,6 @@ public static async Task GetDescriptionAsync( var position = GetDescriptionPosition(item); var supportedPlatforms = GetSupportedPlatforms(item, workspace); - var contextDocument = FindAppropriateDocumentForDescriptionContext(document, supportedPlatforms); - if (symbols.Length != 0) { return await CommonCompletionUtilities.CreateDescriptionAsync(workspace, semanticModel, position, symbols, supportedPlatforms, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticEventTaskScheduler.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticEventTaskScheduler.cs index 3d89dd172b09c..a3fec422461c6 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticEventTaskScheduler.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticEventTaskScheduler.cs @@ -35,7 +35,7 @@ private void Start() while (true) { var task = _tasks.Take(); - var ret = TryExecuteTask(task); + _ = TryExecuteTask(task); } } diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/AbstractRegexDiagnosticAnalyzer.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/AbstractRegexDiagnosticAnalyzer.cs index f32928764bac9..434ef76dddebc 100644 --- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/AbstractRegexDiagnosticAnalyzer.cs +++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/AbstractRegexDiagnosticAnalyzer.cs @@ -42,7 +42,6 @@ public void Analyze(SemanticModelAnalysisContext context) var syntaxTree = semanticModel.SyntaxTree; var cancellationToken = context.CancellationToken; - var options = context.Options; var option = context.GetOption(RegularExpressionsOptions.ReportInvalidRegexPatterns, syntaxTree.Options.Language); if (!option) { diff --git a/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs b/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs index b637e83c6b466..23ee66f77861b 100644 --- a/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs +++ b/src/Features/Core/Portable/FullyQualify/AbstractFullyQualifyCodeFixProvider.cs @@ -128,7 +128,7 @@ private IEnumerable CreateActions( private static string GetNodeName(Document document, SyntaxNode node) { var syntaxFacts = document.GetLanguageService(); - syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out var arity); + syntaxFacts.GetNameAndArityOfSimpleName(node, out var name, out _); return name; } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/GenerateConstructorHelpers.cs b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/GenerateConstructorHelpers.cs index ea93c1e7489e5..7a5f83a2c097a 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/GenerateConstructorHelpers.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/GenerateConstructorHelpers.cs @@ -4,8 +4,6 @@ using System.Collections.Generic; using System.Linq; -using Microsoft.CodeAnalysis.LanguageServices; -using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.GenerateMember.GenerateConstructor { @@ -64,7 +62,6 @@ private static bool ParameterTypesMatch(SemanticDocument semanticDocument, IList } var compilation = semanticDocument.SemanticModel.Compilation; - var semanticFactsService = semanticDocument.Document.GetLanguageService(); for (var i = 0; i < parameterTypes.Count; i++) { diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs index d86fefe210e21..c39140cbd5b01 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs @@ -338,7 +338,7 @@ private ISymbol TryGetAssignedSymbol( if (syntaxFacts.IsSimpleAssignmentStatement(siblingNode)) { syntaxFacts.GetPartsOfAssignmentStatement( - siblingNode, out var left, out var right); + siblingNode, out var left, out _); var symbol = semanticDocument.SemanticModel.GetSymbolInfo(left, cancellationToken).Symbol; if (symbol?.Kind == symbolKind && diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs index 6be5aa95805be..54812da289f96 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs @@ -537,7 +537,6 @@ private async Task> GetGenerateIntoExistingDocu private async Task> GetGenerateIntoTypeOperationsAsync(INamedTypeSymbol namedType) { - var codeGenService = GetCodeGenerationService(); var solution = _semanticDocument.Project.Solution; var codeGenResult = await CodeGenerator.AddNamedTypeDeclarationAsync( solution, diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.State.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.State.cs index 1e244d611345b..16cba8ae1b5c1 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.State.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.State.cs @@ -93,7 +93,7 @@ private async Task TryInitializeAsync( SimpleName = (TSimpleNameSyntax)node; var syntaxFacts = semanticDocument.Document.GetLanguageService(); - syntaxFacts.GetNameAndArityOfSimpleName(SimpleName, out var name, out var arity); + syntaxFacts.GetNameAndArityOfSimpleName(SimpleName, out var name, out _); Name = name; NameIsVerbatim = syntaxFacts.IsVerbatimIdentifier(SimpleName.GetFirstToken()); diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs index b50dea97c9cbb..6ee96ae53b6c1 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeParameterCodeRefactoringProvider.cs @@ -88,8 +88,6 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetRequiredLanguageService(); - var parameterDefault = syntaxFacts.GetDefaultOfParameter(selectedParameter); - // we can't just call GetDeclaredSymbol on functionDeclaration because it could an anonymous function, // so first we have to get the parameter symbol and then its containing method symbol if (!TryGetParameterSymbol(selectedParameter, semanticModel, out var parameter, cancellationToken)) @@ -235,7 +233,7 @@ protected static bool IsFieldOrPropertyAssignment( } protected static bool IsFieldOrPropertyReference(IOperation operation, INamedTypeSymbol containingType) - => IsFieldOrPropertyAssignment(operation, containingType, out var fieldOrProperty); + => IsFieldOrPropertyAssignment(operation, containingType, out _); protected static bool IsFieldOrPropertyReference( IOperation? operation, INamedTypeSymbol containingType, diff --git a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb index fcd0db360cd2b..22b33cb8428f1 100644 --- a/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb +++ b/src/Features/VisualBasic/Portable/AddImport/VisualBasicAddImportFeatureService.vb @@ -321,7 +321,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddImport semanticModel As SemanticModel, syntaxFacts As ISyntaxFacts, cancellationToken As CancellationToken) As Boolean - Dim leftExpressionType As ITypeSymbol = Nothing + Dim leftExpressionType As ITypeSymbol If syntaxFacts.IsInvocationExpression(expression) Then leftExpressionType = semanticModel.GetEnclosingNamedType(expression.SpanStart, cancellationToken) Else diff --git a/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb index 671c41141a83a..e1caa592e0eba 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/CorrectNextControlVariable/CorrectNextControlVariableCodeFixProvider.vb @@ -87,7 +87,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.CorrectNextControlVariabl ' A ForBlockSyntax can either be a ForBlock or a ForEachBlock. Get the control variable ' from that. - Dim controlVariable As SyntaxNode = Nothing + Dim controlVariable As SyntaxNode Select Case forBlock.Kind() Case SyntaxKind.ForBlock Dim forStatement = DirectCast(forBlock.ForOrForEachStatement, ForStatementSyntax) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb index 7829fa5081e13..b08cd72878277 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Iterator/VisualBasicConvertToIteratorCodeFixProvider.vb @@ -111,7 +111,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Iterator Private Shared Function AddIteratorKeywordToMethod(root As SyntaxNode, methodStatementNode As MethodStatementSyntax) As SyntaxNode ' Add iterator keyword Dim iteratorToken As SyntaxToken = Token(SyntaxKind.IteratorKeyword).WithAdditionalAnnotations(Formatter.Annotation) - Dim newFunctionNode As MethodStatementSyntax = Nothing + Dim newFunctionNode As MethodStatementSyntax ' If the iterator keyword is going to be added to the front of the method declaration, ' we will need to move the trivia from the method onto the keyword. diff --git a/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb b/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb index 3c6bcde2345a1..0303c1e4b4ba4 100644 --- a/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb +++ b/src/Features/VisualBasic/Portable/CodeLens/VisualBasicDisplayInfoService.vb @@ -122,7 +122,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeLens End If Dim symbol As ISymbol = semanticModel.GetDeclaredSymbol(node) - Dim symbolName As String = Nothing + Dim symbolName As String Select Case node.Kind() Case SyntaxKind.GetAccessorBlock, diff --git a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb index 84f2773d41b42..2851670d56e1e 100644 --- a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb +++ b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb @@ -2049,7 +2049,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue End If For Each member In type.Members - Dim modifiers As SyntaxTokenList = Nothing + Dim modifiers As SyntaxTokenList Select Case member.Kind Case SyntaxKind.DeclareFunctionStatement, @@ -2893,7 +2893,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue Protected Overrides Function GetExceptionHandlingAncestors(node As SyntaxNode, isNonLeaf As Boolean) As List(Of SyntaxNode) Dim result = New List(Of SyntaxNode)() - Dim initialNode = node While node IsNot Nothing Dim kind = node.Kind diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.vb index a7cfe64082798..f1491179c4aa0 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.vb @@ -98,8 +98,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Dim binding = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False) For Each typeParameter In TypeParameterCollector.Collect(type) - Dim vbType = DirectCast(typeParameter, ITypeSymbol) - Dim typeName = SyntaxFactory.ParseTypeName(typeParameter.Name) Dim symbolInfo = binding.GetSpeculativeSymbolInfo(contextNode.SpanStart, typeName, SpeculativeBindingOption.BindAsTypeOrNamespace) Dim currentType = TryCast(symbolInfo.Symbol, ITypeSymbol) diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb index c337de3ebf2c2..810606c7e81b6 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionResult.vb @@ -139,7 +139,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod End If End If - Dim expression As ExpressionSyntax = Nothing + Dim expression As ExpressionSyntax If TypeOf node Is CollectionInitializerSyntax Then expression = node.GetUnparenthesizedExpression() Return semanticModel.GetTypeInfo(expression).ConvertedType diff --git a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb index 6bf27eb26c23f..f837349c47de5 100644 --- a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb +++ b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb @@ -711,8 +711,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateType typeInferenceService As ITypeInferenceService, cancellationToken As CancellationToken, ByRef propertySymbol As IPropertySymbol) As Boolean - propertySymbol = Nothing - Dim typeSymbol = GetPropertyType(propertyName, semanticModel, typeInferenceService, cancellationToken) If typeSymbol Is Nothing OrElse TypeOf typeSymbol Is IErrorTypeSymbol Then propertySymbol = GenerateProperty(propertyName, semanticModel.Compilation.ObjectType) diff --git a/src/Workspaces/CSharp/Portable/Classification/ClassificationHelpers.cs b/src/Workspaces/CSharp/Portable/Classification/ClassificationHelpers.cs index fbd0752e8ab9f..a26b5ab55d621 100644 --- a/src/Workspaces/CSharp/Portable/Classification/ClassificationHelpers.cs +++ b/src/Workspaces/CSharp/Portable/Classification/ClassificationHelpers.cs @@ -239,7 +239,7 @@ private static bool IsVerbatimStringToken(SyntaxToken token) { FieldDeclarationSyntax fieldDeclaration => fieldDeclaration.Modifiers.Any(SyntaxKind.ConstKeyword) ? ClassificationTypeNames.ConstantName : ClassificationTypeNames.FieldName, LocalDeclarationStatementSyntax localDeclarationStatement => localDeclarationStatement.IsConst ? ClassificationTypeNames.ConstantName : ClassificationTypeNames.LocalName, - EventFieldDeclarationSyntax aventFieldDeclarationSyntax => ClassificationTypeNames.EventName, + EventFieldDeclarationSyntax _ => ClassificationTypeNames.EventName, _ => ClassificationTypeNames.LocalName, }; } diff --git a/src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.cs b/src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.cs index 7a947860a0d68..3125f308c26d6 100644 --- a/src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.cs +++ b/src/Workspaces/CSharp/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.cs @@ -214,11 +214,11 @@ private bool TryClassifySymbol( token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForMethod(methodSymbol)); return true; - case IPropertySymbol propertySymbol: + case IPropertySymbol _: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.PropertyName); return true; - case IEventSymbol eventSymbol: + case IEventSymbol _: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.EventName); return true; @@ -235,7 +235,7 @@ private bool TryClassifySymbol( token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForLocal(localSymbol)); return true; - case ILabelSymbol labelSymbol: + case ILabelSymbol _: token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.LabelName); return true; diff --git a/src/Workspaces/CSharp/Portable/Classification/Worker.cs b/src/Workspaces/CSharp/Portable/Classification/Worker.cs index 0b8cc14b98511..16e2d2071f848 100644 --- a/src/Workspaces/CSharp/Portable/Classification/Worker.cs +++ b/src/Workspaces/CSharp/Portable/Classification/Worker.cs @@ -124,7 +124,6 @@ private void ClassifyTriviaList(SyntaxTriviaList list) // comments out a file). Try to skip as many as possible if they're not actually in the span // we care about classifying. var classificationSpanStart = _textSpan.Start; - var classificationSpanEnd = _textSpan.End; // First, skip all the trivia before the span we care about. var enumerator = list.GetEnumerator(); diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs index 1ad9e93bc16a5..861aabc0233a7 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs @@ -58,7 +58,6 @@ private static ConversionOperatorDeclarationSyntax GenerateConversionDeclaration return reusableSyntax; } - var operatorToken = SyntaxFactory.Token(SyntaxFacts.GetOperatorKind(method.MetadataName)); var keyword = method.MetadataName == WellKnownMemberNames.ImplicitConversionName ? SyntaxFactory.Token(SyntaxKind.ImplicitKeyword) : SyntaxFactory.Token(SyntaxKind.ExplicitKeyword); diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/ExpressionGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/ExpressionGenerator.cs index e2abab75cd89b..9e71b71c9a952 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/ExpressionGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/ExpressionGenerator.cs @@ -118,7 +118,7 @@ private static ExpressionSyntax GenerateCharLiteralExpression(char val) private static string DetermineSuffix(ITypeSymbol type, object value) { - if (value is float f) + if (value is float) { var stringValue = ((IFormattable)value).ToString("R", CultureInfo.InvariantCulture); diff --git a/src/Workspaces/CSharp/Portable/Editing/CSharpImportAdder.cs b/src/Workspaces/CSharp/Portable/Editing/CSharpImportAdder.cs index 7c4c37ab1e0f1..552e6b9fa1c77 100644 --- a/src/Workspaces/CSharp/Portable/Editing/CSharpImportAdder.cs +++ b/src/Workspaces/CSharp/Portable/Editing/CSharpImportAdder.cs @@ -53,7 +53,7 @@ protected override SyntaxNode MakeSafeToAddNamespaces(SyntaxNode root, IEnumerab // name must refer to something that is not a namespace, but be qualified with a namespace. var symbol = model.GetSymbolInfo(fullName).Symbol; - if (symbol != null && symbol.Kind != SymbolKind.Namespace && model.GetSymbolInfo(namespacePart).Symbol is INamespaceSymbol nsSymbol) + if (symbol != null && symbol.Kind != SymbolKind.Namespace && model.GetSymbolInfo(namespacePart).Symbol is INamespaceSymbol) { // use the symbols containing namespace, and not the potentially less than fully qualified namespace in the full name expression. var ns = symbol.ContainingNamespace; diff --git a/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.cs b/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.cs index f465680bd8ac5..92713de50e47a 100644 --- a/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.cs +++ b/src/Workspaces/CSharp/Portable/Indentation/CSharpIndentationService.cs @@ -190,7 +190,6 @@ private void ReplaceCaseIndentationRules(List list, Syntax private static void AddIndentBlockOperations(List list, SyntaxNode node) { // only add indent block operation if the base token is the first token on line - var text = node.SyntaxTree.GetText(); var baseToken = node.Parent.GetFirstToken(includeZeroWidth: true); list.Add(FormattingOperations.CreateRelativeIndentBlockOperation( diff --git a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs index e83231514763e..41b15b10d60ae 100644 --- a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs +++ b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs @@ -574,8 +574,8 @@ private SyntaxToken RenameToken(SyntaxToken oldToken, SyntaxToken newToken, stri // if it's an attribute name we don't mess with the escaping because it might change overload resolution newToken = _isVerbatim || (isAttributeName && oldToken.IsVerbatimIdentifier()) - ? newToken = newToken.CopyAnnotationsTo(SyntaxFactory.VerbatimIdentifier(newToken.LeadingTrivia, currentNewIdentifier, valueText, newToken.TrailingTrivia)) - : newToken = newToken.CopyAnnotationsTo(SyntaxFactory.Identifier(newToken.LeadingTrivia, SyntaxKind.IdentifierToken, currentNewIdentifier, valueText, newToken.TrailingTrivia)); + ? newToken.CopyAnnotationsTo(SyntaxFactory.VerbatimIdentifier(newToken.LeadingTrivia, currentNewIdentifier, valueText, newToken.TrailingTrivia)) + : newToken.CopyAnnotationsTo(SyntaxFactory.Identifier(newToken.LeadingTrivia, SyntaxKind.IdentifierToken, currentNewIdentifier, valueText, newToken.TrailingTrivia)); if (_replacementTextValid) { diff --git a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs index 2f8d78e4d6168..637413f704b33 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.Expander.cs @@ -435,8 +435,6 @@ public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) { _cancellationToken.ThrowIfCancellationRequested(); - var identifier = node.Identifier; - var newNode = (SimpleNameSyntax)base.VisitIdentifierName(node); return VisitSimpleName(newNode, node); diff --git a/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpNameReducer.cs b/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpNameReducer.cs index 1b30eb2984950..9d6a4768d8659 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpNameReducer.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpNameReducer.cs @@ -11,7 +11,6 @@ using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Simplification; -using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp.Simplification { @@ -33,13 +32,12 @@ private static SyntaxNode SimplifyName( CancellationToken cancellationToken) { SyntaxNode replacementNode; - TextSpan issueSpan; if (node.IsKind(SyntaxKind.QualifiedCref, out QualifiedCrefSyntax crefSyntax)) { if (!QualifiedCrefSimplifier.Instance.TrySimplify( crefSyntax, semanticModel, optionSet, - out var crefReplacement, out issueSpan, cancellationToken)) + out var crefReplacement, out _, cancellationToken)) { return node; } @@ -49,7 +47,7 @@ private static SyntaxNode SimplifyName( else { var expressionSyntax = (ExpressionSyntax)node; - if (!ExpressionSimplifier.Instance.TrySimplify(expressionSyntax, semanticModel, optionSet, out var expressionReplacement, out issueSpan, cancellationToken)) + if (!ExpressionSimplifier.Instance.TrySimplify(expressionSyntax, semanticModel, optionSet, out var expressionReplacement, out _, cancellationToken)) { return node; } diff --git a/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/AbstractCSharpSimplifier.cs b/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/AbstractCSharpSimplifier.cs index 0e427bbcce994..297916a962982 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/AbstractCSharpSimplifier.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/AbstractCSharpSimplifier.cs @@ -258,7 +258,7 @@ private static bool ValidateAliasForTarget(IAliasSymbol aliasReplacement, Semant if (boundSymbols.Length == 1) { - if (boundSymbols[0] is IAliasSymbol boundAlias && aliasReplacement.Target.Equals(symbol)) + if (boundSymbols[0] is IAliasSymbol && aliasReplacement.Target.Equals(symbol)) { return true; } diff --git a/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/ExpressionSimplifier.cs b/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/ExpressionSimplifier.cs index fa63bf1c7da6c..f24802e0e7fa5 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/ExpressionSimplifier.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/Simplifiers/ExpressionSimplifier.cs @@ -456,7 +456,7 @@ private static bool TrySimplifyMemberAccessOrQualifiedName( if (containingType != null && !containingType.Equals(leftSymbol)) { - if (leftSymbol is INamedTypeSymbol namedType && + if (leftSymbol is INamedTypeSymbol && containingType.TypeArguments.Length != 0) { return false; diff --git a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs index 48b7350ee1c62..35d2a4912816d 100644 --- a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs +++ b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs @@ -6523,7 +6523,7 @@ group t by t.Item1 into cat } } "; - await AssertFormatAsync(expected, code); + await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); } [Fact] diff --git a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs index b50be4c1f5df0..846ece975daae 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/MSBuildWorkspace.cs @@ -398,7 +398,7 @@ protected override void ApplyDocumentAdded(DocumentInfo info, SourceText text) Debug.Assert(_applyChangesProjectFile != null); var project = this.CurrentSolution.GetProject(info.Id.ProjectId); - if (_projectFileLoaderRegistry.TryGetLoaderFromProjectPath(project.FilePath, out var loader)) + if (_projectFileLoaderRegistry.TryGetLoaderFromProjectPath(project.FilePath, out _)) { var extension = _applyChangesProjectFile.GetDocumentExtension(info.SourceCodeKind); var fileName = Path.ChangeExtension(info.Name, extension); diff --git a/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/ProjectFile.cs b/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/ProjectFile.cs index 4a7341221b550..727c959c911c5 100644 --- a/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/ProjectFile.cs +++ b/src/Workspaces/Core/MSBuild/MSBuild/ProjectFile/ProjectFile.cs @@ -444,7 +444,6 @@ public void AddProjectReference(string projectName, ProjectFileReference referen public void RemoveProjectReference(string projectName, string projectFilePath) { - var relativePath = PathUtilities.GetRelativePath(_loadedProject.DirectoryPath, projectFilePath); var item = FindProjectReferenceItem(projectName, projectFilePath); if (item != null) { diff --git a/src/Workspaces/Core/Portable/CaseCorrection/CaseCorrector.cs b/src/Workspaces/Core/Portable/CaseCorrection/CaseCorrector.cs index b16ea12d297a9..b3897b2dbfe42 100644 --- a/src/Workspaces/Core/Portable/CaseCorrection/CaseCorrector.cs +++ b/src/Workspaces/Core/Portable/CaseCorrection/CaseCorrector.cs @@ -54,7 +54,6 @@ public static async Task CaseCorrectAsync(Document document, SyntaxAnn /// public static async Task CaseCorrectAsync(Document document, TextSpan span, CancellationToken cancellationToken = default) { - var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); return await CaseCorrectAsync(document, ImmutableArray.Create(span), cancellationToken).ConfigureAwait(false); } diff --git a/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs b/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs index c6d489dd76b32..948f776e203dc 100644 --- a/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs +++ b/src/Workspaces/Core/Portable/CodeCleanup/AbstractCodeCleanerService.cs @@ -333,7 +333,7 @@ private ImmutableArray GetNonOverlappingSpans(ISyntaxFactsService synt foreach (var span in spans) { cancellationToken.ThrowIfCancellationRequested(); - var spanAlignedToTokens = GetSpanAlignedToTokens(syntaxFactsService, root, span, out var startToken, out var endToken); + _ = GetSpanAlignedToTokens(syntaxFactsService, root, span, out var startToken, out var endToken); var previousToken = startToken.GetPreviousToken(includeZeroWidth: true, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true); var nextToken = endToken.GetNextToken(includeZeroWidth: true, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true); diff --git a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs index e95058996a792..123c9f599f341 100644 --- a/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs +++ b/src/Workspaces/Core/Portable/CodeFixes/FixAllOccurrences/BatchFixAllProvider.cs @@ -269,7 +269,7 @@ public virtual async Task TryMergeFixesAsync( // For each changed document, also keep track of the associated code action that // produced it. var getChangedDocumentsTasks = new List(); - foreach (var (diagnostic, action) in diagnosticsAndCodeActions) + foreach (var (_, action) in diagnosticsAndCodeActions) { getChangedDocumentsTasks.Add(GetChangedDocumentsAsync( oldSolution, documentIdToChangedDocuments, diff --git a/src/Workspaces/Core/Portable/CodeGeneration/AbstractCodeGenerationService_FindDeclaration.cs b/src/Workspaces/Core/Portable/CodeGeneration/AbstractCodeGenerationService_FindDeclaration.cs index 1bf6effa57984..ced4672b5c96b 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/AbstractCodeGenerationService_FindDeclaration.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/AbstractCodeGenerationService_FindDeclaration.cs @@ -52,7 +52,7 @@ protected static TextSpan GetSpan(SyntaxNode node) } public bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToken cancellationToken) - => CanAddTo(destination, solution, cancellationToken, out var availableIndices); + => CanAddTo(destination, solution, cancellationToken, out _); private bool CanAddTo(SyntaxNode destination, Solution solution, CancellationToken cancellationToken, out IList availableIndices, bool checkGeneratedCode = false) diff --git a/src/Workspaces/Core/Portable/Differencing/LongestCommonSubsequence.cs b/src/Workspaces/Core/Portable/Differencing/LongestCommonSubsequence.cs index 35e5367d14911..2d29be9a3ec3e 100644 --- a/src/Workspaces/Core/Portable/Differencing/LongestCommonSubsequence.cs +++ b/src/Workspaces/Core/Portable/Differencing/LongestCommonSubsequence.cs @@ -406,7 +406,6 @@ private VStack ComputeEditPaths(TSequence oldSequence, int oldLength, TSequence // start point var yStart = currentV[kPrev]; - var xStart = yStart + kPrev; // mid point var yMid = right ? yStart : yStart + 1; diff --git a/src/Workspaces/Core/Portable/Differencing/Match.cs b/src/Workspaces/Core/Portable/Differencing/Match.cs index 141a063861345..5812789337326 100644 --- a/src/Workspaces/Core/Portable/Differencing/Match.cs +++ b/src/Workspaces/Core/Portable/Differencing/Match.cs @@ -33,8 +33,8 @@ internal Match(TNode root1, TNode root2, TreeComparer comparer, IEnumerab _comparer = comparer; var labelCount = comparer.LabelCount; - CategorizeNodesByLabels(comparer, root1, labelCount, out var nodes1, out var count1); - CategorizeNodesByLabels(comparer, root2, labelCount, out var nodes2, out var count2); + CategorizeNodesByLabels(comparer, root1, labelCount, out var nodes1, out _); + CategorizeNodesByLabels(comparer, root2, labelCount, out var nodes2, out _); _oneToTwo = new Dictionary(); _twoToOne = new Dictionary(); diff --git a/src/Workspaces/Core/Portable/Execution/SerializerService_Asset.cs b/src/Workspaces/Core/Portable/Execution/SerializerService_Asset.cs index 4549521bd9ee5..3116cb5c49928 100644 --- a/src/Workspaces/Core/Portable/Execution/SerializerService_Asset.cs +++ b/src/Workspaces/Core/Portable/Execution/SerializerService_Asset.cs @@ -48,7 +48,7 @@ private SourceText DeserializeSourceText(ObjectReader reader, CancellationToken cancellationToken.ThrowIfCancellationRequested(); // REVIEW: why IDE services doesnt care about checksumAlgorithm? - var checksumAlgorithm = (SourceHashAlgorithm)reader.ReadInt32(); + _ = (SourceHashAlgorithm)reader.ReadInt32(); var encoding = ReadEncodingFrom(reader, cancellationToken); var kind = (SerializationKinds)reader.ReadInt32(); diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs b/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs index 96f198bebffc4..7cb5cf5d42b3e 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindLiterals/FindLiteralsSearchEngine.cs @@ -59,10 +59,10 @@ public FindLiteralsSearchEngine( _longValue = BitConverter.DoubleToInt64Bits(f); _searchKind = SearchKind.NumericLiterals; break; - case decimal d: // unsupported + case decimal _: // unsupported _searchKind = SearchKind.None; break; - case char c: + case char _: _longValue = IntegerUtilities.ToInt64(value); _searchKind = SearchKind.CharacterLiterals; break; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs index 4aed46cd3912f..3fd9bf38d91a4 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs @@ -263,7 +263,6 @@ protected static ImmutableArray FindReferencesInTokens( var location = token.GetLocation(); var symbolUsageInfo = GetSymbolUsageInfo(token.Parent, semanticModel, syntaxFacts, semanticFacts, cancellationToken); - var isWrittenTo = symbolUsageInfo.IsWrittenTo(); locations.Add(new FinderLocation(token.Parent, new ReferenceLocation( document, alias, location, isImplicit: false, symbolUsageInfo, GetAdditionalFindUsagesProperties(token.Parent, semanticModel, syntaxFacts), candidateReason: reason))); diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs index a54d7f39e1fac..97a7b4ed55349 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs @@ -540,7 +540,6 @@ internal void AssertEquivalentTo(SymbolTreeInfo other) Debug.Assert(_inheritanceMap.Keys.Count == other._inheritanceMap.Keys.Count); var orderedKeys1 = this._inheritanceMap.Keys.Order().ToList(); - var orderedKeys2 = other._inheritanceMap.Keys.Order().ToList(); for (var i = 0; i < orderedKeys1.Count; i++) { diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index b6816b8917683..114b679188004 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -398,6 +398,7 @@ private static bool HeuristicMetadataNameEquivalenceCheck( { return true; } + var index = newMetadataName.IndexOf(replacementText, 0); var newMetadataNameBuilder = new StringBuilder(); diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs index ca7cb84b8bbc6..52c58cf0925c4 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs @@ -210,7 +210,6 @@ private static bool IsBrowsingProhibitedByTypeLibAttributeWorker( { if (Equals(attribute.AttributeConstructor, constructor)) { - // Check for both constructor signatures. The constructor that takes a TypeLib*Flags reports an int argument. var argumentValue = attribute.ConstructorArguments.First().Value; diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs index 4d1ee85cb9d86..50e837e05e77e 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs @@ -107,7 +107,7 @@ public static ImmutableArray CreateFieldsForParameters( { // For non-out parameters, create a field and assign the parameter to it. // TODO: I'm not sure that's what we really want for ref parameters. - if (TryGetValue(parameterToNewFieldMap, parameterName, out var fieldName)) + if (TryGetValue(parameterToNewFieldMap, parameterName, out _)) { result.Add(CodeGenerationSymbolFactory.CreateFieldSymbol( attributes: default, @@ -278,6 +278,7 @@ public static async Task OverridePropertyAsync( { var getAccessibility = overriddenProperty.GetMethod.ComputeResultantAccessibility(containingType); var setAccessibility = overriddenProperty.SetMethod.ComputeResultantAccessibility(containingType); + SyntaxNode getBody; SyntaxNode setBody; // Implement an abstract property by throwing not implemented in accessors. diff --git a/src/Workspaces/Core/Portable/Workspace/Workspace.cs b/src/Workspaces/Core/Portable/Workspace/Workspace.cs index 26fc2ac567c2b..6d71f556d378c 100644 --- a/src/Workspaces/Core/Portable/Workspace/Workspace.cs +++ b/src/Workspaces/Core/Portable/Workspace/Workspace.cs @@ -1084,7 +1084,7 @@ protected void UpdateReferencesAfterAdd() if (newSolution != oldSolution) { newSolution = this.SetCurrentSolution(newSolution); - var ignore = this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.SolutionChanged, oldSolution, newSolution); + _ = this.RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.SolutionChanged, oldSolution, newSolution); } } } @@ -1503,7 +1503,6 @@ protected virtual void ApplyProjectChanges(ProjectChanges projectChanges) // changed additional documents foreach (var documentId in projectChanges.GetChangedAdditionalDocuments()) { - var oldDoc = projectChanges.OldProject.GetAdditionalDocument(documentId)!; var newDoc = projectChanges.NewProject.GetAdditionalDocument(documentId)!; // We don't understand the text of additional documents and so we just replace the entire text. @@ -1514,7 +1513,6 @@ protected virtual void ApplyProjectChanges(ProjectChanges projectChanges) // changed analyzer config documents foreach (var documentId in projectChanges.GetChangedAnalyzerConfigDocuments()) { - var oldDoc = projectChanges.OldProject.GetAnalyzerConfigDocument(documentId)!; var newDoc = projectChanges.NewProject.GetAnalyzerConfigDocument(documentId)!; // We don't understand the text of analyzer config documents and so we just replace the entire text. diff --git a/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs b/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs index 6b8185419a784..2b65f5e0b82cc 100644 --- a/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs +++ b/src/Workspaces/CoreTest/CodeStyle/EditorConfigCodeStyleParserTests.cs @@ -41,18 +41,6 @@ public class EditorConfigCodeStyleParserTests [InlineData("false : error", false, ReportDiagnostic.Error)] public void TestParseEditorConfigCodeStyleOption(string args, bool isEnabled, ReportDiagnostic severity) { - switch (severity) - { - case ReportDiagnostic.Hidden: - break; - case ReportDiagnostic.Info: - break; - case ReportDiagnostic.Warn: - break; - case ReportDiagnostic.Error: - break; - } - CodeStyleHelpers.TryParseBoolEditorConfigCodeStyleOption(args, out var result); Assert.True(result.Value == isEnabled, $"Expected {nameof(isEnabled)} to be {isEnabled}, was {result.Value}"); diff --git a/src/Workspaces/CoreTest/Differencing/LongestCommonSubsequenceTests.cs b/src/Workspaces/CoreTest/Differencing/LongestCommonSubsequenceTests.cs index b26cc697d3f22..f481744b2a996 100644 --- a/src/Workspaces/CoreTest/Differencing/LongestCommonSubsequenceTests.cs +++ b/src/Workspaces/CoreTest/Differencing/LongestCommonSubsequenceTests.cs @@ -310,7 +310,6 @@ public void LongString() var x9 = new string('x', 9); var x10 = new string('x', 10); var x99 = new string('x', 99); - var x100 = new string('x', 100); var x1000 = new string('x', 1000); var y1000 = new string('y', 1000); diff --git a/src/Workspaces/CoreTest/EditorConfigStorageLocation/NamingStylePreferenceEditorConfigStorageLocationTests.cs b/src/Workspaces/CoreTest/EditorConfigStorageLocation/NamingStylePreferenceEditorConfigStorageLocationTests.cs index 48bd97bcabca3..8a61832a9707a 100644 --- a/src/Workspaces/CoreTest/EditorConfigStorageLocation/NamingStylePreferenceEditorConfigStorageLocationTests.cs +++ b/src/Workspaces/CoreTest/EditorConfigStorageLocation/NamingStylePreferenceEditorConfigStorageLocationTests.cs @@ -16,7 +16,7 @@ public class NamingStylePreferenceEditorConfigStorageLocationTests public static void TestEmptyDictionaryReturnNoNamingStylePreferencesObjectReturnsFalse() { var editorConfigStorageLocation = new NamingStylePreferenceEditorConfigStorageLocation(); - var result = editorConfigStorageLocation.TryGetOption(new Dictionary(), typeof(NamingStylePreferences), out var @object); + var result = editorConfigStorageLocation.TryGetOption(new Dictionary(), typeof(NamingStylePreferences), out _); Assert.False(result, "Expected TryParseReadonlyDictionary to return 'false' for empty dictionary"); } @@ -27,7 +27,7 @@ public static void TestEmptyDictionaryDefaultNamingStylePreferencesObjectReturns var result = editorConfigStorageLocation.TryGetOption( new Dictionary(), typeof(NamingStylePreferences), - out var @object); + out _); Assert.False(result, "Expected TryParseReadonlyDictionary to return 'false' for empty dictionary"); } diff --git a/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs b/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs index 04ca9826db37e..a7f4c7462f136 100644 --- a/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs +++ b/src/Workspaces/CoreTest/SolutionTests/SolutionTests.cs @@ -1672,9 +1672,9 @@ public async Task TestGetSyntaxRootAsync() .AddDocument(did, "goo.cs", text); var document = sol.GetDocument(did); - Assert.False(document.TryGetSyntaxRoot(out var root)); + Assert.False(document.TryGetSyntaxRoot(out _)); - root = await document.GetSyntaxRootAsync(); + var root = await document.GetSyntaxRootAsync(); Assert.NotNull(root); Assert.Equal(text, root.ToString()); @@ -1727,9 +1727,9 @@ public void TestUpdateSyntaxTreeWithAnnotations() var root2 = tree2.GetRoot(); // text should not be available yet (it should be defer created from the node) // and getting the document or root should not cause it to be created. - Assert.False(tree2.TryGetText(out var text2)); + Assert.False(tree2.TryGetText(out _)); - text2 = tree2.GetText(); + var text2 = tree2.GetText(); Assert.NotNull(text2); Assert.NotSame(tree, tree2); @@ -1782,7 +1782,7 @@ public void TestSyntaxRootNotKeptAlive() observedRoot.AssertReleased(); // re-get the tree (should recover from storage, not reparse) - var root = sol.GetDocument(did).GetSyntaxRootAsync().Result; + _ = sol.GetDocument(did).GetSyntaxRootAsync().Result; } [MethodImpl(MethodImplOptions.NoInlining)] @@ -2614,7 +2614,7 @@ public void TestWithSyntaxTree() var newTree = recoverableTree.WithFilePath("different/dummy"); // this shouldn't throw - var root = newTree.GetRoot(); + _ = newTree.GetRoot(); } [Fact] diff --git a/src/Workspaces/CoreTest/SyntaxNodeTests.cs b/src/Workspaces/CoreTest/SyntaxNodeTests.cs index 8054758233fc8..b247637719e80 100644 --- a/src/Workspaces/CoreTest/SyntaxNodeTests.cs +++ b/src/Workspaces/CoreTest/SyntaxNodeTests.cs @@ -97,8 +97,6 @@ public async Task TestTrackNodesWithDocument() var trackedRoot = root.TrackNodes(classDecl, methodDecl); // use some fancy document centric rewrites - var comp = await doc.Project.GetCompilationAsync(); - var gen = SyntaxGenerator.GetGenerator(doc); var cgenField = gen.FieldDeclaration("X", gen.TypeExpression(SpecialType.System_Int32), Accessibility.Private); diff --git a/src/Workspaces/CoreTest/SyntaxPathTests.cs b/src/Workspaces/CoreTest/SyntaxPathTests.cs index a3899d4e4ef18..9aac45cf8b8ed 100644 --- a/src/Workspaces/CoreTest/SyntaxPathTests.cs +++ b/src/Workspaces/CoreTest/SyntaxPathTests.cs @@ -29,7 +29,7 @@ public void FailFirstType() var node = SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("Hi")); var path = new SyntaxPath(node); - Assert.False(path.TryResolve(SyntaxFactory.ParseExpression("Goo()"), out SyntaxNode recovered)); + Assert.False(path.TryResolve(SyntaxFactory.ParseExpression("Goo()"), out SyntaxNode _)); } [Fact] @@ -49,7 +49,7 @@ public void FailChildCount() var path = new SyntaxPath(((InvocationExpressionSyntax)root).ArgumentList.Arguments.Last()); var root2 = SyntaxFactory.ParseExpression("Goo(a)"); - Assert.False(path.TryResolve(root2, out SyntaxNode recovered)); + Assert.False(path.TryResolve(root2, out SyntaxNode _)); } [Fact] @@ -59,7 +59,7 @@ public void FailChildType() var path = new SyntaxPath(((InvocationExpressionSyntax)root).ArgumentList.Arguments.First().Expression); var root2 = SyntaxFactory.ParseExpression("Goo(3)"); - Assert.False(path.TryResolve(root2, out SyntaxNode recovered)); + Assert.False(path.TryResolve(root2, out SyntaxNode _)); } [Fact] @@ -254,7 +254,7 @@ class D { tree = WithReplaceFirst(tree, "class", "struct"); Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1)); - Assert.False(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2)); + Assert.False(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode _)); Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind()); Assert.Equal("D", ((TypeDeclarationSyntax)n1).Identifier.ValueText); @@ -284,8 +284,8 @@ class D { tree = WithReplaceFirst(tree, "class", "struct"); Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1)); - Assert.False(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2)); - Assert.False(path3.TryResolve(tree, CancellationToken.None, out SyntaxNode n3)); + Assert.False(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode _)); + Assert.False(path3.TryResolve(tree, CancellationToken.None, out SyntaxNode _)); Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind()); Assert.Equal("D", ((TypeDeclarationSyntax)n1).Identifier.ValueText); diff --git a/src/Workspaces/CoreTest/UtilityTest/BKTreeTests.cs b/src/Workspaces/CoreTest/UtilityTest/BKTreeTests.cs index 1c5b0ee8e8b7e..1609d7cb1de76 100644 --- a/src/Workspaces/CoreTest/UtilityTest/BKTreeTests.cs +++ b/src/Workspaces/CoreTest/UtilityTest/BKTreeTests.cs @@ -40,7 +40,6 @@ private void TestTreeInvariants(string[] testValues) foreach (var value in testValues) { // With a threshold of 0, we should only find exactly the item we're searching for. - var items = tree.Find(value, threshold: 0); Assert.Single(tree.Find(value, threshold: 0), value.ToLower()); } diff --git a/src/Workspaces/DesktopTest/CommandLineProjectTests.cs b/src/Workspaces/DesktopTest/CommandLineProjectTests.cs index 28c936caae062..9ebac33273ec9 100644 --- a/src/Workspaces/DesktopTest/CommandLineProjectTests.cs +++ b/src/Workspaces/DesktopTest/CommandLineProjectTests.cs @@ -44,7 +44,7 @@ public void TestCreateWithRequiredServices() { string commandLine = @"goo.cs"; var ws = new AdhocWorkspace(DesktopMefHostServices.DefaultServices); // includes non-portable services too - var info = CommandLineProject.CreateProjectInfo("TestProject", LanguageNames.CSharp, commandLine, @"C:\ProjectDirectory", ws); + _ = CommandLineProject.CreateProjectInfo("TestProject", LanguageNames.CSharp, commandLine, @"C:\ProjectDirectory", ws); } [Fact] diff --git a/src/Workspaces/MSBuildTest/MSBuildWorkspaceTests.cs b/src/Workspaces/MSBuildTest/MSBuildWorkspaceTests.cs index 219d98e1900ab..f584ed3e5aa5a 100644 --- a/src/Workspaces/MSBuildTest/MSBuildWorkspaceTests.cs +++ b/src/Workspaces/MSBuildTest/MSBuildWorkspaceTests.cs @@ -705,7 +705,6 @@ public async Task TestOpenProject_VisualBasic_WithoutAssemblyName() [ConditionalFact(typeof(VisualStudioMSBuildInstalled)), Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)] public async Task Test_Respect_ReferenceOutputassembly_Flag() { - var projFile = GetSolutionFileName(@"VisualBasicProject\VisualBasicProject.vbproj"); CreateFiles(GetSimpleCSharpSolutionFiles() .WithFile(@"VisualBasicProject_Circular_Top.vbproj", Resources.ProjectFiles.VisualBasic.Circular_Top) .WithFile(@"VisualBasicProject_Circular_Target.vbproj", Resources.ProjectFiles.VisualBasic.Circular_Target)); diff --git a/src/Workspaces/MSBuildTest/WorkspaceTestBase.cs b/src/Workspaces/MSBuildTest/WorkspaceTestBase.cs index 84dda873aa527..ffbb305c1f3ba 100644 --- a/src/Workspaces/MSBuildTest/WorkspaceTestBase.cs +++ b/src/Workspaces/MSBuildTest/WorkspaceTestBase.cs @@ -310,7 +310,6 @@ protected Document AssertSemanticVersionChanged(Document document, SourceText ne var docVersion = document.GetTopLevelChangeTextVersionAsync().Result; var projVersion = document.Project.GetSemanticVersionAsync().Result; - var text = document.GetTextAsync().Result; var newDoc = document.WithText(newText); var newDocVersion = newDoc.GetTopLevelChangeTextVersionAsync().Result; @@ -327,7 +326,6 @@ protected Document AssertSemanticVersionUnchanged(Document document, SourceText var docVersion = document.GetTopLevelChangeTextVersionAsync().Result; var projVersion = document.Project.GetSemanticVersionAsync().Result; - var text = document.GetTextAsync().Result; var newDoc = document.WithText(newText); var newDocVersion = newDoc.GetTopLevelChangeTextVersionAsync().Result; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs index ccde76e8c1c40..56761202f745e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxNodeExtensions.cs @@ -894,7 +894,7 @@ public static bool CheckTopLevel(this SyntaxNode node, TextSpan span) break; } - case GlobalStatementSyntax global: + case GlobalStatementSyntax _: return true; case ConstructorInitializerSyntax constructorInitializer: return constructorInitializer.ContainsInArgument(span); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs index 694e2482de1d4..51b57731e51b1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs @@ -224,7 +224,6 @@ public static bool IsEntirelyWithinSingleLineDocComment( if (trivia.IsSingleLineDocComment()) { - var span = trivia.Span; var fullSpan = trivia.FullSpan; var endsWithNewLine = trivia.GetStructure().GetLastToken(includeSkipped: true).Kind() == SyntaxKind.XmlTextLiteralNewLineToken; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs index fccaace6963b5..1a654f42f2ec9 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxFacts.cs @@ -1098,7 +1098,7 @@ private void CheckMemberId(SyntaxNode root, SyntaxNode node, int memberId) } // If this node is not parented by a name, we're done. - if (!(parent is NameSyntax name)) + if (!(parent is NameSyntax)) { break; } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs index 1f2e36cf9bd5e..c2b9b900257e7 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs @@ -1094,7 +1094,7 @@ private static Conversion GetSpeculatedExpressionToOuterTypeConversion(Expressio return conversion; } - var speculatedExpressionOuterType = GetOuterCastType(speculatedExpression, speculationAnalyzer.SpeculativeSemanticModel, out var discarded) ?? typeInfo.ConvertedType; + var speculatedExpressionOuterType = GetOuterCastType(speculatedExpression, speculationAnalyzer.SpeculativeSemanticModel, out _) ?? typeInfo.ConvertedType; if (speculatedExpressionOuterType == null) { return default; @@ -1163,7 +1163,7 @@ private static bool ParamsArgumentCastMustBePreserved( if (parent is AttributeArgumentSyntax attributeArgument) { - if (attributeArgument.Parent is AttributeArgumentListSyntax attributeArgumentList) + if (attributeArgument.Parent is AttributeArgumentListSyntax) { // We don't check the position of the argument because in attributes it is allowed that // params parameter are positioned in between if named arguments are used. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs index 46746c6c8df4d..8a9e6318d40fa 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs @@ -207,7 +207,7 @@ internal static class FormattingRangeHelper // double initializer case such as // { { } - if (parentOfParent is InitializerExpressionSyntax doubleInitializer) + if (parentOfParent is InitializerExpressionSyntax) { // if parent block has a missing brace, and current block is on same line, then // don't try to indent inner block. diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/OperatorPlacementWhenWrappingPreference.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/OperatorPlacementWhenWrappingPreference.cs index 956461f4f045e..2b37a394b1145 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/OperatorPlacementWhenWrappingPreference.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CodeStyle/OperatorPlacementWhenWrappingPreference.cs @@ -22,7 +22,7 @@ public static string GetEditorConfigString(OperatorPlacementWhenWrappingPreferen public static Optional Parse(string optionString) { if (CodeStyleHelpers.TryGetCodeStyleValueAndOptionalNotification( - optionString, out var value, out var notificationOpt)) + optionString, out var value, out _)) { switch (value) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ISymbolExtensions_Accessibility.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ISymbolExtensions_Accessibility.cs index df997f2cf00d3..24a578c5a220e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ISymbolExtensions_Accessibility.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ISymbolExtensions_Accessibility.cs @@ -42,7 +42,7 @@ public static bool IsAccessibleWithin( IAssemblySymbol within, ITypeSymbol? throughType = null) { - return IsSymbolAccessibleCore(symbol, within, throughType, out var failedThroughTypeCheck); + return IsSymbolAccessibleCore(symbol, within, throughType, out _); } /// @@ -54,7 +54,7 @@ public static bool IsAccessibleWithin( INamedTypeSymbol within, ITypeSymbol? throughType = null) { - return IsSymbolAccessible(symbol, within, throughType, out var failedThroughTypeCheck); + return IsSymbolAccessible(symbol, within, throughType, out _); } /// @@ -170,7 +170,6 @@ private static bool IsNamedTypeAccessible(INamedTypeSymbol type, ISymbol within) return true; } - bool unused; if (!type.IsDefinition) { // All type argument must be accessible. @@ -180,7 +179,7 @@ private static bool IsNamedTypeAccessible(INamedTypeSymbol type, ISymbol within) // worth optimizing this). if (typeArg.Kind != SymbolKind.TypeParameter && typeArg.TypeKind != TypeKind.Error && - !IsSymbolAccessibleCore(typeArg, within, null, out unused)) + !IsSymbolAccessibleCore(typeArg, within, null, out _)) { return false; } @@ -190,7 +189,7 @@ private static bool IsNamedTypeAccessible(INamedTypeSymbol type, ISymbol within) var containingType = type.ContainingType; return containingType == null ? IsNonNestedTypeAccessible(type.ContainingAssembly, type.DeclaredAccessibility, within) - : IsMemberAccessible(type.ContainingType, type.DeclaredAccessibility, within, null, out unused); + : IsMemberAccessible(type.ContainingType, type.DeclaredAccessibility, within, null, out _); } // Is a top-level type with accessibility "declaredAccessibility" inside assembly "assembly" diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Changes.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Changes.cs index 7046208f972b2..e58a188336ca3 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Changes.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Changes.cs @@ -24,7 +24,7 @@ private struct Changes private ConcurrentDictionary _map; public bool TryRemove(int pairIndex) - => _map?.TryRemove(pairIndex, out var temp) ?? false; + => _map?.TryRemove(pairIndex, out _) ?? false; public void AddOrReplace(int key, TriviaData triviaInfo) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/FormattingExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/FormattingExtensions.cs index 56f18c7693a7b..fe1674ed64efc 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/FormattingExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/FormattingExtensions.cs @@ -168,7 +168,6 @@ public static string AdjustIndentForXmlDocExteriorTrivia( var isEmptyString = false; var builder = StringBuilderPool.Allocate(); - var trimmedTriviaText = triviaText.TrimEnd(s_trimChars); var nonWhitespaceCharIndex = GetFirstNonWhitespaceIndexInString(triviaText); if (nonWhitespaceCharIndex == -1) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/AbstractSyntaxFacts.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/AbstractSyntaxFacts.cs index 0e829571a145d..992a3cb36e8d9 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/AbstractSyntaxFacts.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/AbstractSyntaxFacts.cs @@ -231,7 +231,7 @@ public ImmutableArray GetLeadingBlankLines(TSyntaxNod public TSyntaxNode GetNodeWithoutLeadingBlankLines(TSyntaxNode node) where TSyntaxNode : SyntaxNode { - return GetNodeWithoutLeadingBlankLines(node, out var blankLines); + return GetNodeWithoutLeadingBlankLines(node, out _); } public TSyntaxNode GetNodeWithoutLeadingBlankLines( @@ -259,7 +259,7 @@ public TSyntaxNode GetNodeWithoutLeadingBannerAndPreprocessorDirectives( diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CancellableLazy`1.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CancellableLazy`1.cs index 92357e262c26a..db5ee597b6afe 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CancellableLazy`1.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CancellableLazy`1.cs @@ -26,7 +26,7 @@ public bool HasValue { get { - return this.TryGetValue(out var tmp); + return this.TryGetValue(out _); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CommonFormattingHelpers.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CommonFormattingHelpers.cs index 53fc7514f8156..dd0cfdd71b5d8 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CommonFormattingHelpers.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/CommonFormattingHelpers.cs @@ -51,7 +51,6 @@ public static IEnumerable> ConvertToTokenPa yield break; } - var pairs = new List>(); var previousOne = root.ConvertToTokenPair(spans[0]); // iterate through each spans and make sure each one doesn't overlap each other @@ -179,8 +178,6 @@ public static void AppendTextBetween(SyntaxToken token1, SyntaxToken token2, Str return; } - var token1PartOftoken2LeadingTrivia = token1.FullSpan.Start > token2.FullSpan.Start; - if (token1.FullSpan.End == token2.FullSpan.Start) { AppendTextBetweenTwoAdjacentTokens(token1, token2, builder); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/WordSimilarityChecker.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/WordSimilarityChecker.cs index 5d746e5405055..02ccc3322e920 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/WordSimilarityChecker.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/WordSimilarityChecker.cs @@ -85,7 +85,7 @@ public static bool AreSimilar(string originalText, string candidateText) => AreSimilar(originalText, candidateText, substringsAreSimilar: false); public static bool AreSimilar(string originalText, string candidateText, bool substringsAreSimilar) - => AreSimilar(originalText, candidateText, substringsAreSimilar, out var unused); + => AreSimilar(originalText, candidateText, substringsAreSimilar, out _); public static bool AreSimilar(string originalText, string candidateText, out double similarityWeight) { @@ -112,7 +112,7 @@ internal static int GetThreshold(string value) => value.Length <= 4 ? 1 : 2; public bool AreSimilar(string candidateText) - => AreSimilar(candidateText, out var similarityWeight); + => AreSimilar(candidateText, out _); public bool AreSimilar(string candidateText, out double similarityWeight) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxNodeExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxNodeExtensions.vb index 703b4e78292d2..e5b17834623f2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxNodeExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxNodeExtensions.vb @@ -765,8 +765,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions statements, SyntaxFactory.EndSubStatement()).WithAdditionalAnnotations(annotations) - current = singleLineLambda.Parent - oldBlock = singleLineLambda newBlock = multiLineLambda diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs index b724fe9667346..f8e9e67c8bec9 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/CSharpSyntaxContext.cs @@ -271,7 +271,7 @@ private static CSharpSyntaxContext CreateContextWorker(Workspace workspace, Sema public static CSharpSyntaxContext CreateContext_Test(SemanticModel semanticModel, int position, CancellationToken cancellationToken) { var inferenceService = new CSharpTypeInferenceService(); - var types = inferenceService.InferTypes(semanticModel, position, cancellationToken); + _ = inferenceService.InferTypes(semanticModel, position, cancellationToken); return CreateContextWorker(workspace: null, semanticModel: semanticModel, position: position, cancellationToken: cancellationToken); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs index 428a5dcb68a4d..333ecda367e05 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs @@ -105,7 +105,7 @@ public static ImmutableArray LookupName( CancellationToken cancellationToken) { var expr = SyntaxFactory.GetStandaloneExpression(expression); - DecomposeName(expr, out var qualifier, out var name, out var arity); + DecomposeName(expr, out var qualifier, out var name, out _); INamespaceOrTypeSymbol symbol = null; if (qualifier != null) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SyntaxTreeExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SyntaxTreeExtensions.cs index 9bf90117f60dc..535f3f93d8284 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SyntaxTreeExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SyntaxTreeExtensions.cs @@ -95,7 +95,7 @@ public static bool IsInInactiveRegion( public static bool IsInPartiallyWrittenGeneric( this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken) { - return syntaxTree.IsInPartiallyWrittenGeneric(position, cancellationToken, out var genericIdentifier, out var lessThanToken); + return syntaxTree.IsInPartiallyWrittenGeneric(position, cancellationToken, out _, out _); } public static bool IsInPartiallyWrittenGeneric( @@ -104,7 +104,7 @@ public static bool IsInPartiallyWrittenGeneric( CancellationToken cancellationToken, out SyntaxToken genericIdentifier) { - return syntaxTree.IsInPartiallyWrittenGeneric(position, cancellationToken, out genericIdentifier, out var lessThanToken); + return syntaxTree.IsInPartiallyWrittenGeneric(position, cancellationToken, out genericIdentifier, out _); } public static bool IsInPartiallyWrittenGeneric( diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index 070fb55670ea9..52cab148a1e74 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -144,7 +144,7 @@ protected override IEnumerable InferTypesWorker_DoNotCallDire ArrowExpressionClauseSyntax arrowClause => InferTypeInArrowExpressionClause(arrowClause), AssignmentExpressionSyntax assignmentExpression => InferTypeInBinaryOrAssignmentExpression(assignmentExpression, assignmentExpression.OperatorToken, assignmentExpression.Left, assignmentExpression.Right, expression), AttributeArgumentSyntax attribute => InferTypeInAttributeArgument(attribute), - AttributeSyntax attribute => InferTypeInAttribute(), + AttributeSyntax _ => InferTypeInAttribute(), AwaitExpressionSyntax awaitExpression => InferTypeInAwaitExpression(awaitExpression), BinaryExpressionSyntax binaryExpression => InferTypeInBinaryOrAssignmentExpression(binaryExpression, binaryExpression.OperatorToken, binaryExpression.Left, binaryExpression.Right, expression), CastExpressionSyntax castExpression => InferTypeInCastExpression(castExpression, expression), diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs index 4bcf5634d6cb3..a2254daca448a 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/AddImports/AbstractAddImportsService.cs @@ -96,7 +96,8 @@ public SyntaxNode GetImportContainer(SyntaxNode root, SyntaxNode? contextLocatio switch (import) { - case TExternSyntax e: return externContainer; + case TExternSyntax _: + return externContainer; case TUsingOrAliasSyntax u: if (IsAlias(u)) { diff --git a/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb b/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb index 90e59df96bf5d..de2df6de0a0f5 100644 --- a/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb +++ b/src/Workspaces/VisualBasic/Portable/Rename/VisualBasicRenameRewriterLanguageService.vb @@ -463,7 +463,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename If identifierToken <> Nothing AndAlso Not Me._annotatedIdentifierTokens.Contains(identifierToken) Then Dim symbolInfo = Me._semanticModel.GetSymbolInfo(invocationExpression, Me._cancellationToken) - Dim symbols As IEnumerable(Of ISymbol) = Nothing + Dim symbols As IEnumerable(Of ISymbol) If symbolInfo.Symbol Is Nothing Then Return Nothing Else diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/AbstractVisualBasicReducer.AbstractReductionRewriter.vb b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/AbstractVisualBasicReducer.AbstractReductionRewriter.vb index 1ca866ee8ae51..8b98b289b8199 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/AbstractVisualBasicReducer.AbstractReductionRewriter.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/AbstractVisualBasicReducer.AbstractReductionRewriter.vb @@ -33,7 +33,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification Public Sub Initialize(parseOptions As ParseOptions, optionSet As OptionSet, cancellationToken As CancellationToken) Implements IReductionRewriter.Initialize Me.ParseOptions = DirectCast(parseOptions, VisualBasicParseOptions) _simplificationOptions = optionSet - cancellationToken = cancellationToken + Me.CancellationToken = cancellationToken End Sub Public Sub Dispose() Implements IDisposable.Dispose diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.Expander.vb b/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.Expander.vb index eb37ddd342dc3..59cecef73b403 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.Expander.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/VisualBasicSimplificationService.Expander.vb @@ -353,7 +353,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification Dim found = False For Each argument In tuple.Arguments - Dim elementName = Nothing + Dim elementName As Object If argument.NameColonEquals IsNot Nothing Then elementName = argument.NameColonEquals.Name.Identifier.ValueText Else @@ -752,8 +752,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification Select Case parent.Kind Case SyntaxKind.QualifiedName - Dim qualifiedParent = DirectCast(parent, QualifiedNameSyntax) - result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.QualifiedName( DirectCast(left, NameSyntax), diff --git a/src/Workspaces/VisualBasicTest/CodeGeneration/SyntaxGeneratorTests.vb b/src/Workspaces/VisualBasicTest/CodeGeneration/SyntaxGeneratorTests.vb index 4a365bb97af9c..f587fc3f59942 100644 --- a/src/Workspaces/VisualBasicTest/CodeGeneration/SyntaxGeneratorTests.vb +++ b/src/Workspaces/VisualBasicTest/CodeGeneration/SyntaxGeneratorTests.vb @@ -553,8 +553,6 @@ End If") Public Sub TestSwitchStatements() - Dim x = 10 - VerifySyntax(Of SelectBlockSyntax)( Generator.SwitchStatement(Generator.IdentifierName("x"), Generator.SwitchSection(Generator.IdentifierName("y"), diff --git a/src/Workspaces/VisualBasicTest/Formatting/VisualBasicFormattingTestBase.vb b/src/Workspaces/VisualBasicTest/Formatting/VisualBasicFormattingTestBase.vb index 7881726aec877..8d9156f66087a 100644 --- a/src/Workspaces/VisualBasicTest/Formatting/VisualBasicFormattingTestBase.vb +++ b/src/Workspaces/VisualBasicTest/Formatting/VisualBasicFormattingTestBase.vb @@ -80,7 +80,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Formatting Protected Function AssertFormatSpanAsync(markupCode As String, expected As String) As Task Dim code As String = Nothing - Dim cursorPosition As Integer? = Nothing Dim spans As ImmutableArray(Of TextSpan) = Nothing MarkupTestFile.GetSpans(markupCode, code, spans) From bd25849fdfc80db9286673c5fe57bd1d1212cb73 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Wed, 29 Apr 2020 08:30:09 -0700 Subject: [PATCH 144/222] Revert temporary workaround for IDE0059 FixAll operation --- .editorconfig | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.editorconfig b/.editorconfig index dc7b06ed952fe..699fb17642c9f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -225,10 +225,6 @@ dotnet_diagnostic.RS0037.severity = none # warning RS0005: Do not use generic CodeAction.Create to create CodeAction dotnet_diagnostic.RS0005.severity = none -[*.{cs,vb}] -# Temporary workaround to enable FixAll in solution -dotnet_diagnostic.IDE0059.severity = none - [src/{Analyzers,CodeStyle,Features,Workspaces}/**/*.{cs,vb}] # IDE0005: Remove unnecessary usings/imports dotnet_diagnostic.IDE0005.severity = warning From 7b27ca3b7722c5e56910a6cfba837e6a9d352d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Mon, 11 May 2020 19:17:04 -0700 Subject: [PATCH 145/222] Fixes PathMap parsing to support all paths (#43706) --- docs/compilers/CSharp/CommandLine.md | 2 +- docs/compilers/Visual Basic/CommandLine.md | 2 +- .../Test/CommandLine/CommandLineTests.cs | 64 ++++++++++++++----- .../Microsoft.Managed.Core.targets | 18 ++---- .../Core/MSBuildTaskTests/DotNetSdkTests.cs | 61 +++++++++++++++--- .../Portable/CommandLine/CommandLineParser.cs | 58 +++++++++++++++-- .../Test/CommandLine/CommandLineTests.vb | 56 ++++++++++------ 7 files changed, 203 insertions(+), 58 deletions(-) diff --git a/docs/compilers/CSharp/CommandLine.md b/docs/compilers/CSharp/CommandLine.md index b9d175c5f58c8..929aa5adba0f2 100644 --- a/docs/compilers/CSharp/CommandLine.md +++ b/docs/compilers/CSharp/CommandLine.md @@ -72,7 +72,7 @@ | `/main`:*type* | Specify the type that contains the entry point (ignore all other possible entry points) (Short form: `/m`) | `/fullpaths` | Compiler generates fully qualified paths | `/filealign`:*n* | Specify the alignment used for output file sections -| `/pathmap:`*k1*=*v1*,*k2*=*v2*,... | Specify a mapping for source path names output by the compiler. +| `/pathmap:`*k1*=*v1*,*k2*=*v2*,... | Specify a mapping for source path names output by the compiler. Two consecutive separator characters are treated as a single character that is part of the key or value (i.e. `==` stands for `=` and `,,` for `,`). | `/pdb:`*file* | Specify debug information file name (default: output file name with `.pdb` extension) | `/errorendlocation` | Output line and column of the end location of each error | `/preferreduilang` | Specify the preferred output language name. diff --git a/docs/compilers/Visual Basic/CommandLine.md b/docs/compilers/Visual Basic/CommandLine.md index 0a19596761318..c9ac6b34d0af1 100644 --- a/docs/compilers/Visual Basic/CommandLine.md +++ b/docs/compilers/Visual Basic/CommandLine.md @@ -84,7 +84,7 @@ | `/moduleassemblyname:`*string* | Name of the assembly which this module will be a part of. | `/netcf` | Target the .NET Compact Framework. | `/nostdlib` | Do not reference standard libraries (`system.dll` and `VBC.RSP` file). -| `/pathmap:`*k1*=*v1*,*k2*=*v2*,... | Specify a mapping for source path names output by the compiler. +| `/pathmap:`*k1*=*v1*,*k2*=*v2*,... | Specify a mapping for source path names output by the compiler. Two consecutive separator characters are treated as a single character that is part of the key or value (i.e. `==` stands for `=` and `,,` for `,`). | `/platform:`*string* | Limit which platforms this code can run on; must be `x86`, `x64`, `Itanium`, `arm`, `AnyCPU32BitPreferred` or `anycpu` (default). | `/preferreduilang` | Specify the preferred output language name. | `/sdkpath:`*path* | Location of the .NET Framework SDK directory (`mscorlib.dll`). diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index 2ca3621266f2e..f14907018027c 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -10549,33 +10549,40 @@ public void ParseSeparatedPaths_QuotedComma() paths); } + [Fact] [CompilerTrait(CompilerFeature.Determinism)] - [ConditionalFact(typeof(WindowsOnly), Reason = "https://github.com/dotnet/roslyn/issues/30289")] public void PathMapParser() { + var s = PathUtilities.DirectorySeparatorStr; + var parsedArgs = DefaultParse(new[] { "/pathmap:", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); Assert.Equal(ImmutableArray.Create>(), parsedArgs.PathMap); parsedArgs = DefaultParse(new[] { "/pathmap:K1=V1", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); - Assert.Equal(KeyValuePairUtil.Create("K1\\", "V1\\"), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("K1" + s, "V1" + s), parsedArgs.PathMap[0]); - parsedArgs = DefaultParse(new[] { "/pathmap:C:\\goo\\=/", "a.cs" }, WorkingDirectory); + parsedArgs = DefaultParse(new[] { $"/pathmap:abc{s}=/", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); - Assert.Equal(KeyValuePairUtil.Create("C:\\goo\\", "/"), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("abc" + s, "/"), parsedArgs.PathMap[0]); parsedArgs = DefaultParse(new[] { "/pathmap:K1=V1,K2=V2", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); - Assert.Equal(KeyValuePairUtil.Create("K1\\", "V1\\"), parsedArgs.PathMap[0]); - Assert.Equal(KeyValuePairUtil.Create("K2\\", "V2\\"), parsedArgs.PathMap[1]); + Assert.Equal(KeyValuePairUtil.Create("K1" + s, "V1" + s), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("K2" + s, "V2" + s), parsedArgs.PathMap[1]); + + parsedArgs = DefaultParse(new[] { "/pathmap:,", "a.cs" }, WorkingDirectory); + parsedArgs.Errors.Verify(); + Assert.Equal(ImmutableArray.Create>(), parsedArgs.PathMap); + + parsedArgs = DefaultParse(new[] { "/pathmap:,,", "a.cs" }, WorkingDirectory); + Assert.Equal(1, parsedArgs.Errors.Count()); + Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[0].Code); parsedArgs = DefaultParse(new[] { "/pathmap:,,,", "a.cs" }, WorkingDirectory); - Assert.Equal(4, parsedArgs.Errors.Count()); + Assert.Equal(1, parsedArgs.Errors.Count()); Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[0].Code); - Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[1].Code); - Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[2].Code); - Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[3].Code); parsedArgs = DefaultParse(new[] { "/pathmap:k=,=v", "a.cs" }, WorkingDirectory); Assert.Equal(2, parsedArgs.Errors.Count()); @@ -10586,19 +10593,46 @@ public void PathMapParser() Assert.Equal(1, parsedArgs.Errors.Count()); Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[0].Code); + parsedArgs = DefaultParse(new[] { "/pathmap:k=", "a.cs" }, WorkingDirectory); + Assert.Equal(1, parsedArgs.Errors.Count()); + Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[0].Code); + + parsedArgs = DefaultParse(new[] { "/pathmap:=v", "a.cs" }, WorkingDirectory); + Assert.Equal(1, parsedArgs.Errors.Count()); + Assert.Equal((int)ErrorCode.ERR_InvalidPathMap, parsedArgs.Errors[0].Code); + parsedArgs = DefaultParse(new[] { "/pathmap:\"supporting spaces=is hard\"", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); - Assert.Equal(KeyValuePairUtil.Create("supporting spaces\\", "is hard\\"), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("supporting spaces" + s, "is hard" + s), parsedArgs.PathMap[0]); parsedArgs = DefaultParse(new[] { "/pathmap:\"K 1=V 1\",\"K 2=V 2\"", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); - Assert.Equal(KeyValuePairUtil.Create("K 1\\", "V 1\\"), parsedArgs.PathMap[0]); - Assert.Equal(KeyValuePairUtil.Create("K 2\\", "V 2\\"), parsedArgs.PathMap[1]); + Assert.Equal(KeyValuePairUtil.Create("K 1" + s, "V 1" + s), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("K 2" + s, "V 2" + s), parsedArgs.PathMap[1]); parsedArgs = DefaultParse(new[] { "/pathmap:\"K 1\"=\"V 1\",\"K 2\"=\"V 2\"", "a.cs" }, WorkingDirectory); parsedArgs.Errors.Verify(); - Assert.Equal(KeyValuePairUtil.Create("K 1\\", "V 1\\"), parsedArgs.PathMap[0]); - Assert.Equal(KeyValuePairUtil.Create("K 2\\", "V 2\\"), parsedArgs.PathMap[1]); + Assert.Equal(KeyValuePairUtil.Create("K 1" + s, "V 1" + s), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("K 2" + s, "V 2" + s), parsedArgs.PathMap[1]); + + parsedArgs = DefaultParse(new[] { "/pathmap:\"a ==,,b\"=\"1,,== 2\",\"x ==,,y\"=\"3 4\",", "a.cs" }, WorkingDirectory); + parsedArgs.Errors.Verify(); + Assert.Equal(KeyValuePairUtil.Create("a =,b" + s, "1,= 2" + s), parsedArgs.PathMap[0]); + Assert.Equal(KeyValuePairUtil.Create("x =,y" + s, "3 4" + s), parsedArgs.PathMap[1]); + } + + [Theory] + [InlineData("", new string[0])] + [InlineData(",", new[] { "", "" })] + [InlineData(",,", new[] { "," })] + [InlineData(",,,", new[] { ",", "" })] + [InlineData(",,,,", new[] { ",," })] + [InlineData("a,", new[] { "a", "" })] + [InlineData("a,b", new[] { "a", "b" })] + [InlineData(",,a,,,,,b,,", new[] { ",a,,", "b," })] + public void SplitWithDoubledSeparatorEscaping(string str, string[] expected) + { + AssertEx.Equal(expected, CommandLineParser.SplitWithDoubledSeparatorEscaping(str, ',')); } [ConditionalFact(typeof(WindowsOnly), Reason = "https://github.com/dotnet/roslyn/issues/30289")] diff --git a/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets b/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets index 7088355bbccfb..470a1a1862d12 100644 --- a/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets +++ b/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets @@ -159,7 +159,8 @@ --> + DependsOnTargets="_InitializeSourceRootMappedPathsFromSourceControl" + Returns="@(SourceRoot)"> <_MappedSourceRoot Remove="@(_MappedSourceRoot)" /> @@ -207,26 +208,21 @@ Condition="'$(DeterministicSourcePaths)' == 'true'"> - <_TopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"/> + <_TopLevelSourceRoot Include="@(SourceRoot)" Condition="'%(SourceRoot.NestedRoot)' == ''"> + $([MSBuild]::ValueOrDefault('%(Identity)', '').Replace(',', ',,').Replace('=', '==')) + $([MSBuild]::ValueOrDefault('%(MappedPath)', '').Replace(',', ',,').Replace('=', '==')) + - - - - ,$(PathMap) - - @(_TopLevelSourceRoot->'%(Identity)=%(MappedPath)', ',')$(PathMap) + @(_TopLevelSourceRoot->'%(EscapedKey)=%(EscapedValue)', ','),$(PathMap) diff --git a/src/Compilers/Core/MSBuildTaskTests/DotNetSdkTests.cs b/src/Compilers/Core/MSBuildTaskTests/DotNetSdkTests.cs index ebffbaa30a587..1aa7b5fff0205 100644 --- a/src/Compilers/Core/MSBuildTaskTests/DotNetSdkTests.cs +++ b/src/Compilers/Core/MSBuildTaskTests/DotNetSdkTests.cs @@ -6,21 +6,24 @@ using System.IO; using Roslyn.Test.Utilities; +using Xunit; namespace Microsoft.CodeAnalysis.BuildTasks.UnitTests { public class DotNetSdkTests : DotNetSdkTestBase { [ConditionalFact(typeof(DotNetSdkAvailable))] + [WorkItem(22835, "https://github.com/dotnet/roslyn/issues/22835")] public void TestSourceLink() { - var sourcePackageDir = Temp.CreateDirectory(); - // TODO: test escaping (https://github.com/dotnet/roslyn/issues/22835): .CreateDirectory("a=b, c"); - + var sourcePackageDir = Temp.CreateDirectory().CreateDirectory("a=b, c"); var libFile = sourcePackageDir.CreateFile("lib.cs").WriteAllText("class Lib { public void M() { } }"); - var root1 = Path.GetFullPath(ProjectDir.Path + "\\"); - var root2 = Path.GetFullPath(sourcePackageDir.Path + "\\"); + var root1 = Path.GetFullPath(ProjectDir.Path + Path.DirectorySeparatorChar); + var root2 = Path.GetFullPath(sourcePackageDir.Path + Path.DirectorySeparatorChar); + + var escapedRoot1 = root1.Replace(",", ",,").Replace("=", "=="); + var escapedRoot2 = root2.Replace(",", ",,").Replace("=", "=="); var sourceLinkJsonPath = Path.Combine(ObjDir.Path, ProjectName + ".sourcelink.json"); @@ -86,7 +89,7 @@ public void TestSourceLink() $@"{root1}sub1\: /_/sub1/", $@"{root1}sub2\: /_/sub2/", "true", - $@"{root2}=/_1/,{root1}=/_/,PreviousPathMap", + $@"{escapedRoot2}=/_1/,{escapedRoot1}=/_/,PreviousPathMap", "true" }); @@ -236,7 +239,7 @@ public void TestSourceLink() $@"{root1}: /_/", $@"{root2}: /_1/", @"true", - $@"{root1}=/_/,{root2}=/_1/" + $@"{escapedRoot1}=/_/,{escapedRoot2}=/_1/," }); AssertEx.AssertEqualToleratingWhitespaceDifferences( @@ -274,7 +277,7 @@ public void TestSourceLink() $@"{root1}: /_/", $@"{root2}: /_1/", @"true", - $@"{root1}=/_/,{root2}=/_1/" + $@"{escapedRoot1}=/_/,{escapedRoot2}=/_1/," }); AssertEx.AssertEqualToleratingWhitespaceDifferences( @@ -283,6 +286,48 @@ public void TestSourceLink() File.ReadAllText(sourceLinkJsonPath)); } + [ConditionalTheory(typeof(DotNetSdkAvailable))] + [CombinatorialData] + [WorkItem(43476, "https://github.com/dotnet/roslyn/issues/43476")] + public void InitializeSourceRootMappedPathsReturnsSourceMap(bool deterministicSourcePaths) + { + ProjectDir.CreateFile("Project2.csproj").WriteAllText($@" + + + netstandard2.0 + {deterministicSourcePaths} + + + + + + + +"); + + VerifyValues( + customProps: $@" + + + +", + customTargets: null, + targets: new[] + { + "ResolveProjectReferences;_BeforeVBCSCoreCompile" + }, + expressions: new[] + { + "@(ReferencedProjectSourceRoots)", + }, + expectedResults: new[] + { + @"X\", + @"Y\", + @"Z\", + }); + } + /// /// Validates dependencies of _BeforeVBCSCoreCompile target. /// diff --git a/src/Compilers/Core/Portable/CommandLine/CommandLineParser.cs b/src/Compilers/Core/Portable/CommandLine/CommandLineParser.cs index a02bea896691b..d7659ef138cd8 100644 --- a/src/Compilers/Core/Portable/CommandLine/CommandLineParser.cs +++ b/src/Compilers/Core/Portable/CommandLine/CommandLineParser.cs @@ -261,20 +261,27 @@ internal static void ParseAndNormalizeFile( protected ImmutableArray> ParsePathMap(string pathMap, IList errors) { - var pathMapBuilder = ArrayBuilder>.GetInstance(); if (pathMap.IsEmpty()) { - return pathMapBuilder.ToImmutableAndFree(); + return ImmutableArray>.Empty; } - foreach (var kEqualsV in pathMap.Split(',')) + var pathMapBuilder = ArrayBuilder>.GetInstance(); + + foreach (var kEqualsV in SplitWithDoubledSeparatorEscaping(pathMap, ',')) { - var kv = kEqualsV.Split('='); + if (kEqualsV.IsEmpty()) + { + continue; + } + + var kv = SplitWithDoubledSeparatorEscaping(kEqualsV, '='); if (kv.Length != 2) { errors.Add(Diagnostic.Create(_messageProvider, _messageProvider.ERR_InvalidPathMap, kEqualsV)); continue; } + var from = kv[0]; var to = kv[1]; @@ -293,6 +300,49 @@ protected ImmutableArray> ParsePathMap(string pathM return pathMapBuilder.ToImmutableAndFree(); } + /// + /// Splits specified on + /// treating two consecutive separators as if they were a single non-separating character. + /// E.g. "a,,b,c" split on ',' yields ["a,b", "c"]. + /// + internal static string[] SplitWithDoubledSeparatorEscaping(string str, char separator) + { + if (str.Length == 0) + { + return Array.Empty(); + } + + var result = ArrayBuilder.GetInstance(); + var pooledPart = PooledStringBuilder.GetInstance(); + var part = pooledPart.Builder; + + int i = 0; + while (i < str.Length) + { + char c = str[i++]; + if (c == separator) + { + if (i < str.Length && str[i] == separator) + { + i++; + } + else + { + result.Add(part.ToString()); + part.Clear(); + continue; + } + } + + part.Append(c); + } + + result.Add(part.ToString()); + + pooledPart.Free(); + return result.ToArrayAndFree(); + } + internal void ParseOutputFile( string value, IList errors, diff --git a/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb b/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb index 21ecf4858cbaf..1057b8dd663f6 100644 --- a/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb +++ b/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb @@ -3410,6 +3410,8 @@ print Goodbye, World" Public Sub PathMapParser() + Dim s = PathUtilities.DirectorySeparatorStr + Dim parsedArgs = DefaultParse({"/pathmap:", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify( Diagnostic(ERRID.WRN_BadSwitch).WithArguments("/pathmap:").WithLocation(1, 1) @@ -3418,23 +3420,28 @@ print Goodbye, World" parsedArgs = DefaultParse({"/pathmap:K1=V1", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify() - Assert.Equal(KeyValuePairUtil.Create("K1\", "V1\"), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("K1" & s, "V1" & s), parsedArgs.PathMap(0)) - parsedArgs = DefaultParse({"/pathmap:C:\goo\=/", "a.vb"}, _baseDirectory) + parsedArgs = DefaultParse({$"/pathmap:abc{s}=/", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify() - Assert.Equal(KeyValuePairUtil.Create("C:\goo\", "/"), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("abc" & s, "/"), parsedArgs.PathMap(0)) parsedArgs = DefaultParse({"/pathmap:K1=V1,K2=V2", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify() - Assert.Equal(KeyValuePairUtil.Create("K1\", "V1\"), parsedArgs.PathMap(0)) - Assert.Equal(KeyValuePairUtil.Create("K2\", "V2\"), parsedArgs.PathMap(1)) + Assert.Equal(KeyValuePairUtil.Create("K1" & s, "V1" & s), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("K2" & s, "V2" & s), parsedArgs.PathMap(1)) + + parsedArgs = DefaultParse({"/pathmap:,", "a.vb"}, _baseDirectory) + parsedArgs.Errors.Verify() + Assert.Equal(ImmutableArray.Create(Of KeyValuePair(Of String, String))(), parsedArgs.PathMap) + + parsedArgs = DefaultParse({"/pathmap:,,", "a.vb"}, _baseDirectory) + Assert.Equal(1, parsedArgs.Errors.Count()) + Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(0).Code) parsedArgs = DefaultParse({"/pathmap:,,,", "a.vb"}, _baseDirectory) - Assert.Equal(4, parsedArgs.Errors.Count()) + Assert.Equal(1, parsedArgs.Errors.Count()) Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(0).Code) - Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(1).Code) - Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(2).Code) - Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(3).Code) parsedArgs = DefaultParse({"/pathmap:k=,=v", "a.vb"}, _baseDirectory) Assert.Equal(2, parsedArgs.Errors.Count()) @@ -3445,19 +3452,32 @@ print Goodbye, World" Assert.Equal(1, parsedArgs.Errors.Count()) Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(0).Code) + parsedArgs = DefaultParse({"/pathmap:k=", "a.vb"}, _baseDirectory) + Assert.Equal(1, parsedArgs.Errors.Count()) + Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(0).Code) + + parsedArgs = DefaultParse({"/pathmap:=v", "a.vb"}, _baseDirectory) + Assert.Equal(1, parsedArgs.Errors.Count()) + Assert.Equal(ERRID.ERR_InvalidPathMap, parsedArgs.Errors(0).Code) + parsedArgs = DefaultParse({"/pathmap:""supporting spaces=is hard""", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify() - Assert.Equal(KeyValuePairUtil.Create("supporting spaces\", "is hard\"), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("supporting spaces" & s, "is hard" & s), parsedArgs.PathMap(0)) parsedArgs = DefaultParse({"/pathmap:""K 1=V 1"",""K 2=V 2""", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify() - Assert.Equal(KeyValuePairUtil.Create("K 1\", "V 1\"), parsedArgs.PathMap(0)) - Assert.Equal(KeyValuePairUtil.Create("K 2\", "V 2\"), parsedArgs.PathMap(1)) + Assert.Equal(KeyValuePairUtil.Create("K 1" & s, "V 1" & s), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("K 2" & s, "V 2" & s), parsedArgs.PathMap(1)) parsedArgs = DefaultParse({"/pathmap:""K 1""=""V 1"",""K 2""=""V 2""", "a.vb"}, _baseDirectory) parsedArgs.Errors.Verify() - Assert.Equal(KeyValuePairUtil.Create("K 1\", "V 1\"), parsedArgs.PathMap(0)) - Assert.Equal(KeyValuePairUtil.Create("K 2\", "V 2\"), parsedArgs.PathMap(1)) + Assert.Equal(KeyValuePairUtil.Create("K 1" & s, "V 1" & s), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("K 2" & s, "V 2" & s), parsedArgs.PathMap(1)) + + parsedArgs = DefaultParse({"/pathmap:""a ==,,b""=""1,,== 2"",""x ==,,y""=""3 4"",", "a.vb"}, _baseDirectory) + parsedArgs.Errors.Verify() + Assert.Equal(KeyValuePairUtil.Create("a =,b" & s, "1,= 2" & s), parsedArgs.PathMap(0)) + Assert.Equal(KeyValuePairUtil.Create("x =,y" & s, "3 4" & s), parsedArgs.PathMap(1)) End Sub ' PathMapKeepsCrossPlatformRoot and PathMapInconsistentSlashes should be in an @@ -3472,7 +3492,7 @@ print Goodbye, World" Public Sub PathMapKeepsCrossPlatformRoot(expectedFrom As String, expectedTo As String, sourceFrom As String, sourceTo As String) Dim pathmapArg = $"/pathmap:{sourceFrom}={sourceTo}" - Dim parsedArgs = VisualBasicCommandLineParser.Default.Parse({pathmapArg, "a.cs"}, TempRoot.Root, RuntimeEnvironment.GetRuntimeDirectory(), Nothing) + Dim parsedArgs = VisualBasicCommandLineParser.Default.Parse({pathmapArg, "a.vb"}, TempRoot.Root, RuntimeEnvironment.GetRuntimeDirectory(), Nothing) parsedArgs.Errors.Verify() Dim expected = New KeyValuePair(Of String, String)(expectedFrom, expectedTo) Assert.Equal(expected, parsedArgs.PathMap(0)) @@ -3486,9 +3506,9 @@ print Goodbye, World" Return parsedArgs End Function Dim sep = PathUtilities.DirectorySeparatorChar - Assert.Equal(New KeyValuePair(Of String, String)("C:\temp/goo" + sep, "/temp\goo" + sep), Parse({"/pathmap:C:\temp/goo=/temp\goo", "a.cs"}).PathMap(0)) - Assert.Equal(New KeyValuePair(Of String, String)("noslash" + sep, "withoutslash" + sep), Parse({"/pathmap:noslash=withoutslash", "a.cs"}).PathMap(0)) - Dim doublemap = Parse({"/pathmap:/temp=/goo,/temp/=/bar", "a.cs"}).PathMap + Assert.Equal(New KeyValuePair(Of String, String)("C:\temp/goo" + sep, "/temp\goo" + sep), Parse({"/pathmap:C:\temp/goo=/temp\goo", "a.vb"}).PathMap(0)) + Assert.Equal(New KeyValuePair(Of String, String)("noslash" + sep, "withoutslash" + sep), Parse({"/pathmap:noslash=withoutslash", "a.vb"}).PathMap(0)) + Dim doublemap = Parse({"/pathmap:/temp=/goo,/temp/=/bar", "a.vb"}).PathMap Assert.Equal(New KeyValuePair(Of String, String)("/temp/", "/goo/"), doublemap(0)) Assert.Equal(New KeyValuePair(Of String, String)("/temp/", "/bar/"), doublemap(1)) End Sub From af670dbc113376cdd0e3f5d9e0cb89fe272cb199 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Mon, 11 May 2020 20:23:56 -0700 Subject: [PATCH 146/222] Revert unused OptionsCollection in a test - this test does not use this options collection in master branch, but my prior commit in this PR attempted to use it in the test. This leads the test to fail, so I have restored the original semantics of the test and removed an unused local. --- src/Workspaces/CSharpTest/Formatting/FormattingTests.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs index 35d2a4912816d..f97336dad1f2a 100644 --- a/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs +++ b/src/Workspaces/CSharpTest/Formatting/FormattingTests.cs @@ -6468,11 +6468,6 @@ int M() [Trait(Traits.Feature, Traits.Features.Formatting)] public async Task QueryExpressionInExpression() { - var changingOptions = new OptionsCollection(LanguageNames.CSharp) - { - { CSharpFormattingOptions2.NewLinesForBracesInMethods, false } - }; - var code = @" class C { @@ -6523,7 +6518,7 @@ group t by t.Item1 into cat } } "; - await AssertFormatAsync(expected, code, changedOptionSet: changingOptions); + await AssertFormatAsync(expected, code); } [Fact] From 2668cf6ed331b394158cbad46ba72819391ec743 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Tue, 12 May 2020 10:28:09 +0100 Subject: [PATCH 147/222] Enforce parent type (as it was initially) --- .../VisualBasicInferredMemberNameSimplifier.vb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb index 75ac7b412bebc..8b33d095d911d 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Simplification/VisualBasicInferredMemberNameSimplifier.vb @@ -32,7 +32,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification End Function Friend Function CanSimplifyNamedFieldInitializer(node As NamedFieldInitializerSyntax) As Boolean - If node.Parent.IsParentKind(SyntaxKind.ObjectCreationExpression) OrElse RemovalCausesAmbiguity(DirectCast(node.Parent, ObjectMemberInitializerSyntax).Initializers, node) Then + Dim parentMemberInitializer As ObjectMemberInitializerSyntax = DirectCast(node.Parent, ObjectMemberInitializerSyntax) + + ' Spec requires explicit names for object creation expressions (unlike anonymous objects and tuples which can infer them) + Dim requiresExplicitNames = parentMemberInitializer.IsParentKind(SyntaxKind.ObjectCreationExpression) + If requiresExplicitNames OrElse RemovalCausesAmbiguity(parentMemberInitializer.Initializers, node) Then Return False End If From 86b9a7687dcad0fe60ffd2cc4651b48b9a11e1f7 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 10:55:06 -0700 Subject: [PATCH 148/222] Remove unnecessary value assignment --- .../Portable/MetadataAsSource/SymbolMappingServiceFactory.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs b/src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs index e5c577885a8f5..a1c5bf1e7bd2b 100644 --- a/src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs +++ b/src/Features/Core/Portable/MetadataAsSource/SymbolMappingServiceFactory.cs @@ -41,7 +41,6 @@ private sealed class SymbolMappingService : ISymbolMappingService public async Task MapSymbolAsync(Document document, ISymbol symbol, CancellationToken cancellationToken) { - var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); return await MapSymbolAsync(document, SymbolKey.Create(symbol, cancellationToken), cancellationToken).ConfigureAwait(false); } } From 8d37b6a3979147a55519b7ba2974f7ad70cb9613 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 12 May 2020 11:21:46 -0700 Subject: [PATCH 149/222] Avoid cancelling when not requested --- .../Core/Def/Packaging/PackageInstallerServiceFactory.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index ddee8232fb7dc..7b9b139a47136 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -118,8 +118,7 @@ public PackageInstallerService( } else if (allowSwitchToMainThread) { - using var combinedToken = _tokenSource.Token.CombineWith(cancellationToken); - return await packageSourcesAsync.JoinAsync(combinedToken.Token).ConfigureAwait(false); + return await packageSourcesAsync.JoinAsync(cancellationToken).ConfigureAwait(false); } else { From 241c5e6e16939dd1d2a2c7e9bf5fd7af2cc64a8d Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 12 May 2020 11:22:00 -0700 Subject: [PATCH 150/222] Simplify code --- .../PackageInstallerServiceFactory.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 7b9b139a47136..6cf902ecb9356 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -97,18 +97,15 @@ public PackageInstallerService( { // Only read from _packageSourcesAsync once, since OnSourceProviderSourcesChanged could reset it to default // at any time while this method is running. - var packageSourcesAsync = _packageSourcesAsync; - if (packageSourcesAsync is null) + JoinableTask> packageSourcesAsync; + lock (_gate) { - lock (_gate) + if (_packageSourcesAsync is null) { - if (_packageSourcesAsync is null) - { - _packageSourcesAsync = ThreadingContext.JoinableTaskFactory.RunAsync(() => GetPackageSourcesImplAsync()); - } - - packageSourcesAsync = _packageSourcesAsync; + _packageSourcesAsync = ThreadingContext.JoinableTaskFactory.RunAsync(() => GetPackageSourcesImplAsync()); } + + packageSourcesAsync = _packageSourcesAsync; } if (packageSourcesAsync.IsCompleted) @@ -136,15 +133,7 @@ private async Task> GetPackageSourcesImplAsync() var cancellationToken = _tokenSource.Token; try { - var result = await GetPackageSourcesImplAsync(cancellationToken).ConfigureAwait(false); - if (result.IsEmpty && cancellationToken.IsCancellationRequested) - { - // The failure may have been caused by a workspace change; try again after a short delay - await Task.Delay(TimeSpan.FromMilliseconds(250)).ConfigureAwait(false); - continue; - } - - return result; + return await GetPackageSourcesImplAsync(cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { From 931ff835d4dab3ca35896406cca2290ceeffc2bd Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 12 May 2020 11:30:08 -0700 Subject: [PATCH 151/222] Remove unnecessary coupling --- .../Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs index 1e2de6a05079c..1f16c720f0fbd 100644 --- a/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs +++ b/src/VisualStudio/Core/Def/Implementation/Library/ObjectBrowser/Extensions.cs @@ -62,7 +62,7 @@ public static string GetProjectDisplayName(this Project project) { return project.Name; } - else if (project.Solution.Workspace is VisualStudioWorkspaceImpl workspace + else if (project.Solution.Workspace is VisualStudioWorkspace workspace && workspace.GetHierarchy(project.Id) is { } hierarchy && (IVsSolution3)ServiceProvider.GlobalProvider.GetService(typeof(SVsSolution)) is { } solution) { From 6f0788dae6b974c5de7b48ca57a9940aeeab73bc Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Tue, 12 May 2020 12:54:03 -0700 Subject: [PATCH 152/222] Fix stopwatch usage --- src/Tools/AnalyzerRunner/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tools/AnalyzerRunner/Program.cs b/src/Tools/AnalyzerRunner/Program.cs index cbacc400be242..f35d8a6b69ff6 100644 --- a/src/Tools/AnalyzerRunner/Program.cs +++ b/src/Tools/AnalyzerRunner/Program.cs @@ -83,6 +83,8 @@ public static async Task Main(string[] args) } } + Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); + if (options.ShowStats) { stopwatch = PerformanceTracker.StartNew(); @@ -90,8 +92,6 @@ public static async Task Main(string[] args) Console.WriteLine($"Statistics gathered in {stopwatch.GetSummary(preciseMemory: true)}"); } - Console.WriteLine($"Loaded solution in {stopwatch.GetSummary(preciseMemory: true)}"); - if (options.ShowCompilerDiagnostics) { await ShowCompilerDiagnosticsAsync(workspace.CurrentSolution, cancellationToken).ConfigureAwait(false); From 8c87ee2dc8c3f87a47058dd38797eb576629e7af Mon Sep 17 00:00:00 2001 From: Chris Sienkiewicz Date: Tue, 12 May 2020 13:04:17 -0700 Subject: [PATCH 153/222] Convert a couple of PROTOTYPE comments that crept in via source generators (#44165) --- .../LanguageServices/CSharpCompilationFactoryService.cs | 2 +- ...pilationAndGeneratorDriverTranslationAction_Actions.cs | 8 ++++---- .../Solution/SolutionState.CompilationTracker.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Workspaces/CSharp/Portable/Workspace/LanguageServices/CSharpCompilationFactoryService.cs b/src/Workspaces/CSharp/Portable/Workspace/LanguageServices/CSharpCompilationFactoryService.cs index 1a036b5a60c00..22b4948d939cd 100644 --- a/src/Workspaces/CSharp/Portable/Workspace/LanguageServices/CSharpCompilationFactoryService.cs +++ b/src/Workspaces/CSharp/Portable/Workspace/LanguageServices/CSharpCompilationFactoryService.cs @@ -44,7 +44,7 @@ CompilationOptions ICompilationFactoryService.GetDefaultCompilationOptions() GeneratorDriver? ICompilationFactoryService.CreateGeneratorDriver(ParseOptions parseOptions, ImmutableArray generators, ImmutableArray additionalTexts) { - // PROTOTYPE: for now we gate behind langver == preview. We'll remove this before final shipping, as the feature is langver agnostic + // https://github.com/dotnet/roslyn/issues/42565: for now we gate behind langver == preview. We'll remove this before final shipping, as the feature is langver agnostic if (((CSharpParseOptions)parseOptions).LanguageVersion != LanguageVersion.Preview) { return null; diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationAndGeneratorDriverTranslationAction_Actions.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationAndGeneratorDriverTranslationAction_Actions.cs index b49a08b66c0a7..0adf260ccb162 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationAndGeneratorDriverTranslationAction_Actions.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationAndGeneratorDriverTranslationAction_Actions.cs @@ -168,7 +168,7 @@ public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGenerator internal sealed class AddAdditionalDocumentsAction : CompilationAndGeneratorDriverTranslationAction { #pragma warning disable IDE0052 // Remove unread private members - // PROTOTYPE: right now there is no way to tell a GeneratorDriver that an additional file has been added + // https://github.com/dotnet/roslyn/issues/44161: right now there is no way to tell a GeneratorDriver that an additional file has been added private readonly ImmutableArray _additionalDocuments; #pragma warning restore IDE0052 // Remove unread private members @@ -179,7 +179,7 @@ public AddAdditionalDocumentsAction(ImmutableArray additional public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGeneratorDriver generatorDriver) { - // PROTOTYPE: right now there is no way to tell a GeneratorDriver that an additional file has been added + // https://github.com/dotnet/roslyn/issues/44161: right now there is no way to tell a GeneratorDriver that an additional file has been added // to allow for incremental updates: our only option is to recreate the generator driver from scratch. // return generatorDriver.WithPendingEdits(_additionalDocuments.SelectAsArray(a => (PendingEdit)new AdditionalFileAddedEdit(new AdditionalTextWithState(a)))); return new TrackedGeneratorDriver(generatorDriver: null); @@ -189,7 +189,7 @@ public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGenerator internal sealed class RemoveAdditionalDocumentsAction : CompilationAndGeneratorDriverTranslationAction { #pragma warning disable IDE0052 // Remove unread private members - // PROTOTYPE: right now there is no way to tell a GeneratorDriver that an additional file has been added + // https://github.com/dotnet/roslyn/issues/44161: right now there is no way to tell a GeneratorDriver that an additional file has been added private readonly ImmutableArray _additionalDocuments; #pragma warning restore IDE0052 // Remove unread private members @@ -200,7 +200,7 @@ public RemoveAdditionalDocumentsAction(ImmutableArray additio public override TrackedGeneratorDriver TransformGeneratorDriver(TrackedGeneratorDriver generatorDriver) { - // PROTOTYPE: right now there is no way to tell a GeneratorDriver that an additional file has been removed + // https://github.com/dotnet/roslyn/issues/44161: right now there is no way to tell a GeneratorDriver that an additional file has been removed // to allow for incremental updates: our only option is to recreate the generator driver from scratch. // return generatorDriver.WithPendingEdits(_additionalDocuments.SelectAsArray(a => (PendingEdit)new AdditionalFileRemovedEdit(...))); return new TrackedGeneratorDriver(generatorDriver: null); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs index f7b07aa8049fc..24b38080a34c7 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.CompilationTracker.cs @@ -709,7 +709,7 @@ private async Task FinalizeCompilationAsync( if (generatorDriver.GeneratorDriver != null) { - // PROTOTYPE: make an API to expose these diagnostics + // https://github.com/dotnet/roslyn/issues/44163: make an API to expose these diagnostics generatorDriver = new TrackedGeneratorDriver(generatorDriver.GeneratorDriver.RunFullGeneration(compilation, out compilation, out var diagnostics, cancellationToken)); } From c7f5584d4d9b287459e03aa12bdd86e7e6416bcd Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 12 May 2020 13:26:38 -0700 Subject: [PATCH 154/222] Use named tuple elements --- .../Engine/Trivia/TriviaRewriter.cs | 12 +++--- .../CSharp/Formatting/FormattingHelpers.cs | 18 ++++----- .../Formatting/Rules/BaseFormattingRule.cs | 7 ++-- .../Rules/ElasticTriviaFormattingRule.cs | 4 +- .../Rules/IndentBlockFormattingRule.cs | 6 +-- .../Rules/SuppressFormattingRule.cs | 6 +-- .../Rules/WrappingFormattingRule.cs | 37 +++++++++---------- .../CSharp/Utilities/FormattingRangeHelper.cs | 4 +- .../Formatting/Engine/AbstractFormatEngine.cs | 8 ++-- .../Formatting/Engine/TokenStream.Iterator.cs | 16 ++++---- .../Core/Formatting/Engine/TokenStream.cs | 2 +- 11 files changed, 58 insertions(+), 62 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Engine/Trivia/TriviaRewriter.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Engine/Trivia/TriviaRewriter.cs index 1c7ce3c5f95ff..0012279bc8574 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Engine/Trivia/TriviaRewriter.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Engine/Trivia/TriviaRewriter.cs @@ -57,28 +57,28 @@ private void PreprocessTriviaListMap( { cancellationToken.ThrowIfCancellationRequested(); - var tuple = GetTrailingAndLeadingTrivia(pair, cancellationToken); + var (trailingTrivia, leadingTrivia) = GetTrailingAndLeadingTrivia(pair, cancellationToken); if (pair.Key.Item1.RawKind != 0) { - _trailingTriviaMap.Add(pair.Key.Item1, tuple.Item1); + _trailingTriviaMap.Add(pair.Key.Item1, trailingTrivia); } if (pair.Key.Item2.RawKind != 0) { - _leadingTriviaMap.Add(pair.Key.Item2, tuple.Item2); + _leadingTriviaMap.Add(pair.Key.Item2, leadingTrivia); } } } - private ValueTuple GetTrailingAndLeadingTrivia( + private (SyntaxTriviaList trailingTrivia, SyntaxTriviaList leadingTrivia) GetTrailingAndLeadingTrivia( KeyValuePair, TriviaData> pair, CancellationToken cancellationToken) { if (pair.Key.Item1.RawKind == 0) { - return ValueTuple.Create(default(SyntaxTriviaList), GetLeadingTriviaAtBeginningOfTree(pair.Key, pair.Value, cancellationToken)); + return (default(SyntaxTriviaList), GetLeadingTriviaAtBeginningOfTree(pair.Key, pair.Value, cancellationToken)); } if (pair.Value is TriviaDataWithList csharpTriviaData) @@ -98,7 +98,7 @@ private ValueTuple GetTrailingAndLeadingTriv var width = trailingTrivia.GetFullWidth(); var leadingTrivia = SyntaxFactory.ParseLeadingTrivia(text.Substring(width)); - return ValueTuple.Create(trailingTrivia, leadingTrivia); + return (trailingTrivia, leadingTrivia); } private TextSpan GetTextSpan(ValueTuple pair) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs index 08d8338c16ff9..a7c0c277e5529 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/FormattingHelpers.cs @@ -47,14 +47,14 @@ public static string ContentBeforeLastNewLine(this IEnumerable tri return leading.Substring(0, lastNewLinePos); } - public static ValueTuple GetBracePair(this SyntaxNode node) + public static (SyntaxToken openBrace, SyntaxToken closeBrace) GetBracePair(this SyntaxNode node) => node.GetBraces(); - public static bool IsValidBracePair(this ValueTuple bracePair) + public static bool IsValidBracePair(this (SyntaxToken openBrace, SyntaxToken closeBrace) bracePair) { - if (bracePair.Item1.IsKind(SyntaxKind.None) || - bracePair.Item1.IsMissing || - bracePair.Item2.IsKind(SyntaxKind.None)) + if (bracePair.openBrace.IsKind(SyntaxKind.None) || + bracePair.openBrace.IsMissing || + bracePair.closeBrace.IsKind(SyntaxKind.None)) { return false; } @@ -473,7 +473,7 @@ public static bool IsLastTokenInLabelStatement(this SyntaxToken token) return token.Parent.Parent is LabeledStatementSyntax; } - public static ValueTuple GetFirstAndLastMemberDeclarationTokensAfterAttributes(this MemberDeclarationSyntax node) + public static (SyntaxToken firstToken, SyntaxToken lastToken) GetFirstAndLastMemberDeclarationTokensAfterAttributes(this MemberDeclarationSyntax node) { Contract.ThrowIfNull(node); @@ -481,20 +481,20 @@ public static ValueTuple GetFirstAndLastMemberDeclarat var attributes = node.GetAttributes(); if (attributes.Count == 0) { - return ValueTuple.Create(node.GetFirstToken(includeZeroWidth: true), node.GetLastToken(includeZeroWidth: true)); + return (node.GetFirstToken(includeZeroWidth: true), node.GetLastToken(includeZeroWidth: true)); } var lastToken = node.GetLastToken(includeZeroWidth: true); var lastAttributeToken = attributes.Last().GetLastToken(includeZeroWidth: true); if (lastAttributeToken.Equals(lastToken)) { - return ValueTuple.Create(default(SyntaxToken), default(SyntaxToken)); + return default; } var firstTokenAfterAttribute = lastAttributeToken.GetNextToken(includeZeroWidth: true); // there are attributes, get first token after the tokens belong to attributes - return ValueTuple.Create(firstTokenAfterAttribute, lastToken); + return (firstTokenAfterAttribute, lastToken); } public static bool IsBlockBody(this SyntaxNode node) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs index 85a296e16e284..ba71a718dacc7 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/BaseFormattingRule.cs @@ -172,8 +172,7 @@ protected void AddBraceSuppressOperations(List list, SyntaxNo if (node is MemberDeclarationSyntax memberDeclNode) { - var firstAndLastTokens = memberDeclNode.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); - firstTokenOfNode = firstAndLastTokens.Item1; + (firstTokenOfNode, _) = memberDeclNode.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); } if (node.IsLambdaBodyBlock()) @@ -191,8 +190,8 @@ protected void AddBraceSuppressOperations(List list, SyntaxNo // suppress wrapping on whole construct that owns braces and also brace pair itself if // it is on same line - AddSuppressWrappingIfOnSingleLineOperation(list, firstTokenOfNode, bracePair.Item2); - AddSuppressWrappingIfOnSingleLineOperation(list, bracePair.Item1, bracePair.Item2); + AddSuppressWrappingIfOnSingleLineOperation(list, firstTokenOfNode, bracePair.closeBrace); + AddSuppressWrappingIfOnSingleLineOperation(list, bracePair.openBrace, bracePair.closeBrace); } } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/ElasticTriviaFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/ElasticTriviaFormattingRule.cs index 3b39243bee38f..5450e5d75ff11 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/ElasticTriviaFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/ElasticTriviaFormattingRule.cs @@ -42,9 +42,9 @@ private static void AddPropertyDeclarationSuppressOperations(List a.Body == null) && basePropertyDeclaration.GetAnnotatedTrivia(SyntaxAnnotation.ElasticAnnotation).Any()) { - var tokens = basePropertyDeclaration.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); + var (firstToken, lastToken) = basePropertyDeclaration.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); - list.Add(FormattingOperations.CreateSuppressOperation(tokens.Item1, tokens.Item2, SuppressOption.NoWrapping | SuppressOption.IgnoreElasticWrapping)); + list.Add(FormattingOperations.CreateSuppressOperation(firstToken, lastToken, SuppressOption.NoWrapping | SuppressOption.IgnoreElasticWrapping)); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs index fd39a9a96a374..e4f06d44fabd2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/IndentBlockFormattingRule.cs @@ -233,13 +233,13 @@ private void AddBlockIndentationOperation(List list, Synta return; } - AddIndentBlockOperation(list, bracePair.Item1.GetNextToken(includeZeroWidth: true), bracePair.Item2.GetPreviousToken(includeZeroWidth: true)); + AddIndentBlockOperation(list, bracePair.openBrace.GetNextToken(includeZeroWidth: true), bracePair.closeBrace.GetPreviousToken(includeZeroWidth: true)); } - private void AddAlignmentBlockOperationRelativeToFirstTokenOnBaseTokenLine(List list, ValueTuple bracePair) + private void AddAlignmentBlockOperationRelativeToFirstTokenOnBaseTokenLine(List list, (SyntaxToken openBrace, SyntaxToken closeBrace) bracePair) { var option = IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine; - SetAlignmentBlockOperation(list, bracePair.Item1, bracePair.Item1.GetNextToken(includeZeroWidth: true), bracePair.Item2, option); + SetAlignmentBlockOperation(list, bracePair.openBrace, bracePair.openBrace.GetNextToken(includeZeroWidth: true), bracePair.closeBrace, option); } private void AddEmbeddedStatementsIndentationOperation(List list, SyntaxNode node) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs index 231b4b1aea822..6911279eb30f8 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/SuppressFormattingRule.cs @@ -150,8 +150,8 @@ private void AddSpecificNodesSuppressOperations(List list, Sy { // Attempt to keep the part of a member that follows the attributes on a single // line if that's how it's currently written. - var tokens = memberDeclNode.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); - AddSuppressWrappingIfOnSingleLineOperation(list, tokens.Item1, tokens.Item2); + var (firstToken, lastToken) = memberDeclNode.GetFirstAndLastMemberDeclarationTokensAfterAttributes(); + AddSuppressWrappingIfOnSingleLineOperation(list, firstToken, lastToken); // Also, If the member is on single line with its attributes on it, then keep // it on a single line. This is for code like the following: @@ -170,7 +170,7 @@ private void AddSpecificNodesSuppressOperations(List list, Sy var propertyDeclNode = node as PropertyDeclarationSyntax; if (propertyDeclNode?.Initializer != null && propertyDeclNode?.AccessorList != null) { - AddSuppressWrappingIfOnSingleLineOperation(list, tokens.Item1, propertyDeclNode.AccessorList.GetLastToken()); + AddSuppressWrappingIfOnSingleLineOperation(list, firstToken, propertyDeclNode.AccessorList.GetLastToken()); } return; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/WrappingFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/WrappingFormattingRule.cs index 9dc5310dd3408..dc2d2768784a1 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/WrappingFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/WrappingFormattingRule.cs @@ -63,40 +63,37 @@ public override void AddSuppressOperations(List list, SyntaxN } } - private ValueTuple GetSpecificNodeSuppressionTokenRange(SyntaxNode node) + private (SyntaxToken firstToken, SyntaxToken lastToken) GetSpecificNodeSuppressionTokenRange(SyntaxNode node) { var embeddedStatement = node.GetEmbeddedStatement(); if (embeddedStatement != null) { var firstTokenOfEmbeddedStatement = embeddedStatement.GetFirstToken(includeZeroWidth: true); + var firstToken = firstTokenOfEmbeddedStatement.GetPreviousToken(includeZeroWidth: true); if (embeddedStatement.IsKind(SyntaxKind.Block)) { - return ValueTuple.Create( - firstTokenOfEmbeddedStatement.GetPreviousToken(includeZeroWidth: true), - embeddedStatement.GetLastToken(includeZeroWidth: true)); + return (firstToken, embeddedStatement.GetLastToken(includeZeroWidth: true)); } else { - return ValueTuple.Create( - firstTokenOfEmbeddedStatement.GetPreviousToken(includeZeroWidth: true), - firstTokenOfEmbeddedStatement); + return (firstToken, firstTokenOfEmbeddedStatement); } } return node switch { - SwitchSectionSyntax switchSection => ValueTuple.Create(switchSection.GetFirstToken(includeZeroWidth: true), switchSection.GetLastToken(includeZeroWidth: true)), - AnonymousMethodExpressionSyntax anonymousMethod => ValueTuple.Create(anonymousMethod.DelegateKeyword, anonymousMethod.GetLastToken(includeZeroWidth: true)), + SwitchSectionSyntax switchSection => (switchSection.GetFirstToken(includeZeroWidth: true), switchSection.GetLastToken(includeZeroWidth: true)), + AnonymousMethodExpressionSyntax anonymousMethod => (anonymousMethod.DelegateKeyword, anonymousMethod.GetLastToken(includeZeroWidth: true)), _ => default, }; } private void AddSpecificNodesSuppressOperations(List list, SyntaxNode node) { - var tokens = GetSpecificNodeSuppressionTokenRange(node); - if (!tokens.Equals(default)) + var (firstToken, lastToken) = GetSpecificNodeSuppressionTokenRange(node); + if (!firstToken.IsKind(SyntaxKind.None) || !lastToken.IsKind(SyntaxKind.None)) { - AddSuppressWrappingIfOnSingleLineOperation(list, tokens.Item1, tokens.Item2); + AddSuppressWrappingIfOnSingleLineOperation(list, firstToken, lastToken); } } @@ -124,9 +121,9 @@ private void RemoveSuppressOperationForStatementMethodDeclaration(List list, Synta } // suppress wrapping on whole construct that owns braces and also brace pair itself if it is on same line - RemoveSuppressOperation(list, firstTokenOfNode, bracePair.Item2); - RemoveSuppressOperation(list, bracePair.Item1, bracePair.Item2); + RemoveSuppressOperation(list, firstTokenOfNode, bracePair.closeBrace); + RemoveSuppressOperation(list, bracePair.openBrace, bracePair.closeBrace); } - private ValueTuple GetBracePair(SyntaxNode node) + private (SyntaxToken openBrace, SyntaxToken closeBrace) GetBracePair(SyntaxNode node) { if (node is BaseMethodDeclarationSyntax methodDeclaration && methodDeclaration.Body != null) { - return ValueTuple.Create(methodDeclaration.Body.OpenBraceToken, methodDeclaration.Body.CloseBraceToken); + return (methodDeclaration.Body.OpenBraceToken, methodDeclaration.Body.CloseBraceToken); } if (node is PropertyDeclarationSyntax propertyDeclaration && propertyDeclaration.AccessorList != null) { - return ValueTuple.Create(propertyDeclaration.AccessorList.OpenBraceToken, propertyDeclaration.AccessorList.CloseBraceToken); + return (propertyDeclaration.AccessorList.OpenBraceToken, propertyDeclaration.AccessorList.CloseBraceToken); } if (node is AccessorDeclarationSyntax accessorDeclaration && accessorDeclaration.Body != null) { - return ValueTuple.Create(accessorDeclaration.Body.OpenBraceToken, accessorDeclaration.Body.CloseBraceToken); + return (accessorDeclaration.Body.OpenBraceToken, accessorDeclaration.Body.CloseBraceToken); } return node.GetBracePair(); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs index 46746c6c8df4d..0a414ebc56fff 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/FormattingRangeHelper.cs @@ -38,8 +38,8 @@ internal static class FormattingRangeHelper while (currentToken.Kind() != SyntaxKind.CloseBraceToken && previousToken.Kind() == SyntaxKind.OpenBraceToken) { - var pair = previousToken.Parent.GetBracePair(); - if (pair.Item2.Kind() == SyntaxKind.None || !AreTwoTokensOnSameLine(previousToken, pair.Item2)) + var (_, closeBrace) = previousToken.Parent.GetBracePair(); + if (closeBrace.Kind() == SyntaxKind.None || !AreTwoTokensOnSameLine(previousToken, closeBrace)) { return ValueTuple.Create(currentToken, tokenRange.Value.Item2); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/AbstractFormatEngine.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/AbstractFormatEngine.cs index 2e0c818c416ae..c3a614e84d438 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/AbstractFormatEngine.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/AbstractFormatEngine.cs @@ -209,14 +209,14 @@ private TokenPairWithOperations[] CreateTokenOperation( // pre-allocate list once. this is cheaper than re-adjusting list as items are added. var list = new TokenPairWithOperations[tokenStream.TokenCount - 1]; - foreach (var pair in tokenStream.TokenIterator) + foreach (var (index, currentToken, nextToken) in tokenStream.TokenIterator) { cancellationToken.ThrowIfCancellationRequested(); - var spaceOperation = _formattingRules.GetAdjustSpacesOperation(pair.Item2, pair.Item3); - var lineOperation = _formattingRules.GetAdjustNewLinesOperation(pair.Item2, pair.Item3); + var spaceOperation = _formattingRules.GetAdjustSpacesOperation(currentToken, nextToken); + var lineOperation = _formattingRules.GetAdjustNewLinesOperation(currentToken, nextToken); - list[pair.Item1] = new TokenPairWithOperations(tokenStream, pair.Item1, spaceOperation, lineOperation); + list[index] = new TokenPairWithOperations(tokenStream, index, spaceOperation, lineOperation); } return list; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Iterator.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Iterator.cs index f87e337d5b228..6ed5ef6e5cb7f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Iterator.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.Iterator.cs @@ -13,25 +13,25 @@ internal partial class TokenStream { // gain of having hand written iterator seems about 50-100ms over auto generated one. // not sure whether it is worth it. but I already wrote it to test, so going to just keep it. - private class Iterator : IEnumerable> + private class Iterator : IEnumerable<(int index, SyntaxToken currentToken, SyntaxToken nextToken)> { private readonly List _tokensIncludingZeroWidth; public Iterator(List tokensIncludingZeroWidth) => _tokensIncludingZeroWidth = tokensIncludingZeroWidth; - public IEnumerator> GetEnumerator() + public IEnumerator<(int index, SyntaxToken currentToken, SyntaxToken nextToken)> GetEnumerator() => new Enumerator(_tokensIncludingZeroWidth); System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); - private struct Enumerator : IEnumerator> + private struct Enumerator : IEnumerator<(int index, SyntaxToken currentToken, SyntaxToken nextToken)> { private readonly List _tokensIncludingZeroWidth; private readonly int _maxCount; - private ValueTuple _current; + private (int index, SyntaxToken currentToken, SyntaxToken nextToken) _current; private int _index; public Enumerator(List tokensIncludingZeroWidth) @@ -40,7 +40,7 @@ public Enumerator(List tokensIncludingZeroWidth) _maxCount = _tokensIncludingZeroWidth.Count - 1; _index = 0; - _current = new ValueTuple(); + _current = default; } public void Dispose() @@ -51,7 +51,7 @@ public bool MoveNext() { if (_index < _maxCount) { - _current = ValueTuple.Create(_index, _tokensIncludingZeroWidth[_index], _tokensIncludingZeroWidth[_index + 1]); + _current = (_index, _tokensIncludingZeroWidth[_index], _tokensIncludingZeroWidth[_index + 1]); _index++; return true; } @@ -62,11 +62,11 @@ public bool MoveNext() private bool MoveNextRare() { _index = _maxCount + 1; - _current = new ValueTuple(); + _current = default; return false; } - public ValueTuple Current => _current; + public (int index, SyntaxToken currentToken, SyntaxToken nextToken) Current => _current; object System.Collections.IEnumerator.Current { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.cs index 896b609f5e6ec..9f8b9689385f9 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/Engine/TokenStream.cs @@ -551,7 +551,7 @@ private int GetTokenIndexInStream(SyntaxToken token) return -1; } - public IEnumerable> TokenIterator + public IEnumerable<(int index, SyntaxToken currentToken, SyntaxToken nextToken)> TokenIterator { get { From d5c46274854f42389ce1acb098740e1253f3412b Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 12 May 2020 14:38:56 -0700 Subject: [PATCH 155/222] Use stronger types in the formatter --- .../Rules/AnchorIndentationFormattingRule.cs | 2 +- .../Formatting/Rules/IndentBlockFormattingRule.cs | 11 ++--------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/AnchorIndentationFormattingRule.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/AnchorIndentationFormattingRule.cs index eea37402aec5c..51f9d0ba84632 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/AnchorIndentationFormattingRule.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Formatting/Rules/AnchorIndentationFormattingRule.cs @@ -68,7 +68,7 @@ public override void AddAnchorIndentationOperations(List list, SyntaxN case ImplicitArrayCreationExpressionSyntax implicitArrayCreation when implicitArrayCreation.Initializer != null: SetAlignmentBlockOperation(list, implicitArrayCreation.NewKeyword, implicitArrayCreation.Initializer.OpenBraceToken, implicitArrayCreation.Initializer.CloseBraceToken, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine); return; - case CSharpSyntaxNode syntaxNode when syntaxNode.IsKind(SyntaxKind.SwitchExpression): - SetAlignmentBlockOperation( - list, - syntaxNode.GetFirstToken(), - syntaxNode.ChildNodesAndTokens().First(child => child.IsKind(SyntaxKind.OpenBraceToken)).AsToken(), - syntaxNode.ChildNodesAndTokens().Last(child => child.IsKind(SyntaxKind.CloseBraceToken)).AsToken(), - IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine); + case SwitchExpressionSyntax switchExpression: + SetAlignmentBlockOperation(list, switchExpression.GetFirstToken(), switchExpression.OpenBraceToken, switchExpression.CloseBraceToken, IndentBlockOption.RelativeToFirstTokenOnBaseTokenLine); return; } } From 5bd1f86c5d57dbc9dcb53d7c948caaa554fc0b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sharma?= Date: Tue, 12 May 2020 15:06:58 -0700 Subject: [PATCH 156/222] Fix example (#43910) The snippet's curly braces should be escaped due to the `$`. The `$` isn't actually necessary, so I removed it. --- docs/features/source-generators.cookbook.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/source-generators.cookbook.md b/docs/features/source-generators.cookbook.md index 705a62217d660..97f635e5323ab 100644 --- a/docs/features/source-generators.cookbook.md +++ b/docs/features/source-generators.cookbook.md @@ -90,7 +90,7 @@ public class CustomGenerator : ISourceGenerator public void Execute(SourceGeneratorContext context) { - context.AddSource("myGeneratedFile.cs", SourceText.From($@" + context.AddSource("myGeneratedFile.cs", SourceText.From(@" namespace GeneratedNamespace { public class GeneratedClass From 2552aa4640cbff1ea9bf4674a318d5dec14cd7c6 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 15:16:35 -0700 Subject: [PATCH 157/222] [Dogfooding] Enforce IDE0060 (Remove unused parameter) as build warning in IDE projects ``` # IDE0060: Remove unused parameter dotnet_diagnostic.IDE0060.severity = warning ``` --- .editorconfig | 3 + ...aryPatternParenthesesDiagnosticAnalyzer.cs | 6 +- ...veUnnecessaryParenthesesCodeFixProvider.cs | 2 +- .../AbstractUseAutoPropertyAnalyzer.cs | 4 +- .../Core/Analyzers/Options/AnalyzerHelper.cs | 4 ++ .../GenerateType/GenerateTypeTests.cs | 3 +- .../GenerateConstructorTests.cs | 4 +- ...ddConstructorParametersFromMembersTests.cs | 8 +-- .../GenerateConstructorFromMembersTests.cs | 10 ++-- .../InitializeMemberFromParameterTests.cs | 28 +++++----- .../AbstractCodeActionOrUserDiagnosticTest.cs | 5 +- ...DiagnosticTest.FixAllDiagnosticProvider.cs | 6 +- .../Diagnostics/AbstractUserDiagnosticTest.cs | 1 - .../NamingStylesTestOptionSets.cs | 2 +- ...cEmbeddedLanguageEditorFeaturesProvider.vb | 2 +- .../GenerateConstructorTests.vb | 2 +- .../CrefCompletionProvider.cs | 5 +- .../WhenKeywordRecommender.cs | 2 +- ...harpMethodExtractor.CSharpCodeGenerator.cs | 3 +- .../CSharpGenerateConversionService.cs | 2 - .../AbstractCSharpSignatureHelpProvider.cs | 4 +- ...ractOrdinaryMethodSignatureHelpProvider.cs | 6 +- .../AttributeSignatureHelpProvider.cs | 2 +- ...tructorInitializerSignatureHelpProvider.cs | 11 ++-- ...ntAccessExpressionSignatureHelpProvider.cs | 15 +++-- .../GenericNameSignatureHelpProvider.cs | 19 +++---- ...ericNameSignatureHelpProvider_NamedType.cs | 2 +- ...tializerExpressionSignatureHelpProvider.cs | 2 +- ...onSignatureHelpProviderBase_MethodGroup.cs | 2 +- ...CreationExpressionSignatureHelpProvider.cs | 2 +- ...ssionSignatureHelpProvider_DelegateType.cs | 12 ++-- ...ressionSignatureHelpProvider_NormalType.cs | 11 ++-- ...xpressionBodyForLambdaCodeStyleProvider.cs | 2 +- .../MetadataSymbolsSearchScope.cs | 2 +- .../AbstractAddParameterCodeFixProvider.cs | 5 +- ...r.GlobalSuppressMessageFixAllCodeAction.cs | 4 +- ...ider.RemoveSuppressionCodeAction_Pragma.cs | 4 +- ...AbstractPartialMethodCompletionProvider.cs | 4 +- ...vertForEachToForCodeRefactoringProvider.cs | 20 +++---- .../Portable/Diagnostics/AnalyzerHelper.cs | 2 + ...crementalAnalyzer_GetDiagnosticsForSpan.cs | 25 +++++---- ...ctDocumentationCommentFormattingService.cs | 6 +- .../LanguageServices/RegexPatternDetector.cs | 15 ++--- .../RegularExpressions/RegexCharClass.cs | 4 +- .../Pythia/Api/PythiaSymbolSorting.cs | 2 + .../AbstractExtractInterfaceService.cs | 6 +- .../ExtractInterfaceTypeAnalysisResult.cs | 1 - .../ExtractMethod/ExtractMethodMatrix.cs | 1 - .../ExtractMethod/MethodExtractor.Analyzer.cs | 2 +- .../MethodExtractor.CodeGenerator.cs | 2 +- .../AbstractGenerateMemberService.cs | 1 - ...stractGenerateConstructorService.Editor.cs | 2 +- ...AbstractGenerateEnumMemberService.State.cs | 3 +- ...zedMemberService.AbstractInvocationInfo.cs | 5 +- ...arameterizedMemberService.SignatureInfo.cs | 7 +-- ...enerateParameterizedMemberService.State.cs | 3 +- .../AbstractGenerateVariableService.State.cs | 3 +- .../AbstractGenerateTypeService.Editor.cs | 8 --- ...ctGenerateTypeService.GenerateNamedType.cs | 12 ++-- .../AbstractGenerateTypeService.cs | 4 +- ...actImplementInterfaceService.CodeAction.cs | 17 +++--- ...entInterfaceService.CodeAction_Property.cs | 4 +- ...erCodeRefactoringProviderMemberCreation.cs | 4 +- .../AbstractMetadataAsSourceService.cs | 4 +- .../Navigation/NavigableItemFactory.cs | 12 ---- .../Portable/PullMemberUp/MembersPuller.cs | 7 +-- .../CommonSemanticQuickInfoProvider.cs | 3 +- ...thodWithPropertyCodeRefactoringProvider.cs | 2 + ...pertyWithMethodsCodeRefactoringProvider.cs | 2 + .../AbstractSignatureHelpProvider.cs | 4 +- .../SolutionCrawler/SolutionCrawlerLogger.cs | 4 +- .../BlockStructureServiceWithProviders.cs | 6 +- .../GeneratorTest/CompilerInvocationTests.vb | 2 + .../VisualBasicChangeSignatureService.vb | 3 +- .../VisualBasicAddAwaitCodeFixProvider.vb | 8 +-- .../IncorrectExitContinueCodeFixProvider.vb | 4 +- ...orrectFunctionReturnTypeCodeFixProvider.vb | 6 +- .../CrefCompletionProvider.vb | 9 ++- .../HandlesClauseCompletionProvider.vb | 18 +----- ...ExtensionMethodImportCompletionProvider.vb | 2 +- .../ImportCompletionProviderHelper.vb | 2 +- .../TypeImportCompletionProvider.vb | 2 +- .../RecommendationHelpers.vb | 5 -- .../EditAndContinue/BreakpointSpans.vb | 4 +- .../VisualBasicEditAndContinueAnalyzer.vb | 6 +- .../EmbeddedLanguageUtilities.vb | 2 +- ...alBasicEmbeddedLanguageFeaturesProvider.vb | 2 +- ...ethodExtractor.VisualBasicCodeGenerator.vb | 3 +- ...VisualBasicSelectionValidator.Validator.vb | 4 +- .../VisualBasicSelectionValidator.vb | 4 +- .../VisualBasicGenerateConversionService.vb | 4 +- ...BasicGenerateParameterizedMemberService.vb | 5 +- .../VisualBasicGenerateTypeService.vb | 2 +- ...IntroduceVariableService_IntroduceLocal.vb | 3 +- ...alBasicReplaceMethodWithPropertyService.vb | 3 +- ...ractOrdinaryMethodSignatureHelpProvider.vb | 6 +- ...bstractVisualBasicSignatureHelpProvider.vb | 3 +- .../AttributeSignatureHelpProvider.vb | 16 +++--- ...lectionInitializerSignatureHelpProvider.vb | 2 +- ...unctionAggregationSignatureHelpProvider.vb | 13 ++--- ...ericNameSignatureHelpProvider.NamedType.vb | 2 +- .../GenericNameSignatureHelpProvider.vb | 17 +++--- ...sionSignatureHelpProvider.ElementAccess.vb | 7 +-- ...essionSignatureHelpProvider.MemberGroup.vb | 5 +- ...vocationExpressionSignatureHelpProvider.vb | 2 +- ...ssionSignatureHelpProvider.DelegateType.vb | 12 ++-- ...ressionSignatureHelpProvider.NormalType.vb | 11 ++-- ...CreationExpressionSignatureHelpProvider.vb | 2 +- ...aiseEventStatementSignatureHelpProvider.vb | 15 ++--- .../CSharpCodeGenerationService.cs | 27 +++++---- .../CSharpDeclarationComparer.cs | 6 +- .../CodeGeneration/ConstructorGenerator.cs | 8 ++- .../CodeGeneration/ConversionGenerator.cs | 10 ++-- .../CodeGeneration/DestructorGenerator.cs | 4 +- .../Portable/CodeGeneration/FieldGenerator.cs | 6 +- .../CodeGeneration/OperatorGenerator.cs | 7 +-- .../CSharpRenameRewriterLanguageService.cs | 4 +- .../CSharpParenthesizedPatternReducer.cs | 2 +- .../OrganizeImports/OrganizeUsingsTests.cs | 3 +- .../Portable/Editing/DeclarationModifiers.cs | 1 - .../Declarations/DeclarationFinder.cs | 2 +- .../FindReferences/FindReferenceCache.cs | 24 +++----- .../Finders/AbstractReferenceFinder.cs | 3 +- .../Finders/ParameterSymbolReferenceFinder.cs | 13 +---- .../NoOpStreamingFindReferencesProgress.cs | 2 + .../ReferenceLocationExtensions.cs | 3 +- .../FindSymbols/SymbolTree/SymbolTreeInfo.cs | 2 +- .../LinkedFileDiffMergingLogger.cs | 2 +- .../LinkedFileDiffMergingSession.cs | 2 +- ...torConfigDocumentOptionsProviderFactory.cs | 2 +- .../ConflictResolver.Session.cs | 7 +-- .../RenameLocation.ReferenceProcessing.cs | 8 +-- .../Renamer.RenameSymbolDocumentAction.cs | 5 +- .../Shared/Extensions/ISymbolExtensions.cs | 21 +++---- .../Extensions/SyntaxGeneratorExtensions.cs | 6 +- .../Shared/Utilities/EnumValueUtilities.cs | 4 +- .../Core/Portable/Versions/Extensions.cs | 41 -------------- .../Workspace/Solution/ProjectState.cs | 2 +- .../Portable/Workspace/Solution/Solution.cs | 5 +- .../Workspace/Solution/SolutionState.cs | 10 ++-- .../Core/Portable/Workspace/Workspace.cs | 2 +- .../Portable/Workspace/Workspace_Editor.cs | 2 + .../Formatting/FormattingTestBase.cs | 2 + .../Pythia/Api/PythiaServiceBase.cs | 4 ++ .../ServiceHub/Services/LanguageServer.cs | 4 +- .../CodeStyle/TypeStyle/TypeStyleHelper.cs | 7 +-- .../Extensions/BlockSyntaxExtensions.cs | 4 +- ...ParenthesizedExpressionSyntaxExtensions.cs | 6 +- .../CSharp/Extensions/SyntaxTreeExtensions.cs | 2 + .../CSharp/Lightup/SyntaxFactoryEx.cs | 2 + .../Simplifiers/CastSimplifier.cs | 22 ++++---- .../CSharp/Utilities/SpeculationAnalyzer.cs | 5 +- .../Extensions/INamedTypeSymbolExtensions.cs | 3 +- .../BottomUpBaseIndentationFinder.cs | 9 ++- .../TriviaEngine/AbstractTriviaFormatter.cs | 4 +- ...lEquivalenceComparer.EquivalenceVisitor.cs | 5 +- .../Extensions/ExpressionSyntaxExtensions.vb | 4 ++ .../InvocationExpressionSyntaxExtensions.vb | 9 ++- ...ParenthesizedExpressionSyntaxExtensions.vb | 2 +- .../Extensions/SyntaxTokenExtensions.vb | 3 +- .../VisualBasic/Utilities/CastAnalyzer.vb | 4 +- .../VisualBasic/Utilities/ImportsOrganizer.vb | 3 +- .../Utilities/SpeculationAnalyzer.vb | 5 +- .../ContextQuery/SyntaxTreeExtensions.cs | 4 +- .../Extensions/SemanticModelExtensions.cs | 6 +- .../CSharp/Extensions/TypeSyntaxExtensions.cs | 2 +- ...CSharpTypeInferenceService.TypeInferrer.cs | 15 +++-- .../SyntaxGeneratorExtensions_Negate.cs | 12 ++-- .../CallStatementSyntaxExtensions.vb | 2 +- .../ContextQuery/SyntaxTokenExtensions.vb | 4 +- .../ContextQuery/SyntaxTreeExtensions.vb | 6 ++ .../ContextQuery/VisualBasicSyntaxContext.vb | 10 ++-- .../ObjectCreationExpressionExtensions.vb | 2 +- ...lBasicTypeInferenceService.TypeInferrer.vb | 56 +++++++++---------- .../Classification/ClassificationHelpers.vb | 3 +- .../NameSyntaxClassifier.vb | 26 +++------ .../CodeGeneration/ConversionGenerator.vb | 10 ++-- .../CodeGeneration/OperatorGenerator.vb | 10 ++-- .../VisualBasicCodeGenerationHelpers.vb | 8 +-- .../VisualBasicCodeGenerationService.vb | 22 ++++---- .../FindSymbols/VisualBasicReferenceFinder.vb | 3 +- .../TriviaDataFactory.CodeShapeAnalyzer.vb | 4 +- .../Formatting/Rules/BaseFormattingRule.vb | 6 +- .../VisualBasicIndentationService.Indenter.vb | 4 +- ...ualBasicOrganizeImportsService.Rewriter.vb | 2 +- .../Reducers/VisualBasicCallReducer.vb | 2 +- .../Reducers/VisualBasicEscapingReducer.vb | 3 + .../VisualBasicMiscellaneousReducer.vb | 4 +- 188 files changed, 528 insertions(+), 683 deletions(-) delete mode 100644 src/Workspaces/Core/Portable/Versions/Extensions.cs diff --git a/.editorconfig b/.editorconfig index 699fb17642c9f..4d71709247d6f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -256,3 +256,6 @@ dotnet_diagnostic.IDE0052.severity = warning # IDE0059: Unnecessary assignment to a value dotnet_diagnostic.IDE0059.severity = warning + +# IDE0060: Remove unused parameter +dotnet_diagnostic.IDE0060.severity = warning diff --git a/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer.cs index 63d83bb89edb2..ad247586894e0 100644 --- a/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer.cs @@ -32,15 +32,15 @@ protected override bool CanRemoveParentheses( out PrecedenceKind precedence, out bool clarifiesPrecedence) { return CanRemoveParenthesesHelper( - parenthesizedExpression, semanticModel, + parenthesizedExpression, out precedence, out clarifiesPrecedence); } public static bool CanRemoveParenthesesHelper( - ParenthesizedPatternSyntax parenthesizedPattern, SemanticModel semanticModel, + ParenthesizedPatternSyntax parenthesizedPattern, out PrecedenceKind parentPrecedenceKind, out bool clarifiesPrecedence) { - var result = parenthesizedPattern.CanRemoveParentheses(semanticModel); + var result = parenthesizedPattern.CanRemoveParentheses(); if (!result) { parentPrecedenceKind = default; diff --git a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs index a61805d624c28..72a1b0679d2be 100644 --- a/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs +++ b/src/Analyzers/CSharp/CodeFixes/RemoveUnnecessaryParentheses/CSharpRemoveUnnecessaryParenthesesCodeFixProvider.cs @@ -25,7 +25,7 @@ protected override bool CanRemoveParentheses(SyntaxNode current, SemanticModel s { ParenthesizedExpressionSyntax p => CSharpRemoveUnnecessaryExpressionParenthesesDiagnosticAnalyzer.CanRemoveParenthesesHelper(p, semanticModel, out _, out _), #if !CODE_STYLE - ParenthesizedPatternSyntax p => CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer.CanRemoveParenthesesHelper(p, semanticModel, out _, out _), + ParenthesizedPatternSyntax p => CSharpRemoveUnnecessaryPatternParenthesesDiagnosticAnalyzer.CanRemoveParenthesesHelper(p, out _, out _), #endif _ => false, }; diff --git a/src/Analyzers/Core/Analyzers/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs b/src/Analyzers/Core/Analyzers/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs index 094bacf67fb3b..1102a287e3e96 100644 --- a/src/Analyzers/Core/Analyzers/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs +++ b/src/Analyzers/Core/Analyzers/UseAutoProperty/AbstractUseAutoPropertyAnalyzer.cs @@ -192,7 +192,7 @@ protected void AnalyzeProperty( var setMethod = property.SetMethod; if (setMethod != null) { - var setterField = GetSetterField(semanticModel, containingType, setMethod, cancellationToken); + var setterField = GetSetterField(semanticModel, setMethod, cancellationToken); if (setterField != getterField) { // If there is a getter and a setter, they both need to agree on which field they are @@ -238,7 +238,7 @@ protected virtual bool CanConvert(IPropertySymbol property) => true; private IFieldSymbol GetSetterField( - SemanticModel semanticModel, ISymbol containingType, IMethodSymbol setMethod, CancellationToken cancellationToken) + SemanticModel semanticModel, IMethodSymbol setMethod, CancellationToken cancellationToken) { return CheckFieldAccessExpression(semanticModel, GetSetterExpression(setMethod, semanticModel, cancellationToken)); } diff --git a/src/CodeStyle/Core/Analyzers/Options/AnalyzerHelper.cs b/src/CodeStyle/Core/Analyzers/Options/AnalyzerHelper.cs index 0b6d1fbdcfa53..b6c0918cb51ff 100644 --- a/src/CodeStyle/Core/Analyzers/Options/AnalyzerHelper.cs +++ b/src/CodeStyle/Core/Analyzers/Options/AnalyzerHelper.cs @@ -11,7 +11,9 @@ namespace Microsoft.CodeAnalysis.Diagnostics { internal static partial class AnalyzerHelper { +#pragma warning disable IDE0060 // Remove unused parameter - Needed to share this method signature between CodeStyle and Features layer. public static T GetOption(this AnalyzerOptions analyzerOptions, IOption2 option, string? language, SyntaxTree syntaxTree, CancellationToken cancellationToken) +#pragma warning restore IDE0060 // Remove unused parameter { if (analyzerOptions.TryGetEditorConfigOption(option, syntaxTree, out var value)) { @@ -27,7 +29,9 @@ public static T GetOption(this AnalyzerOptions analyzerOptions, Option2 op public static T GetOption(this AnalyzerOptions analyzerOptions, PerLanguageOption2 option, string? language, SyntaxTree syntaxTree, CancellationToken cancellationToken) => GetOption(analyzerOptions, (IOption2)option, language, syntaxTree, cancellationToken); +#pragma warning disable IDE0060 // Remove unused parameter - Needed to share this method signature between CodeStyle and Features layer. public static AnalyzerConfigOptions GetAnalyzerOptionSet(this AnalyzerOptions analyzerOptions, SyntaxTree syntaxTree, CancellationToken cancellationToken) +#pragma warning restore IDE0060 // Remove unused parameter => analyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree); } } diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs index ab42c416ab484..266ae8b4f7e54 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs @@ -3365,8 +3365,7 @@ void Goo() { [|Bar|] b; } -}", -index: 1); +}"); } [WorkItem(539674, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539674")] diff --git a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs index 5bdba3451ddc6..c6c4e35df947d 100644 --- a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs @@ -3641,7 +3641,7 @@ static void Main(string[] args) string s = """"; new Program(s); } -}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); +}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } [WorkItem(14077, "https://github.com/dotnet/roslyn/issues/14077")] @@ -3676,7 +3676,7 @@ public MyAttribute(int p_v) [MyAttribute(123)] class D { -}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); +}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } [WorkItem(33673, "https://github.com/dotnet/roslyn/issues/33673")] diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs index 57eabeb0da9fe..72c5d06798016 100644 --- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs @@ -1298,7 +1298,7 @@ public C(int p_v) } "; await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); + options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1328,7 +1328,7 @@ public C(int p_v) } "; await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); + options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1358,7 +1358,7 @@ public C(int p_v) } "; await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); + options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1407,7 +1407,7 @@ public C(int p_test) } "; await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); + options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs index d72ae876ed22a..c67eaa36c27d0 100644 --- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs @@ -1644,7 +1644,7 @@ public Z(int p_a_End{|Navigation:)|} { field_a = p_a_End; } -}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp)); +}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)); } [WorkItem(36741, "https://github.com/dotnet/roslyn/issues/36741")] @@ -1664,7 +1664,7 @@ public Z(int p_a_End{|Navigation:)|} { field_s_a = p_a_End; } -}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp)); +}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)); } [WorkItem(36741, "https://github.com/dotnet/roslyn/issues/36741")] @@ -1684,7 +1684,7 @@ public Z(int p_a_End{|Navigation:)|} { s_field_a = p_a_End; } -}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp)); +}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)); } [WorkItem(36741, "https://github.com/dotnet/roslyn/issues/36741")] @@ -1695,7 +1695,7 @@ await TestMissingAsync( @"class Z { int [|field__End|] = 2; -}", new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp))); +}", new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix))); } [WorkItem(36741, "https://github.com/dotnet/roslyn/issues/36741")] @@ -1717,7 +1717,7 @@ public Z(int p_a{|Navigation:)|} { s_field_a = p_a; } -}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp)); +}", options: options.MergeStyles(options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); } } } diff --git a/src/EditorFeatures/CSharpTest/InitializeParameter/InitializeMemberFromParameterTests.cs b/src/EditorFeatures/CSharpTest/InitializeParameter/InitializeMemberFromParameterTests.cs index 24d108c276680..89b7a2de28dd4 100644 --- a/src/EditorFeatures/CSharpTest/InitializeParameter/InitializeMemberFromParameterTests.cs +++ b/src/EditorFeatures/CSharpTest/InitializeParameter/InitializeMemberFromParameterTests.cs @@ -1019,7 +1019,7 @@ public C(string p_s_End) { _s = p_s_End; } -}", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1042,7 +1042,7 @@ public C(string t_p_s_End) { _s = t_p_s_End; } -}", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1065,7 +1065,7 @@ public C([||]string p_t_s) { _s = p_t_s; } -}", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.CSharp))); +}", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1134,7 +1134,7 @@ public C(string p_s_End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1157,7 +1157,7 @@ public C(string t_p_s_End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1180,7 +1180,7 @@ public C([||]string p_t_s_End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1255,7 +1255,7 @@ public C(string p_s_End) { _s = p_s_End; } -}", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1280,7 +1280,7 @@ public C(string t_p_s_End) { _s = t_p_s_End; } -}", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1305,7 +1305,7 @@ public C([||]string p_t_s_End) { _s = p_t_s_End; } -}", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1380,7 +1380,7 @@ public C(string p_s_End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1405,7 +1405,7 @@ public C(string t_p_s_End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1430,7 +1430,7 @@ public C([||]string p_t_s_End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1445,7 +1445,7 @@ public C([||]string p__End) } public string S { get; } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -1461,7 +1461,7 @@ class C public C([|string p__End, string p_test_t|]) { } -}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix, LanguageNames.CSharp))); +}", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix))); } private TestParameters OmitIfDefault_Warning => new TestParameters(options: Option(CodeStyleOptions2.RequireAccessibilityModifiers, AccessibilityModifiersRequired.OmitIfDefault, NotificationOption2.Warning)); diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs index 1886863f265bf..65f10a930abbe 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/CodeActions/AbstractCodeActionOrUserDiagnosticTest.cs @@ -479,7 +479,7 @@ internal async Task> TestActionAsync( var operations = await VerifyActionAndGetOperationsAsync(workspace, action, parameters); return await TestOperationsAsync( workspace, expected, operations, conflictSpans, renameSpans, - warningSpans, navigationSpans, expectedChangedDocumentId: null, parseOptions: parameters.parseOptions); + warningSpans, navigationSpans, expectedChangedDocumentId: null); } protected async Task> TestOperationsAsync( @@ -490,8 +490,7 @@ protected async Task> TestOperationsAsync( ImmutableArray renameSpans, ImmutableArray warningSpans, ImmutableArray navigationSpans, - DocumentId expectedChangedDocumentId, - ParseOptions parseOptions = null) + DocumentId expectedChangedDocumentId) { var appliedChanges = ApplyOperationsAndGetSolution(workspace, operations); var oldSolution = appliedChanges.Item1; diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.FixAllDiagnosticProvider.cs b/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.FixAllDiagnosticProvider.cs index 90b6c2b7629ac..c7e9f36aa908f 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.FixAllDiagnosticProvider.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.FixAllDiagnosticProvider.cs @@ -34,13 +34,13 @@ public override async Task> GetDocumentDiagnosticsAsync( } public override Task> GetAllDiagnosticsAsync(Project project, CancellationToken cancellationToken) - => GetProjectDiagnosticsAsync(project, true, cancellationToken); + => GetProjectDiagnosticsAsync(project, true); public override Task> GetProjectDiagnosticsAsync(Project project, CancellationToken cancellationToken) - => GetProjectDiagnosticsAsync(project, false, cancellationToken); + => GetProjectDiagnosticsAsync(project, false); private async Task> GetProjectDiagnosticsAsync( - Project project, bool includeAllDocumentDiagnostics, CancellationToken cancellationToken) + Project project, bool includeAllDocumentDiagnostics) { var diags = includeAllDocumentDiagnostics ? await _testDriver.GetAllDiagnosticsAsync(project) diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs b/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs index f68563d8cf9f1..5dab1d0e780f4 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/Diagnostics/AbstractUserDiagnosticTest.cs @@ -286,7 +286,6 @@ private async Task TestActionCountInAllFixesAsync( internal async Task TestSpansAsync( string initialMarkup, - int index = 0, string diagnosticId = null, TestParameters parameters = default) { diff --git a/src/EditorFeatures/DiagnosticsTestUtilities/NamingStyles/NamingStylesTestOptionSets.cs b/src/EditorFeatures/DiagnosticsTestUtilities/NamingStyles/NamingStylesTestOptionSets.cs index 132d83e9307fe..2772cd6bb332a 100644 --- a/src/EditorFeatures/DiagnosticsTestUtilities/NamingStyles/NamingStylesTestOptionSets.cs +++ b/src/EditorFeatures/DiagnosticsTestUtilities/NamingStyles/NamingStylesTestOptionSets.cs @@ -27,7 +27,7 @@ public NamingStylesTestOptionSets(string languageName) public OptionKey2 OptionKey => _optionKey; - internal OptionsCollection MergeStyles(OptionsCollection first, OptionsCollection second, string languageName) + internal OptionsCollection MergeStyles(OptionsCollection first, OptionsCollection second) { var firstPreferences = (NamingStylePreferences)first.First().Value; var secondPreferences = (NamingStylePreferences)second.First().Value; diff --git a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb index 2271e3936ebcd..69adb41dc540e 100644 --- a/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb +++ b/src/EditorFeatures/VisualBasic/EmbeddedLanguages/VisualBasicEmbeddedLanguageEditorFeaturesProvider.vb @@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages End Sub Friend Overrides Function EscapeText(text As String, token As SyntaxToken) As String - Return EmbeddedLanguageUtilities.EscapeText(text, token) + Return EmbeddedLanguageUtilities.EscapeText(text) End Function End Class End Namespace diff --git a/src/EditorFeatures/VisualBasicTest/GenerateConstructor/GenerateConstructorTests.vb b/src/EditorFeatures/VisualBasicTest/GenerateConstructor/GenerateConstructorTests.vb index dff7da410e9e6..76f0c7a7105fe 100644 --- a/src/EditorFeatures/VisualBasicTest/GenerateConstructor/GenerateConstructorTests.vb +++ b/src/EditorFeatures/VisualBasicTest/GenerateConstructor/GenerateConstructorTests.vb @@ -1919,7 +1919,7 @@ End Class", Dim x As Integer = 1 Dim obj As New C(x) End Sub -End Class", options:=options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix, LanguageNames.VisualBasic)) +End Class", options:=options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)) End Function diff --git a/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs b/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs index 3553e3c56a518..bc0652de48850 100644 --- a/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs +++ b/src/Features/CSharp/Portable/Completion/CompletionProviders/CrefCompletionProvider.cs @@ -97,8 +97,7 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) var hideAdvancedMembers = options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language); var serializedOptions = ImmutableDictionary.Empty.Add(HideAdvancedMembers, hideAdvancedMembers.ToString()); - var items = CreateCompletionItems(document.Project.Solution.Workspace, - semanticModel, symbols, token, position, serializedOptions); + var items = CreateCompletionItems(semanticModel, symbols, token, position, serializedOptions); context.AddItems(items); } @@ -270,7 +269,7 @@ private static TextSpan GetCompletionItemSpan(SourceText text, int position) } private IEnumerable CreateCompletionItems( - Workspace workspace, SemanticModel semanticModel, ImmutableArray symbols, SyntaxToken token, int position, ImmutableDictionary options) + SemanticModel semanticModel, ImmutableArray symbols, SyntaxToken token, int position, ImmutableDictionary options) { var builder = SharedPools.Default().Allocate(); try diff --git a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs index de359affa29ca..f7c27f9902352 100644 --- a/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs +++ b/src/Features/CSharp/Portable/Completion/KeywordRecommenders/WhenKeywordRecommender.cs @@ -148,7 +148,7 @@ private static bool IsTypeName( } isVar = typeSyntax.IsVar; - symbols = semanticModel.LookupName(typeSyntax, namespacesAndTypesOnly: false, cancellationToken); + symbols = semanticModel.LookupName(typeSyntax, cancellationToken); } else { diff --git a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs index 47ec985340ca8..2814acc0b757e 100644 --- a/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs +++ b/src/Features/CSharp/Portable/ExtractMethod/CSharpMethodExtractor.CSharpCodeGenerator.cs @@ -161,9 +161,8 @@ selectedNode is FieldDeclarationSyntax || var semanticModel = SemanticDocument.SemanticModel; var context = InsertionPoint.GetContext(); var postProcessor = new PostProcessor(semanticModel, context.SpanStart); - var statements = SpecializedCollections.EmptyEnumerable(); - statements = AddSplitOrMoveDeclarationOutStatementsToCallSite(statements, cancellationToken); + var statements = AddSplitOrMoveDeclarationOutStatementsToCallSite(cancellationToken); statements = postProcessor.MergeDeclarationStatements(statements); statements = AddAssignmentStatementToCallSite(statements, cancellationToken); statements = await AddInvocationAtCallSiteAsync(statements, cancellationToken).ConfigureAwait(false); diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs index 8e8f5e47c12c5..fcab519fee538 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateConversionService.cs @@ -155,7 +155,6 @@ private bool TryGetExplicitConversionMethodAndTypeToGenerateIn( methodSymbol = GenerateMethodSymbol(typeToGenerateIn, parameterSymbol); if (!ValidateTypeToGenerateIn( - document.Project.Solution, typeToGenerateIn, true, classInterfaceModuleStructTypes)) @@ -187,7 +186,6 @@ private bool TryGetImplicitConversionMethodAndTypeToGenerateIn( methodSymbol = GenerateMethodSymbol(typeToGenerateIn, parameterSymbol); if (!ValidateTypeToGenerateIn( - document.Project.Solution, typeToGenerateIn, true, classInterfaceModuleStructTypes)) diff --git a/src/Features/CSharp/Portable/SignatureHelp/AbstractCSharpSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/AbstractCSharpSignatureHelpProvider.cs index 50cd606a3efcd..1024ad0b62cc1 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/AbstractCSharpSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/AbstractCSharpSignatureHelpProvider.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; -using System.Threading; using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.SignatureHelp; @@ -45,8 +44,7 @@ protected static SignatureHelpSymbolParameter Convert( IParameterSymbol parameter, SemanticModel semanticModel, int position, - IDocumentationCommentFormattingService formatter, - CancellationToken cancellationToken) + IDocumentationCommentFormattingService formatter) { return new SignatureHelpSymbolParameter( parameter.Name, diff --git a/src/Features/CSharp/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.cs index 6b6e2e6f2a5a8..c1b461a1bbdd8 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Linq; -using System.Threading; using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -19,8 +18,7 @@ internal static SignatureHelpItem ConvertMethodGroupMethod( Document document, IMethodSymbol method, int position, - SemanticModel semanticModel, - CancellationToken cancellationToken) + SemanticModel semanticModel) { return ConvertMethodGroupMethod(document, method, position, semanticModel, descriptionParts: null); } @@ -43,7 +41,7 @@ internal static SignatureHelpItem ConvertMethodGroupMethod( GetMethodGroupPreambleParts(method, semanticModel, position), GetSeparatorParts(), GetMethodGroupPostambleParts(), - method.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService, CancellationToken.None)).ToList(), + method.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList(), descriptionParts: descriptionParts); } diff --git a/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs index e701b1dce1bcb..f9b80fd52bd7f 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/AttributeSignatureHelpProvider.cs @@ -155,7 +155,7 @@ private IList GetParameters( var result = new List(); foreach (var parameter in constructor.Parameters) { - result.Add(Convert(parameter, semanticModel, position, documentationCommentFormatter, cancellationToken)); + result.Add(Convert(parameter, semanticModel, position, documentationCommentFormatter)); } for (var i = 0; i < namedParameters.Count; i++) diff --git a/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs index a6a941320668b..ba7d096be48a7 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ConstructorInitializerSignatureHelpProvider.cs @@ -106,7 +106,7 @@ protected override async Task GetItemsWorkerAsync(Document d var selectedItem = TryGetSelectedIndex(accessibleConstructors, symbolInfo); return CreateSignatureHelpItems(accessibleConstructors.SelectAsArray(c => - Convert(c, constructorInitializer.ArgumentList.OpenParenToken, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + Convert(c, constructorInitializer.ArgumentList.OpenParenToken, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem); } @@ -126,8 +126,7 @@ private SignatureHelpItem Convert( SyntaxToken openToken, SemanticModel semanticModel, IAnonymousTypeDisplayService anonymousTypeDisplayService, - IDocumentationCommentFormattingService documentationCommentFormattingService, - CancellationToken cancellationToken) + IDocumentationCommentFormattingService documentationCommentFormattingService) { var position = openToken.SpanStart; var item = CreateItem( @@ -137,8 +136,8 @@ private SignatureHelpItem Convert( constructor.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetPreambleParts(constructor, semanticModel, position), GetSeparatorParts(), - GetPostambleParts(constructor), - constructor.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()); + GetPostambleParts(), + constructor.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()); return item; } @@ -155,7 +154,7 @@ private IList GetPreambleParts( return result; } - private IList GetPostambleParts(IMethodSymbol method) + private IList GetPostambleParts() { return SpecializedCollections.SingletonList( Punctuation(SyntaxKind.CloseParenToken)); diff --git a/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs index 614dad3df1aa2..ff0e27d9501d3 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ElementAccessExpressionSignatureHelpProvider.cs @@ -105,7 +105,7 @@ protected override async Task GetItemsWorkerAsync(Document d var syntaxFacts = document.GetLanguageService(); return CreateSignatureHelpItems(accessibleIndexers.Select(p => - Convert(p, openBrace, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + Convert(p, openBrace, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem: null); } @@ -119,7 +119,7 @@ private TextSpan GetTextSpan(ExpressionSyntax expression, SyntaxToken openBracke } else { - return CompleteElementAccessExpression.GetTextSpan(expression, openBracket); + return CompleteElementAccessExpression.GetTextSpan(openBracket); } } else if (openBracket.Parent is ArrayRankSpecifierSyntax) @@ -224,8 +224,7 @@ private SignatureHelpItem Convert( SyntaxToken openToken, SemanticModel semanticModel, IAnonymousTypeDisplayService anonymousTypeDisplayService, - IDocumentationCommentFormattingService documentationCommentFormattingService, - CancellationToken cancellationToken) + IDocumentationCommentFormattingService documentationCommentFormattingService) { var position = openToken.SpanStart; var item = CreateItem(indexer, semanticModel, position, @@ -234,8 +233,8 @@ private SignatureHelpItem Convert( indexer.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetPreambleParts(indexer, position, semanticModel), GetSeparatorParts(), - GetPostambleParts(indexer), - indexer.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()); + GetPostambleParts(), + indexer.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()); return item; } @@ -274,7 +273,7 @@ private IList GetPreambleParts( return result; } - private IList GetPostambleParts(IPropertySymbol indexer) + private IList GetPostambleParts() { return SpecializedCollections.SingletonList( Punctuation(SyntaxKind.CloseBracketToken)); @@ -297,7 +296,7 @@ internal static bool IsArgumentListToken(ElementAccessExpressionSyntax expressio token != expression.ArgumentList.CloseBracketToken; } - internal static TextSpan GetTextSpan(SyntaxNode expression, SyntaxToken openBracket) + internal static TextSpan GetTextSpan(SyntaxToken openBracket) { Contract.ThrowIfFalse(openBracket.Parent is BracketedArgumentListSyntax && (openBracket.Parent.Parent is ElementAccessExpressionSyntax || openBracket.Parent.Parent is ElementBindingExpressionSyntax)); diff --git a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs index 90601df6c5213..6cff8868160f9 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider.cs @@ -131,7 +131,7 @@ protected override async Task GetItemsWorkerAsync(Document d var syntaxFacts = document.GetLanguageService(); return CreateSignatureHelpItems(accessibleSymbols.Select(s => - Convert(s, lessThanToken, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + Convert(s, lessThanToken, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem: null); } @@ -167,8 +167,7 @@ private SignatureHelpItem Convert( SyntaxToken lessThanToken, SemanticModel semanticModel, IAnonymousTypeDisplayService anonymousTypeDisplayService, - IDocumentationCommentFormattingService documentationCommentFormattingService, - CancellationToken cancellationToken) + IDocumentationCommentFormattingService documentationCommentFormattingService) { var position = lessThanToken.SpanStart; @@ -182,8 +181,8 @@ private SignatureHelpItem Convert( symbol.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetPreambleParts(namedType, semanticModel, position), GetSeparatorParts(), - GetPostambleParts(namedType), - namedType.TypeParameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()); + GetPostambleParts(), + namedType.TypeParameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()); } else { @@ -196,7 +195,7 @@ private SignatureHelpItem Convert( GetPreambleParts(method, semanticModel, position), GetSeparatorParts(), GetPostambleParts(method, semanticModel, position), - method.TypeParameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()); + method.TypeParameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()); } return item; @@ -210,22 +209,20 @@ private SignatureHelpSymbolParameter Convert( ITypeParameterSymbol parameter, SemanticModel semanticModel, int position, - IDocumentationCommentFormattingService formatter, - CancellationToken cancellationToken) + IDocumentationCommentFormattingService formatter) { return new SignatureHelpSymbolParameter( parameter.Name, isOptional: false, documentationFactory: parameter.GetDocumentationPartsFactory(semanticModel, position, formatter), displayParts: parameter.ToMinimalDisplayParts(semanticModel, position, s_minimallyQualifiedFormat), - selectedDisplayParts: GetSelectedDisplayParts(parameter, semanticModel, position, cancellationToken)); + selectedDisplayParts: GetSelectedDisplayParts(parameter, semanticModel, position)); } private IList GetSelectedDisplayParts( ITypeParameterSymbol typeParam, SemanticModel semanticModel, - int position, - CancellationToken cancellationToken) + int position) { var parts = new List(); diff --git a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider_NamedType.cs b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider_NamedType.cs index 2302e88f79f1d..ce1e12805fac8 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider_NamedType.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/GenericNameSignatureHelpProvider_NamedType.cs @@ -22,7 +22,7 @@ private IList GetPreambleParts( return result; } - private IList GetPostambleParts(INamedTypeSymbol namedType) + private IList GetPostambleParts() { return SpecializedCollections.SingletonList( Punctuation(SyntaxKind.GreaterThanToken)); diff --git a/src/Features/CSharp/Portable/SignatureHelp/InitializerExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/InitializerExpressionSignatureHelpProvider.cs index 92d32af4cde88..414eb81ddff4e 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/InitializerExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/InitializerExpressionSignatureHelpProvider.cs @@ -63,7 +63,7 @@ protected override async Task GetItemsWorkerAsync(Document d var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); return CreateCollectionInitializerSignatureHelpItems(addMethods.Select(s => - ConvertMethodGroupMethod(document, s, initializerExpression.OpenBraceToken.SpanStart, semanticModel, cancellationToken)).ToList(), + ConvertMethodGroupMethod(document, s, initializerExpression.OpenBraceToken.SpanStart, semanticModel)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken)); } diff --git a/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProviderBase_MethodGroup.cs b/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProviderBase_MethodGroup.cs index 76857bcb6ffdf..35fe08d09ae97 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProviderBase_MethodGroup.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/InvocationExpressionSignatureHelpProviderBase_MethodGroup.cs @@ -26,7 +26,7 @@ internal partial class InvocationExpressionSignatureHelpProviderBase CancellationToken cancellationToken) { return Task.FromResult( - (accessibleMethods.SelectAsArray(m => ConvertMethodGroupMethod(document, m, invocationExpression.SpanStart, semanticModel, cancellationToken)), + (accessibleMethods.SelectAsArray(m => ConvertMethodGroupMethod(document, m, invocationExpression.SpanStart, semanticModel)), TryGetSelectedIndex(accessibleMethods, currentSymbol))); } diff --git a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs index 8c6aa0ae52f1f..e939822dbc1a5 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.cs @@ -76,7 +76,7 @@ protected override async Task GetItemsWorkerAsync(Document d var syntaxFacts = document.GetLanguageService(); var (items, selectedItem) = type.TypeKind == TypeKind.Delegate - ? GetDelegateTypeConstructors(objectCreationExpression, semanticModel, anonymousTypeDisplayService, type, cancellationToken) + ? GetDelegateTypeConstructors(objectCreationExpression, semanticModel, anonymousTypeDisplayService, type) : GetNormalTypeConstructors(document, objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, type, within, cancellationToken); return CreateSignatureHelpItems(items, textSpan, diff --git a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_DelegateType.cs b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_DelegateType.cs index 1d847610870d9..7d84a629a3674 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_DelegateType.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_DelegateType.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Threading; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.SignatureHelp; @@ -17,8 +16,7 @@ internal partial class ObjectCreationExpressionSignatureHelpProvider BaseObjectCreationExpressionSyntax objectCreationExpression, SemanticModel semanticModel, IAnonymousTypeDisplayService anonymousTypeDisplayService, - INamedTypeSymbol delegateType, - CancellationToken cancellationToken) + INamedTypeSymbol delegateType) { var invokeMethod = delegateType.DelegateInvokeMethod; if (invokeMethod == null) @@ -34,8 +32,8 @@ internal partial class ObjectCreationExpressionSignatureHelpProvider documentationFactory: null, prefixParts: GetDelegateTypePreambleParts(invokeMethod, semanticModel, position), separatorParts: GetSeparatorParts(), - suffixParts: GetDelegateTypePostambleParts(invokeMethod), - parameters: GetDelegateTypeParameters(invokeMethod, semanticModel, position, cancellationToken)); + suffixParts: GetDelegateTypePostambleParts(), + parameters: GetDelegateTypeParameters(invokeMethod, semanticModel, position)); return (SpecializedCollections.SingletonList(item), 0); } @@ -50,7 +48,7 @@ private IList GetDelegateTypePreambleParts(IMethodSymbol invo return result; } - private IList GetDelegateTypeParameters(IMethodSymbol invokeMethod, SemanticModel semanticModel, int position, CancellationToken cancellationToken) + private IList GetDelegateTypeParameters(IMethodSymbol invokeMethod, SemanticModel semanticModel, int position) { const string TargetName = "target"; @@ -84,7 +82,7 @@ private IList GetDelegateTypeParameters(IMethodSym displayParts: parts)); } - private IList GetDelegateTypePostambleParts(IMethodSymbol invokeMethod) + private IList GetDelegateTypePostambleParts() { return SpecializedCollections.SingletonList( Punctuation(SyntaxKind.CloseParenToken)); diff --git a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_NormalType.cs b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_NormalType.cs index 06cafc44a7549..de32314084f15 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_NormalType.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider_NormalType.cs @@ -36,7 +36,7 @@ internal partial class ObjectCreationExpressionSignatureHelpProvider var selectedItem = TryGetSelectedIndex(accessibleConstructors, symbolInfo); var items = accessibleConstructors.SelectAsArray(c => - ConvertNormalTypeConstructor(c, objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)); + ConvertNormalTypeConstructor(c, objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)); return (items, selectedItem); } @@ -46,8 +46,7 @@ private SignatureHelpItem ConvertNormalTypeConstructor( BaseObjectCreationExpressionSyntax objectCreationExpression, SemanticModel semanticModel, IAnonymousTypeDisplayService anonymousTypeDisplayService, - IDocumentationCommentFormattingService documentationCommentFormattingService, - CancellationToken cancellationToken) + IDocumentationCommentFormattingService documentationCommentFormattingService) { var position = objectCreationExpression.SpanStart; var item = CreateItem( @@ -57,8 +56,8 @@ private SignatureHelpItem ConvertNormalTypeConstructor( constructor.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetNormalTypePreambleParts(constructor, semanticModel, position), GetSeparatorParts(), - GetNormalTypePostambleParts(constructor), - constructor.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()); + GetNormalTypePostambleParts(), + constructor.Parameters.Select(p => Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()); return item; } @@ -76,7 +75,7 @@ private IList GetNormalTypePreambleParts( return result; } - private IList GetNormalTypePostambleParts(IMethodSymbol method) + private IList GetNormalTypePostambleParts() { return SpecializedCollections.SingletonList( Punctuation(SyntaxKind.CloseParenToken)); diff --git a/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeStyleProvider.cs b/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeStyleProvider.cs index c1e2cdc8dcd54..6eaeb5649bafb 100644 --- a/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeStyleProvider.cs +++ b/src/Features/CSharp/Portable/UseExpressionBodyForLambda/UseExpressionBodyForLambdaCodeStyleProvider.cs @@ -73,7 +73,7 @@ private static bool TryConvertToExpressionBody( var body = declaration.Body as BlockSyntax; return body.TryConvertToExpressionBody( - declaration.Kind(), options, conversionPreference, + options, conversionPreference, out expression, out semicolon); } diff --git a/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs b/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs index 6f7ff8c3a0ade..07f8fa3969337 100644 --- a/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs +++ b/src/Features/Core/Portable/AddImport/SearchScopes/MetadataSymbolsSearchScope.cs @@ -55,7 +55,7 @@ protected override async Task> FindDeclarationsAsync( } var declarations = await info.FindAsync( - searchQuery, _assembly, _assemblyProjectId, + searchQuery, _assembly, filter, CancellationToken).ConfigureAwait(false); return declarations; diff --git a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs index 2269c78559d54..92f9ca0ab72b6 100644 --- a/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs +++ b/src/Features/Core/Portable/AddParameter/AbstractAddParameterCodeFixProvider.cs @@ -187,7 +187,7 @@ private static ImmutableArray> GetAr { var argumentToAdd = DetermineFirstArgumentToAdd( semanticModel, syntaxFacts, comparer, method, - arguments, argumentOpt); + arguments); if (argumentToAdd != null) { @@ -418,8 +418,7 @@ private static TArgumentSyntax DetermineFirstArgumentToAdd( ISyntaxFactsService syntaxFacts, StringComparer comparer, IMethodSymbol method, - SeparatedSyntaxList arguments, - TArgumentSyntax argumentOpt) + SeparatedSyntaxList arguments) { var compilation = semanticModel.Compilation; var methodParameterNames = new HashSet(comparer); diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs index af9f3c024751d..de783a70d872a 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.GlobalSuppressMessageFixAllCodeAction.cs @@ -99,7 +99,7 @@ private static async Task CreateChangedSolutionAsync(AbstractSuppressi if (suppressMessageAttribute != null) { - var diagnosticsBySymbol = await CreateDiagnosticsBySymbolAsync(fixer, oldProject, kvp.Value, cancellationToken).ConfigureAwait(false); + var diagnosticsBySymbol = await CreateDiagnosticsBySymbolAsync(oldProject, kvp.Value, cancellationToken).ConfigureAwait(false); if (diagnosticsBySymbol.Any()) { var projectCodeAction = new GlobalSuppressMessageFixAllCodeAction( @@ -166,7 +166,7 @@ private static async Task>>> CreateDiagnosticsBySymbolAsync(AbstractSuppressionCodeFixProvider fixer, Project project, ImmutableArray diagnostics, CancellationToken cancellationToken) + private static async Task>>> CreateDiagnosticsBySymbolAsync(Project project, ImmutableArray diagnostics, CancellationToken cancellationToken) { var diagnosticsMapBuilder = ImmutableDictionary.CreateBuilder>(); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs index 1c590120ea213..6ada3bb313a65 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs @@ -169,9 +169,9 @@ private SyntaxToken GetNewTokenWithAddedPragma(SyntaxToken token, TextSpan curre } private SyntaxToken GetNewTokenWithRemovedOrToggledPragma(SyntaxToken token, int indexOfTriviaToRemoveOrToggle, bool isStartToken, bool toggle) - => GetNewTokenWithPragmaUnsuppress(token, indexOfTriviaToRemoveOrToggle, _diagnostic, Fixer, isStartToken, toggle); + => GetNewTokenWithPragmaUnsuppress(token, indexOfTriviaToRemoveOrToggle, Fixer, isStartToken, toggle); - private static SyntaxToken GetNewTokenWithPragmaUnsuppress(SyntaxToken token, int indexOfTriviaToRemoveOrToggle, Diagnostic diagnostic, AbstractSuppressionCodeFixProvider fixer, bool isStartToken, bool toggle) + private static SyntaxToken GetNewTokenWithPragmaUnsuppress(SyntaxToken token, int indexOfTriviaToRemoveOrToggle, AbstractSuppressionCodeFixProvider fixer, bool isStartToken, bool toggle) { Contract.ThrowIfFalse(indexOfTriviaToRemoveOrToggle >= 0); diff --git a/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs b/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs index 83bc9b89e53f5..3d782387f894c 100644 --- a/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs +++ b/src/Features/Core/Portable/Completion/Providers/AbstractPartialMethodCompletionProvider.cs @@ -96,10 +96,10 @@ protected async Task> CreatePartialItemsAsync( var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var line = text.Lines.IndexOf(position); var lineSpan = text.Lines.GetLineFromPosition(position).Span; - return symbols.Select(s => CreateItem(s, line, lineSpan, span, semanticModel, modifiers, document, token)); + return symbols.Select(s => CreateItem(s, line, span, semanticModel, modifiers, token)); } - private CompletionItem CreateItem(IMethodSymbol method, int line, TextSpan lineSpan, TextSpan span, SemanticModel semanticModel, DeclarationModifiers modifiers, Document document, SyntaxToken token) + private CompletionItem CreateItem(IMethodSymbol method, int line, TextSpan span, SemanticModel semanticModel, DeclarationModifiers modifiers, SyntaxToken token) { modifiers = new DeclarationModifiers(method.IsStatic, isUnsafe: method.RequiresUnsafeModifier(), isPartial: true, isAsync: modifiers.IsAsync); var displayText = GetDisplayText(method, semanticModel, span.Start); diff --git a/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs b/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs index e2f391cce855e..6eeeb9933c716 100644 --- a/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ConvertForEachToFor/AbstractConvertForEachToForCodeRefactoringProvider.cs @@ -69,7 +69,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte var semanticFact = document.GetLanguageService(); var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - var foreachInfo = GetForeachInfo(semanticFact, options, model, foreachStatement, cancellationToken); + var foreachInfo = GetForeachInfo(semanticFact, model, foreachStatement, cancellationToken); if (foreachInfo == null || !ValidLocation(foreachInfo)) { return; @@ -143,7 +143,7 @@ protected TStatementSyntax AddItemVariableDeclaration( } private ForEachInfo GetForeachInfo( - ISemanticFactsService semanticFact, OptionSet options, SemanticModel model, + ISemanticFactsService semanticFact, SemanticModel model, TForEachStatement foreachStatement, CancellationToken cancellationToken) { if (!(model.GetOperation(foreachStatement, cancellationToken) is IForEachLoopOperation operation) || operation.Locals.Length != 1) @@ -172,7 +172,7 @@ private ForEachInfo GetForeachInfo( return null; } - GetInterfaceInfo(semanticFact, model, foreachVariable, foreachCollection, + GetInterfaceInfo(model, foreachVariable, foreachCollection, out var explicitCastInterface, out var collectionNameSuggestion, out var countName); if (countName == null) { @@ -186,7 +186,7 @@ private ForEachInfo GetForeachInfo( } private static void GetInterfaceInfo( - ISemanticFactsService semanticFact, SemanticModel model, ILocalSymbol foreachVariable, IOperation foreachCollection, + SemanticModel model, ILocalSymbol foreachVariable, IOperation foreachCollection, out ITypeSymbol explicitCastInterface, out string collectionNameSuggestion, out string countName) { explicitCastInterface = null; @@ -220,7 +220,7 @@ private static void GetInterfaceInfo( return; } - if (!IsExchangable(semanticFact, array.ElementType, foreachType, model.Compilation)) + if (!IsExchangable(array.ElementType, foreachType, model.Compilation)) { return; } @@ -235,7 +235,7 @@ private static void GetInterfaceInfo( if (collectionType.SpecialType == SpecialType.System_String) { var charType = model.Compilation.GetSpecialType(SpecialType.System_Char); - if (!IsExchangable(semanticFact, charType, foreachType, model.Compilation)) + if (!IsExchangable(charType, foreachType, model.Compilation)) { return; } @@ -252,7 +252,7 @@ private static void GetInterfaceInfo( var indexer = GetInterfaceMember(collectionType, get_Item); if (indexer != null) { - if (!IsExchangable(semanticFact, indexer.ReturnType, foreachType, model.Compilation)) + if (!IsExchangable(indexer.ReturnType, foreachType, model.Compilation)) { return; } @@ -276,7 +276,7 @@ private static void GetInterfaceInfo( { var indexer = GetInterfaceMember(collectionType, get_Item); if (indexer != null && - IsExchangable(semanticFact, indexer.ReturnType, foreachType, model.Compilation)) + IsExchangable(indexer.ReturnType, foreachType, model.Compilation)) { explicitCastInterface = null; countName = Count; @@ -305,7 +305,7 @@ private static void GetInterfaceInfo( continue; } - if (!IsExchangable(semanticFact, indexerImpl.ReturnType, foreachType, model.Compilation)) + if (!IsExchangable(indexerImpl.ReturnType, foreachType, model.Compilation)) { continue; } @@ -334,7 +334,7 @@ private static void GetInterfaceInfo( } private static bool IsExchangable( - ISemanticFactsService semanticFact, ITypeSymbol type1, ITypeSymbol type2, Compilation compilation) + ITypeSymbol type1, ITypeSymbol type2, Compilation compilation) { return compilation.HasImplicitConversion(type1, type2) || compilation.HasImplicitConversion(type2, type1); diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs index fff8f02338a9c..c7237894f9ede 100644 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs +++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs @@ -484,6 +484,7 @@ public static async Task> ComputeProjectDiagnosticAna private static bool IsCanceled(Exception ex, CancellationToken cancellationToken) => (ex as OperationCanceledException)?.CancellationToken == cancellationToken; +#if DEBUG private static async Task VerifyDiagnosticLocationsAsync(ImmutableArray diagnostics, Project project, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) @@ -564,6 +565,7 @@ async Task VerifyDiagnosticLocationAsync(string id, Location location) return null; } } +#endif public static IEnumerable ConvertToLocalDiagnostics(this IEnumerable diagnostics, Document targetDocument, TextSpan? span = null) { diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs index 1c5feafbc57c6..581313ccd4607 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs @@ -271,20 +271,23 @@ private void VerifyDiagnostics(SemanticModel model) GC.KeepAlive(wholeMethodBodyDiagnostics); GC.KeepAlive(wholeDiagnostics); } -#endif - } - private static bool IsUnusedImportDiagnostic(Diagnostic d) - { - switch (d.Id) + return; + + // Local functions. + static bool IsUnusedImportDiagnostic(Diagnostic d) { - case "CS8019": - case "BC50000": - case "BC50001": - return true; - default: - return false; + switch (d.Id) + { + case "CS8019": + case "BC50000": + case "BC50001": + return true; + default: + return false; + } } +#endif } private static TextSpan AdjustSpan(Document document, SyntaxNode root, TextSpan span) diff --git a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs index 49e0bc45b3f52..7847eeffbaca5 100644 --- a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs @@ -323,7 +323,7 @@ private static void AppendTextFromNode(FormatterState state, XNode node, Compila { foreach (var attribute in element.Attributes()) { - AppendTextFromAttribute(state, element, attribute, attributeNameToParse: DocumentationCommentXmlNames.CrefAttributeName, SymbolDisplayPartKind.Text); + AppendTextFromAttribute(state, attribute, attributeNameToParse: DocumentationCommentXmlNames.CrefAttributeName, SymbolDisplayPartKind.Text); } return; @@ -343,7 +343,7 @@ private static void AppendTextFromNode(FormatterState state, XNode node, Compila var kind = name == DocumentationCommentXmlNames.ParameterReferenceElementName ? SymbolDisplayPartKind.ParameterName : SymbolDisplayPartKind.TypeParameterName; foreach (var attribute in element.Attributes()) { - AppendTextFromAttribute(state, element, attribute, attributeNameToParse: DocumentationCommentXmlNames.NameAttributeName, kind); + AppendTextFromAttribute(state, attribute, attributeNameToParse: DocumentationCommentXmlNames.NameAttributeName, kind); } return; @@ -455,7 +455,7 @@ private static (string target, string hint)? GetNavigationTarget(XElement elemen return null; } - private static void AppendTextFromAttribute(FormatterState state, XElement element, XAttribute attribute, string attributeNameToParse, SymbolDisplayPartKind kind) + private static void AppendTextFromAttribute(FormatterState state, XAttribute attribute, string attributeNameToParse, SymbolDisplayPartKind kind) { var attributeName = attribute.Name.LocalName; if (attributeNameToParse == attributeName) diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexPatternDetector.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexPatternDetector.cs index aefe79a27dee7..1fcf8cf6ce9c5 100644 --- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexPatternDetector.cs +++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/LanguageServices/RegexPatternDetector.cs @@ -249,14 +249,14 @@ public bool IsRegexPattern(SyntaxToken token, CancellationToken cancellationToke // allocation. var symbolInfo = _semanticModel.GetSymbolInfo(invocationOrCreation, cancellationToken); var method = symbolInfo.Symbol; - if (TryAnalyzeInvocation(stringLiteral, argumentNode, method, cancellationToken, out options)) + if (TryAnalyzeInvocation(argumentNode, method, cancellationToken, out options)) { return true; } foreach (var candidate in symbolInfo.CandidateSymbols) { - if (TryAnalyzeInvocation(stringLiteral, argumentNode, candidate, cancellationToken, out options)) + if (TryAnalyzeInvocation(argumentNode, candidate, cancellationToken, out options)) { return true; } @@ -276,7 +276,7 @@ public bool IsRegexPattern(SyntaxToken token, CancellationToken cancellationToke { // Argument to "new Regex". Need to do deeper analysis return AnalyzeStringLiteral( - stringLiteral, argumentNode, cancellationToken, out options); + argumentNode, cancellationToken, out options); } } } @@ -286,7 +286,7 @@ public bool IsRegexPattern(SyntaxToken token, CancellationToken cancellationToke } private bool TryAnalyzeInvocation( - SyntaxToken stringLiteral, SyntaxNode argumentNode, ISymbol method, + SyntaxNode argumentNode, ISymbol method, CancellationToken cancellationToken, out RegexOptions options) { if (method != null && @@ -295,7 +295,7 @@ private bool TryAnalyzeInvocation( _regexType.Equals(method.ContainingType)) { return AnalyzeStringLiteral( - stringLiteral, argumentNode, cancellationToken, out options); + argumentNode, cancellationToken, out options); } options = default; @@ -314,8 +314,9 @@ public RegexTree TryParseRegexPattern(SyntaxToken token, CancellationToken cance } private bool AnalyzeStringLiteral( - SyntaxToken stringLiteral, SyntaxNode argumentNode, - CancellationToken cancellationToken, out RegexOptions options) + SyntaxNode argumentNode, + CancellationToken cancellationToken, + out RegexOptions options) { options = default; diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs index 9b967b47b48e8..1aecfdc775cf4 100644 --- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs +++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs @@ -292,7 +292,7 @@ private static bool CharInCategory(char ch, string set, int start, int mySetLeng if (curcat == 0) { // zero is our marker for a group of categories - treated as a unit - if (CharInCategoryGroup(ch, chcategory, set, ref i)) + if (CharInCategoryGroup(chcategory, set, ref i)) return true; } else if (curcat > 0) @@ -344,7 +344,7 @@ private static bool CharInCategory(char ch, string set, int start, int mySetLeng /// This is used for categories which are composed of other categories - L, N, Z, W... /// These groups need special treatment when they are negated /// - private static bool CharInCategoryGroup(char ch, UnicodeCategory chcategory, string category, ref int i) + private static bool CharInCategoryGroup(UnicodeCategory chcategory, string category, ref int i) { i++; diff --git a/src/Features/Core/Portable/ExternalAccess/Pythia/Api/PythiaSymbolSorting.cs b/src/Features/Core/Portable/ExternalAccess/Pythia/Api/PythiaSymbolSorting.cs index 59de23b19d18d..cf07d544177f1 100644 --- a/src/Features/Core/Portable/ExternalAccess/Pythia/Api/PythiaSymbolSorting.cs +++ b/src/Features/Core/Portable/ExternalAccess/Pythia/Api/PythiaSymbolSorting.cs @@ -11,6 +11,7 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.Pythia.Api { internal static class PythiaSymbolSorting { +#pragma warning disable IDE0060 // Remove unused parameter - Avoid breaking change for ExternalAccess API. public static ImmutableArray Sort( ImmutableArray symbols, ISymbolDisplayService symbolDisplayService, @@ -18,5 +19,6 @@ public static ImmutableArray Sort( int position) where TSymbol : ISymbol => Shared.Extensions.ISymbolExtensions2.Sort(symbols, semanticModel, position); +#pragma warning restore IDE0060 // Remove unused parameter } } diff --git a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs index e087b0d2d0e8e..42b5a6264d101 100644 --- a/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs +++ b/src/Features/Core/Portable/ExtractInterface/AbstractExtractInterfaceService.cs @@ -106,7 +106,7 @@ public async Task AnalyzeTypeAtPositionAsync return new ExtractInterfaceTypeAnalysisResult(errorMessage); } - return new ExtractInterfaceTypeAnalysisResult(this, document, typeNode, typeToExtractFrom, extractableMembers); + return new ExtractInterfaceTypeAnalysisResult(document, typeNode, typeToExtractFrom, extractableMembers); } public async Task ExtractInterfaceFromAnalyzedTypeAsync(ExtractInterfaceTypeAnalysisResult refactoringResult, CancellationToken cancellationToken) @@ -199,7 +199,6 @@ private async Task ExtractInterfaceToNewFileAsync( var completedUnformattedSolution = await GetSolutionWithOriginalTypeUpdatedAsync( unformattedInterfaceDocument.Project.Solution, symbolMapping.DocumentIds, - refactoringResult.DocumentToExtractFrom.Id, symbolMapping.TypeNodeAnnotation, refactoringResult.TypeToExtractFrom, extractedInterfaceSymbol, @@ -251,7 +250,7 @@ private async Task ExtractInterfaceToSameFileAsync( // After the interface is inserted, update the original type to show it implements the new interface var unformattedSolutionWithUpdatedType = await GetSolutionWithOriginalTypeUpdatedAsync( unformattedSolution, symbolMapping.DocumentIds, - refactoringResult.DocumentToExtractFrom.Id, symbolMapping.TypeNodeAnnotation, + symbolMapping.TypeNodeAnnotation, refactoringResult.TypeToExtractFrom, extractedInterfaceSymbol, extractInterfaceOptions.IncludedMembers, symbolMapping.SymbolToDeclarationAnnotationMap, cancellationToken).ConfigureAwait(false); @@ -388,7 +387,6 @@ private async Task GetFormattedSolutionAsync(Solution unformattedSolut private async Task GetSolutionWithOriginalTypeUpdatedAsync( Solution solution, List documentIds, - DocumentId invocationLocationDocumentId, SyntaxAnnotation typeNodeAnnotation, INamedTypeSymbol typeToExtractFrom, INamedTypeSymbol extractedInterfaceSymbol, diff --git a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs index 693dd047c5f66..87adf34f51bfd 100644 --- a/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs +++ b/src/Features/Core/Portable/ExtractInterface/ExtractInterfaceTypeAnalysisResult.cs @@ -16,7 +16,6 @@ internal class ExtractInterfaceTypeAnalysisResult public readonly string ErrorMessage; public ExtractInterfaceTypeAnalysisResult( - AbstractExtractInterfaceService extractInterfaceService, Document documentToExtractFrom, SyntaxNode typeNode, INamedTypeSymbol typeToExtractFrom, diff --git a/src/Features/Core/Portable/ExtractMethod/ExtractMethodMatrix.cs b/src/Features/Core/Portable/ExtractMethod/ExtractMethodMatrix.cs index d6cd37e0253a5..5c603d5d7a823 100644 --- a/src/Features/Core/Portable/ExtractMethod/ExtractMethodMatrix.cs +++ b/src/Features/Core/Portable/ExtractMethod/ExtractMethodMatrix.cs @@ -20,7 +20,6 @@ static ExtractMethodMatrix() public static bool TryGetVariableStyle( bool bestEffort, - bool captured, bool dataFlowIn, bool dataFlowOut, bool alwaysAssigned, diff --git a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs index aa2ebaaa8cce6..9d5464c962c6c 100644 --- a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs +++ b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.Analyzer.cs @@ -534,7 +534,7 @@ private bool TryGetVariableStyle( Contract.ThrowIfNull(type); if (!ExtractMethodMatrix.TryGetVariableStyle( - bestEffort, captured, dataFlowIn, dataFlowOut, alwaysAssigned, variableDeclared, + bestEffort, dataFlowIn, dataFlowOut, alwaysAssigned, variableDeclared, readInside, writtenInside, readOutside, writtenOutside, unsafeAddressTaken, out variableStyle)) { diff --git a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.CodeGenerator.cs b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.CodeGenerator.cs index 8b7c670f74db9..f771d67dc61a2 100644 --- a/src/Features/Core/Portable/ExtractMethod/MethodExtractor.CodeGenerator.cs +++ b/src/Features/Core/Portable/ExtractMethod/MethodExtractor.CodeGenerator.cs @@ -255,7 +255,7 @@ protected IEnumerable CreateDeclarationStatements( } protected IEnumerable AddSplitOrMoveDeclarationOutStatementsToCallSite( - IEnumerable statements, CancellationToken cancellationToken) + CancellationToken cancellationToken) { var list = new List(); diff --git a/src/Features/Core/Portable/GenerateMember/AbstractGenerateMemberService.cs b/src/Features/Core/Portable/GenerateMember/AbstractGenerateMemberService.cs index 052848cf101ec..7ff0ea908591a 100644 --- a/src/Features/Core/Portable/GenerateMember/AbstractGenerateMemberService.cs +++ b/src/Features/Core/Portable/GenerateMember/AbstractGenerateMemberService.cs @@ -28,7 +28,6 @@ protected AbstractGenerateMemberService() }; protected bool ValidateTypeToGenerateIn( - Solution solution, INamedTypeSymbol typeToGenerateIn, bool isStatic, ISet typeKinds) diff --git a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.Editor.cs b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.Editor.cs index 8703dfd6b76b9..13831dc9df317 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.Editor.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateConstructor/AbstractGenerateConstructorService.Editor.cs @@ -200,7 +200,7 @@ public Editor( out var parameterToExistingFieldMap, out var parameterToNewFieldMap, out var remainingParameters); var fields = _withFields - ? syntaxFactory.CreateFieldsForParameters(remainingParameters, parameterToNewFieldMap) + ? SyntaxGeneratorExtensions.CreateFieldsForParameters(remainingParameters, parameterToNewFieldMap) : ImmutableArray.Empty; var assignStatements = syntaxFactory.CreateAssignmentStatements( _document.SemanticModel, remainingParameters, diff --git a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.State.cs index ee1b198f55035..fd09faaf634f8 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateEnumMember/AbstractGenerateEnumMemberService.State.cs @@ -72,8 +72,7 @@ private async Task TryInitializeAsync( cancellationToken.ThrowIfCancellationRequested(); TypeToGenerateIn = await SymbolFinder.FindSourceDefinitionAsync(TypeToGenerateIn, document.Project.Solution, cancellationToken).ConfigureAwait(false) as INamedTypeSymbol; - if (!service.ValidateTypeToGenerateIn( - document.Project.Solution, TypeToGenerateIn, true, EnumType)) + if (!service.ValidateTypeToGenerateIn(TypeToGenerateIn, true, EnumType)) { return false; } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.AbstractInvocationInfo.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.AbstractInvocationInfo.cs index 9ee3281ee1da0..09e685224f576 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.AbstractInvocationInfo.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.AbstractInvocationInfo.cs @@ -31,7 +31,7 @@ protected override ImmutableArray DetermineTypeParametersW CancellationToken cancellationToken) { var typeParameters = ComputeTypeParameters(cancellationToken); - return typeParameters.SelectAsArray(tp => MassageTypeParameter(tp, cancellationToken)); + return typeParameters.SelectAsArray(tp => MassageTypeParameter(tp)); } private ImmutableArray ComputeTypeParameters( @@ -53,8 +53,7 @@ private ImmutableArray ComputeTypeParameters( } private ITypeParameterSymbol MassageTypeParameter( - ITypeParameterSymbol typeParameter, - CancellationToken cancellationToken) + ITypeParameterSymbol typeParameter) { var constraints = typeParameter.ConstraintTypes.Where(ts => !ts.IsUnexpressibleTypeParameterConstraint()).ToList(); var classTypes = constraints.Where(ts => ts.TypeKind == TypeKind.Class).ToList(); diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs index 9c37f18865eed..910ca918dec97 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.SignatureInfo.cs @@ -74,7 +74,7 @@ internal async ValueTask GeneratePropertyAsync( var getMethod = CodeGenerationSymbolFactory.CreateAccessorSymbol( attributes: default, accessibility: accessibility, - statements: GenerateStatements(factory, isAbstract, cancellationToken)); + statements: GenerateStatements(factory, isAbstract)); var setMethod = includeSetter ? getMethod : null; @@ -114,7 +114,7 @@ public async ValueTask GenerateMethodAsync( name: State.IdentifierToken.ValueText, typeParameters: DetermineTypeParameters(cancellationToken), parameters: parameters, - statements: GenerateStatements(factory, isAbstract, cancellationToken), + statements: GenerateStatements(factory, isAbstract), handlesExpressions: default, returnTypeAttributes: default, methodKind: State.MethodKind); @@ -189,8 +189,7 @@ private IDictionary CreateTypeArgumentToTypeP private ImmutableArray GenerateStatements( SyntaxGenerator factory, - bool isAbstract, - CancellationToken cancellationToken) + bool isAbstract) { var throwStatement = CodeGenerationHelpers.GenerateThrowStatement(factory, Document, "System.NotImplementedException"); diff --git a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.State.cs index ef4efe1ef7d5a..53d94e129758d 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateParameterizedMember/AbstractGenerateParameterizedMemberService.State.cs @@ -61,8 +61,7 @@ protected async Task TryFinishInitializingStateAsync(TService service, Sem return false; } - if (!service.ValidateTypeToGenerateIn(document.Project.Solution, TypeToGenerateIn, - IsStatic, ClassInterfaceModuleStructTypes)) + if (!service.ValidateTypeToGenerateIn(TypeToGenerateIn, IsStatic, ClassInterfaceModuleStructTypes)) { return false; } diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs index c39140cbd5b01..2121958cd6fc7 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs @@ -122,8 +122,7 @@ private async Task TryInitializeAsync( TypeToGenerateIn = await SymbolFinder.FindSourceDefinitionAsync(TypeToGenerateIn, document.Project.Solution, cancellationToken).ConfigureAwait(false) as INamedTypeSymbol; - if (!service.ValidateTypeToGenerateIn( - document.Project.Solution, TypeToGenerateIn, IsStatic, ClassInterfaceModuleStructTypes)) + if (!service.ValidateTypeToGenerateIn(TypeToGenerateIn, IsStatic, ClassInterfaceModuleStructTypes)) { return false; } diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs index 54812da289f96..27ddc14d7aeb6 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs @@ -562,14 +562,6 @@ private ITypeSymbol FixType( return typeSymbol.RemoveUnnamedErrorTypes(compilation); } - private ICodeGenerationService GetCodeGenerationService() - { - var language = _state.TypeToGenerateInOpt == null - ? _state.SimpleName.Language - : _state.TypeToGenerateInOpt.Language; - return _semanticDocument.Project.Solution.Workspace.Services.GetLanguageServices(language).GetService(); - } - private bool TryFindMatchingField( ParameterName parameterName, ITypeSymbol parameterType, diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.GenerateNamedType.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.GenerateNamedType.cs index 8f5e4f8c6a2d6..671a5bd5c2b72 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.GenerateNamedType.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.GenerateNamedType.cs @@ -49,11 +49,11 @@ private INamedTypeSymbol GenerateNamedType(GenerateTypeOptionsResult options) DetermineAttributes(), options.Accessibility, DetermineModifiers(), - DetermineReturnType(options), + DetermineReturnType(), RefKind.None, name: options.TypeName, - typeParameters: DetermineTypeParameters(options), - parameters: DetermineParameters(options)); + typeParameters: DetermineTypeParametersWithDelegateChecks(), + parameters: DetermineParameters()); } return CodeGenerationSymbolFactory.CreateNamedTypeSymbol( @@ -68,7 +68,7 @@ private INamedTypeSymbol GenerateNamedType(GenerateTypeOptionsResult options) members: DetermineMembers(options)); } - private ITypeSymbol DetermineReturnType(GenerateTypeOptionsResult options) + private ITypeSymbol DetermineReturnType() { if (_state.DelegateMethodSymbol == null || _state.DelegateMethodSymbol.ReturnType == null || @@ -83,7 +83,7 @@ private ITypeSymbol DetermineReturnType(GenerateTypeOptionsResult options) } } - private ImmutableArray DetermineTypeParameters(GenerateTypeOptionsResult options) + private ImmutableArray DetermineTypeParametersWithDelegateChecks() { if (_state.DelegateMethodSymbol != null) { @@ -94,7 +94,7 @@ private ImmutableArray DetermineTypeParameters(GenerateTyp return DetermineTypeParameters(); } - private ImmutableArray DetermineParameters(GenerateTypeOptionsResult options) + private ImmutableArray DetermineParameters() { if (_state.DelegateMethodSymbol != null) { diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs index e9f64eb33d2af..38358f2636f58 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs @@ -120,7 +120,7 @@ private ImmutableArray GetActions( var generateIntoContaining = IsGeneratingIntoContainingNamespace(document, node, state, cancellationToken); if ((isSimpleName || generateIntoContaining) && - CanGenerateIntoContainingNamespace(document, node, state, cancellationToken)) + CanGenerateIntoContainingNamespace(document, node, cancellationToken)) { result.Add(new GenerateTypeCodeAction((TService)this, document.Document, state, intoNamespace: true, inNewFile: false)); } @@ -139,7 +139,7 @@ private ImmutableArray GetActions( return result.ToImmutableAndFree(); } - private bool CanGenerateIntoContainingNamespace(SemanticDocument semanticDocument, SyntaxNode node, State state, CancellationToken cancellationToken) + private bool CanGenerateIntoContainingNamespace(SemanticDocument semanticDocument, SyntaxNode node, CancellationToken cancellationToken) { var containingNamespace = semanticDocument.SemanticModel.GetEnclosingNamespace(node.SpanStart, cancellationToken); diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs index 1b0813a2ce582..a5d34b8b9f419 100644 --- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs +++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction.cs @@ -204,7 +204,7 @@ protected async Task GetUpdatedDocumentAsync( var propertyGenerationBehavior = options.GetOption(ImplementTypeOptions.PropertyGenerationBehavior); var memberDefinitions = GenerateMembers( - compilation, unimplementedMembers, propertyGenerationBehavior, cancellationToken); + compilation, unimplementedMembers, propertyGenerationBehavior); // Only group the members in the destination if the user wants that *and* // it's not a ComImport interface. Member ordering in ComImport interfaces @@ -226,8 +226,7 @@ protected async Task GetUpdatedDocumentAsync( private ImmutableArray GenerateMembers( Compilation compilation, ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> unimplementedMembers, - ImplementTypePropertyGenerationBehavior propertyGenerationBehavior, - CancellationToken cancellationToken) + ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) { // As we go along generating members we may end up with conflicts. For example, say // you have "interface IGoo { string Bar { get; } }" and "interface IQuux { int Bar @@ -252,7 +251,7 @@ private ImmutableArray GenerateMembers( { var member = GenerateMember( compilation, unimplementedInterfaceMember, implementedVisibleMembers, - propertyGenerationBehavior, cancellationToken); + propertyGenerationBehavior); if (member != null) { implementedMembers.Add(member); @@ -295,8 +294,7 @@ private ISymbol GenerateMember( Compilation compilation, ISymbol member, List implementedVisibleMembers, - ImplementTypePropertyGenerationBehavior propertyGenerationBehavior, - CancellationToken cancellationToken) + ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) { // First check if we already generate a member that matches the member we want to // generate. This can happen in C# when you have interfaces that have the same @@ -334,7 +332,7 @@ private ISymbol GenerateMember( return GenerateMember( compilation, member, memberName, generateInvisibleMember, generateAbstractly, - addNew, addUnsafe, propertyGenerationBehavior, cancellationToken); + addNew, addUnsafe, propertyGenerationBehavior); } private bool GenerateInvisibleMember(ISymbol member, string memberName) @@ -402,8 +400,7 @@ private ISymbol GenerateMember( bool generateAbstractly, bool addNew, bool addUnsafe, - ImplementTypePropertyGenerationBehavior propertyGenerationBehavior, - CancellationToken cancellationToken) + ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) { var factory = Document.GetLanguageService(); var modifiers = new DeclarationModifiers(isAbstract: generateAbstractly, isNew: addNew, isUnsafe: addUnsafe); @@ -416,7 +413,7 @@ private ISymbol GenerateMember( return member switch { IMethodSymbol method => GenerateMethod(compilation, method, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName), - IPropertySymbol property => GenerateProperty(compilation, property, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName, propertyGenerationBehavior, cancellationToken), + IPropertySymbol property => GenerateProperty(compilation, property, accessibility, modifiers, generateAbstractly, useExplicitInterfaceSymbol, memberName, propertyGenerationBehavior), IEventSymbol @event => GenerateEvent(compilation, memberName, generateInvisibly, factory, modifiers, useExplicitInterfaceSymbol, accessibility, @event), _ => null, }; diff --git a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs index c0788b9c0906c..2624c827118fa 100644 --- a/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs +++ b/src/Features/Core/Portable/ImplementInterface/AbstractImplementInterfaceService.CodeAction_Property.cs @@ -6,7 +6,6 @@ using System.Collections.Immutable; using System.Linq; -using System.Threading; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.ImplementType; @@ -29,8 +28,7 @@ private ISymbol GenerateProperty( bool generateAbstractly, bool useExplicitInterfaceSymbol, string memberName, - ImplementTypePropertyGenerationBehavior propertyGenerationBehavior, - CancellationToken cancellationToken) + ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) { var factory = Document.GetLanguageService(); var attributesToRemove = AttributesToRemove(compilation); diff --git a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs index f4a251c9f32d8..f2f3de70d90f7 100644 --- a/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs +++ b/src/Features/Core/Portable/InitializeParameter/AbstractInitializeMemberFromParameterCodeRefactoringProviderMemberCreation.cs @@ -88,7 +88,7 @@ protected override async Task> GetRefactoringsForSing { return HandleExistingFieldOrProperty( document, parameter, constructorDeclaration, - method, blockStatementOpt, fieldOrProperty); + blockStatementOpt, fieldOrProperty); } return await HandleNoExistingFieldOrPropertyAsync( @@ -222,7 +222,7 @@ private ImmutableArray GetParametersWithoutAssociatedMembers( return result.ToImmutable(); } - private ImmutableArray HandleExistingFieldOrProperty(Document document, IParameterSymbol parameter, SyntaxNode functionDeclaration, IMethodSymbol method, IBlockOperation? blockStatementOpt, ISymbol fieldOrProperty) + private ImmutableArray HandleExistingFieldOrProperty(Document document, IParameterSymbol parameter, SyntaxNode functionDeclaration, IBlockOperation? blockStatementOpt, ISymbol fieldOrProperty) { // Found a field/property that this parameter should be assigned to. // Just offer the simple assignment to it. diff --git a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs index b1e5be14d07b8..70e2eb159434d 100644 --- a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs @@ -38,7 +38,7 @@ public async Task AddSourceToAsync(Document document, Compilation symb document.Project.Solution, rootNamespace, CreateCodeGenerationSymbol(document, symbol), - CreateCodeGenerationOptions(newSemanticModel.SyntaxTree.GetLocation(new TextSpan()), symbol), + CreateCodeGenerationOptions(newSemanticModel.SyntaxTree.GetLocation(new TextSpan())), cancellationToken).ConfigureAwait(false); document = await RemoveSimplifierAnnotationsFromImportsAsync(document, cancellationToken).ConfigureAwait(false); @@ -118,7 +118,7 @@ private static INamespaceOrTypeSymbol CreateCodeGenerationSymbol(Document docume new[] { wrappedType }); } - private static CodeGenerationOptions CreateCodeGenerationOptions(Location contextLocation, ISymbol symbol) + private static CodeGenerationOptions CreateCodeGenerationOptions(Location contextLocation) { return new CodeGenerationOptions( contextLocation: contextLocation, diff --git a/src/Features/Core/Portable/Navigation/NavigableItemFactory.cs b/src/Features/Core/Portable/Navigation/NavigableItemFactory.cs index 14492844be94c..b849e24f0573c 100644 --- a/src/Features/Core/Portable/Navigation/NavigableItemFactory.cs +++ b/src/Features/Core/Portable/Navigation/NavigableItemFactory.cs @@ -65,17 +65,5 @@ private static IEnumerable GetPreferredSourceLocations(ISymbol symbol) ? visibleSourceLocations : locations.Where(loc => loc.IsInSource); } - - public static IEnumerable GetPreferredNavigableItems( - Solution solution, - IEnumerable navigableItems, - CancellationToken cancellationToken) - { - navigableItems = navigableItems.Where(n => n.Document != null); - var hasNonGeneratedCodeItem = navigableItems.Any(n => !n.Document.IsGeneratedCode(cancellationToken)); - return hasNonGeneratedCodeItem - ? navigableItems.Where(n => !n.Document.IsGeneratedCode(cancellationToken)) - : navigableItems.Where(n => n.Document.IsGeneratedCode(cancellationToken)); - } } } diff --git a/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs b/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs index c556e8054c45a..fbd5d2bdb6608 100644 --- a/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs +++ b/src/Features/Core/Portable/PullMemberUp/MembersPuller.cs @@ -91,7 +91,7 @@ private static async Task PullMembersIntoInterfaceAsync( var codeGenerationService = document.Project.LanguageServices.GetRequiredService(); var destinationSyntaxNode = await codeGenerationService.FindMostRelevantNameSpaceOrTypeDeclarationAsync( solution, pullMemberUpOptions.Destination, options: null, cancellationToken).ConfigureAwait(false); - var symbolToDeclarationsMap = await InitializeSymbolToDeclarationsMapAsync(pullMemberUpOptions, solution, solutionEditor, destinationSyntaxNode, cancellationToken).ConfigureAwait(false); + var symbolToDeclarationsMap = await InitializeSymbolToDeclarationsMapAsync(pullMemberUpOptions, cancellationToken).ConfigureAwait(false); var symbolsToPullUp = pullMemberUpOptions.MemberAnalysisResults. SelectAsArray(analysisResult => GetSymbolsToPullUp(analysisResult)); @@ -237,7 +237,7 @@ private static async Task PullMembersIntoClassAsync( var codeGenerationService = document.Project.LanguageServices.GetRequiredService(); var destinationSyntaxNode = await codeGenerationService.FindMostRelevantNameSpaceOrTypeDeclarationAsync( solution, result.Destination, options: null, cancellationToken).ConfigureAwait(false); - var symbolToDeclarations = await InitializeSymbolToDeclarationsMapAsync(result, solution, solutionEditor, destinationSyntaxNode, cancellationToken).ConfigureAwait(false); + var symbolToDeclarations = await InitializeSymbolToDeclarationsMapAsync(result, cancellationToken).ConfigureAwait(false); // Add members to destination var pullUpMembersSymbols = result.MemberAnalysisResults.SelectAsArray( memberResult => @@ -322,9 +322,6 @@ private static ISymbol MakeAbstractVersion(ISymbol member) private static async Task>> InitializeSymbolToDeclarationsMapAsync( PullMembersUpOptions result, - Solution solution, - SolutionEditor solutionEditor, - SyntaxNode destinationSyntaxNode, CancellationToken cancellationToken) { // One member may have multiple syntax nodes (e.g partial method). diff --git a/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs b/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs index d05401edaeced..8a84e7489dcd2 100644 --- a/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs +++ b/src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs @@ -83,7 +83,7 @@ internal abstract partial class CommonSemanticQuickInfoProvider : CommonQuickInf foreach (var linkedDocumentId in linkedDocumentIds) { var linkedDocument = document.Project.Solution.GetRequiredDocument(linkedDocumentId); - var linkedToken = await FindTokenInLinkedDocumentAsync(token, document, linkedDocument, cancellationToken).ConfigureAwait(false); + var linkedToken = await FindTokenInLinkedDocumentAsync(token, linkedDocument, cancellationToken).ConfigureAwait(false); if (linkedToken != default) { @@ -126,7 +126,6 @@ private static bool HasNoErrors(ImmutableArray symbols) private async Task FindTokenInLinkedDocumentAsync( SyntaxToken token, - Document originalDocument, Document linkedDocument, CancellationToken cancellationToken) { diff --git a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs index cf1af4988f457..b75bb04ca790b 100644 --- a/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplaceMethodWithProperty/ReplaceMethodWithPropertyCodeRefactoringProvider.cs @@ -451,7 +451,9 @@ private async Task> GetDefinitionsByD return result; } +#pragma warning disable IDE0060 // Remove unused parameter - Method not completely implemented. private string GetDefinitionIssues(IEnumerable getMethodReferences) +#pragma warning restore IDE0060 // Remove unused parameter { // TODO: add things to be concerned about here. For example: // 1. If any of the referenced symbols are from metadata. diff --git a/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs b/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs index 89e5b6c52cdf9..5d1df64ab547f 100644 --- a/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs +++ b/src/Features/Core/Portable/ReplacePropertyWithMethods/ReplacePropertyWithMethodsCodeRefactoringProvider.cs @@ -187,7 +187,9 @@ private static IFieldSymbol GetBackingField(IPropertySymbol property) name: uniqueName); } +#pragma warning disable IDE0060 // Remove unused parameter - Method not completely implemented. private string GetDefinitionIssues(IEnumerable getMethodReferences) +#pragma warning restore IDE0060 // Remove unused parameter { // TODO: add things to be concerned about here. For example: // 1. If any of the referenced symbols are from metadata. diff --git a/src/Features/Core/Portable/SignatureHelp/AbstractSignatureHelpProvider.cs b/src/Features/Core/Portable/SignatureHelp/AbstractSignatureHelpProvider.cs index d5ccebbf7eb09..426986751ab8e 100644 --- a/src/Features/Core/Portable/SignatureHelp/AbstractSignatureHelpProvider.cs +++ b/src/Features/Core/Portable/SignatureHelp/AbstractSignatureHelpProvider.cs @@ -294,7 +294,7 @@ public async Task GetItemsAsync( .ToList(); var platformData = new SupportedPlatformData(invalidProjectsForCurrentSymbol, totalProjects, document.Project.Solution.Workspace); - finalItems.Add(UpdateItem(item, platformData, expectedSymbol)); + finalItems.Add(UpdateItem(item, platformData)); } return new SignatureHelpItems( @@ -330,7 +330,7 @@ private async Task>>> ExtractSymbolsFromRela return resultSets; } - private SignatureHelpItem UpdateItem(SignatureHelpItem item, SupportedPlatformData platformData, ISymbol symbol) + private SignatureHelpItem UpdateItem(SignatureHelpItem item, SupportedPlatformData platformData) { var platformParts = platformData.ToDisplayParts().ToTaggedText(); if (platformParts.Length == 0) diff --git a/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerLogger.cs b/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerLogger.cs index 36367b2ddd78d..3d1a53fc86528 100644 --- a/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerLogger.cs +++ b/src/Features/Core/Portable/SolutionCrawler/SolutionCrawlerLogger.cs @@ -167,7 +167,7 @@ public static void LogGlobalOperation(LogAggregator logAggregator) public static void LogActiveFileEnqueue(LogAggregator logAggregator) => logAggregator.IncreaseCount(ActiveFileEnqueue); - public static void LogWorkItemEnqueue(LogAggregator logAggregator, ProjectId projectId) + public static void LogWorkItemEnqueue(LogAggregator logAggregator, ProjectId _) => logAggregator.IncreaseCount(ProjectEnqueue); public static void LogWorkItemEnqueue( @@ -279,7 +279,7 @@ public static void LogProcessOpenDocument(LogAggregator logAggregator, Guid docu logAggregator.IncreaseCount(ValueTuple.Create(OpenDocument, documentId)); } - public static void LogProcessActiveFileDocument(LogAggregator logAggregator, Guid documentId, bool processed) + public static void LogProcessActiveFileDocument(LogAggregator logAggregator, Guid _, bool processed) { if (processed) { diff --git a/src/Features/Core/Portable/Structure/BlockStructureServiceWithProviders.cs b/src/Features/Core/Portable/Structure/BlockStructureServiceWithProviders.cs index 9e0e318b7268a..5a14c5f378ea1 100644 --- a/src/Features/Core/Portable/Structure/BlockStructureServiceWithProviders.cs +++ b/src/Features/Core/Portable/Structure/BlockStructureServiceWithProviders.cs @@ -50,7 +50,7 @@ public override async Task GetBlockStructureAsync( await provider.ProvideBlockStructureAsync(context).ConfigureAwait(false); } - return CreateBlockStructure(document, context); + return CreateBlockStructure(context); } public override BlockStructure GetBlockStructure( @@ -62,10 +62,10 @@ public override BlockStructure GetBlockStructure( provider.ProvideBlockStructure(context); } - return CreateBlockStructure(document, context); + return CreateBlockStructure(context); } - private static BlockStructure CreateBlockStructure(Document document, BlockStructureContext context) + private static BlockStructure CreateBlockStructure(BlockStructureContext context) { var options = context.Document.Project.Solution.Workspace.Options; var language = context.Document.Project.Language; diff --git a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb index 70bb06b3f9af2..ec4a4f6c5b54a 100644 --- a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb +++ b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb @@ -59,9 +59,11 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Assert.Equal(referencePath, DirectCast(metadataReference, PortableExecutableReference).FilePath) End Sub +#Disable Warning IDE0060 ' Remove unused parameter - TODO: File a test issue Public Async Sub TestSourceFilePathMappingWithDriveLetters( from As String, [to] As String) +#Enable Warning IDE0060 ' Remove unused parameter Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", diff --git a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb index 72829663ac153..649780f6d401e 100644 --- a/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb +++ b/src/Features/VisualBasic/Portable/ChangeSignature/VisualBasicChangeSignatureService.vb @@ -118,7 +118,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature End If Dim semanticModel = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False) - Dim symbol = TryGetDeclaredSymbol(semanticModel, matchingNode, token, cancellationToken) + Dim symbol = TryGetDeclaredSymbol(semanticModel, matchingNode, cancellationToken) If symbol IsNot Nothing Then Dim selectedIndex = TryGetSelectedIndexFromDeclaration(position, matchingNode) Return (symbol, selectedIndex) @@ -201,7 +201,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ChangeSignature Private Function TryGetDeclaredSymbol(semanticModel As SemanticModel, matchingNode As SyntaxNode, - token As SyntaxToken, cancellationToken As CancellationToken) As ISymbol Select Case matchingNode.Kind() Case SyntaxKind.PropertyBlock diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb index d1944c19fa3e0..3324baf329e7e 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Async/VisualBasicAddAwaitCodeFixProvider.vb @@ -58,14 +58,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async If Not DoesExpressionReturnGenericTaskWhoseArgumentsMatchLeftSide(expression, semanticModel, document.Project, cancellationToken) Then Return Task.FromResult(Of SyntaxNode)(Nothing) End If - Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression, semanticModel, cancellationToken))) + Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression))) Case BC37055 If Not DoesExpressionReturnTask(expression, semanticModel) Then Return Task.FromResult(Of SyntaxNode)(Nothing) End If - Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression, semanticModel, cancellationToken))) + Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression))) Case BC42358 - Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression, semanticModel, cancellationToken))) + Return Task.FromResult(root.ReplaceNode(oldNode, ConverToAwaitExpression(expression))) Case Else Return SpecializedTasks.Null(Of SyntaxNode)() End Select @@ -127,7 +127,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Async semanticModel.Compilation.ClassifyConversion(taskType, returnType).Exists End Function - Private Shared Function ConverToAwaitExpression(expression As ExpressionSyntax, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ExpressionSyntax + Private Shared Function ConverToAwaitExpression(expression As ExpressionSyntax) As ExpressionSyntax Return SyntaxFactory.AwaitExpression(expression.WithoutTrivia().Parenthesize()) _ .WithTriviaFrom(expression) _ .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation) diff --git a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb index ed06e8b463f5f..de02e90d05d79 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectExitContinue/IncorrectExitContinueCodeFixProvider.vb @@ -104,7 +104,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectExitContinue codeActions = New List(Of CodeAction) End If - Dim blockKinds = GetEnclosingContinuableBlockKinds(enclosingblocks, enclosingDeclaration) + Dim blockKinds = GetEnclosingContinuableBlockKinds(enclosingblocks) Dim tokenAfterContinueToken = continueStatement.ContinueKeyword.GetNextToken(includeSkipped:=True) Dim text = document.Text @@ -176,7 +176,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectExitContinue Return kinds.TakeWhile(Function(k) k <> SyntaxKind.FinallyBlock).GroupBy(Function(k) BlockKindToKeywordKind(k)).Select(Function(g) g.First()) End Function - Private Function GetEnclosingContinuableBlockKinds(enclosingblocks As IEnumerable(Of SyntaxNode), enclosingDeclaration As ISymbol) As IEnumerable(Of SyntaxKind) + Private Function GetEnclosingContinuableBlockKinds(enclosingblocks As IEnumerable(Of SyntaxNode)) As IEnumerable(Of SyntaxKind) Return enclosingblocks.TakeWhile(Function(eb) eb.Kind() <> SyntaxKind.FinallyBlock) _ .Where(Function(eb) eb.IsKind(SyntaxKind.WhileBlock, SyntaxKind.SimpleDoLoopBlock, diff --git a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb index 0c79141ba4b24..7cbbd7e684fb7 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/IncorrectFunctionReturnType/IncorrectFunctionReturnTypeCodeFixProvider.vb @@ -55,7 +55,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectFunctionReturnTy If lambdaHeader IsNot Nothing Then Dim rewrittenLambdaHeader = AsyncOrIteratorFunctionReturnTypeFixer.RewriteLambdaHeader(lambdaHeader, semanticModel, cancellationToken) context.RegisterFixes( - Await GetCodeActions(document, lambdaHeader, rewrittenLambdaHeader, semanticModel, cancellationToken).ConfigureAwait(False), + Await GetCodeActions(document, lambdaHeader, rewrittenLambdaHeader, cancellationToken).ConfigureAwait(False), context.Diagnostics) Return End If @@ -64,7 +64,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectFunctionReturnTy If methodStatement IsNot Nothing Then Dim rewrittenMethodStatement = AsyncOrIteratorFunctionReturnTypeFixer.RewriteMethodStatement(methodStatement, semanticModel, cancellationToken) context.RegisterFixes( - Await GetCodeActions(document, methodStatement, rewrittenMethodStatement, semanticModel, cancellationToken).ConfigureAwait(False), + Await GetCodeActions(document, methodStatement, rewrittenMethodStatement, cancellationToken).ConfigureAwait(False), context.Diagnostics) Return End If @@ -75,7 +75,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.IncorrectFunctionReturnTy .FirstOrDefault(Function(c) c.Span.IntersectsWith(span)) End Function - Private Async Function GetCodeActions(document As Document, node As SyntaxNode, rewrittenNode As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As Task(Of IEnumerable(Of CodeAction)) + Private Async Function GetCodeActions(document As Document, node As SyntaxNode, rewrittenNode As SyntaxNode, cancellationToken As CancellationToken) As Task(Of IEnumerable(Of CodeAction)) If rewrittenNode IsNot node Then Dim root = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) Dim newRoot = root.ReplaceNode(node, rewrittenNode) diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb index bc0ea820db6cd..1544fc5eb8a80 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/CrefCompletionProvider.vb @@ -66,7 +66,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers End If Dim semanticModel = Await document.GetSemanticModelForNodeAsync(parentNode, cancellationToken).ConfigureAwait(False) - Dim workspace = document.Project.Solution.Workspace Dim symbols = GetSymbols(token, semanticModel, cancellationToken) If Not symbols.Any() Then @@ -75,7 +74,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Dim text = Await document.GetTextAsync(cancellationToken).ConfigureAwait(False) - Dim items = CreateCompletionItems(workspace, semanticModel, symbols, position) + Dim items = CreateCompletionItems(semanticModel, symbols, position) context.AddItems(items) If IsFirstCrefParameterContext(token) Then @@ -186,14 +185,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers End Function Private Iterator Function CreateCompletionItems( - workspace As Workspace, semanticModel As SemanticModel, + semanticModel As SemanticModel, symbols As IEnumerable(Of ISymbol), position As Integer) As IEnumerable(Of CompletionItem) Dim builder = SharedPools.Default(Of StringBuilder).Allocate() Try For Each symbol In symbols builder.Clear() - Yield CreateCompletionItem(workspace, semanticModel, symbol, position, builder) + Yield CreateCompletionItem(semanticModel, symbol, position, builder) Next Finally SharedPools.Default(Of StringBuilder).ClearAndFree(builder) @@ -201,7 +200,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers End Function Private Function CreateCompletionItem( - workspace As Workspace, semanticModel As SemanticModel, + semanticModel As SemanticModel, symbol As ISymbol, position As Integer, builder As StringBuilder) As CompletionItem If symbol.IsUserDefinedOperator() Then diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/HandlesClauseCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/HandlesClauseCompletionProvider.vb index 7c778b3461d70..ecf66d6cd3d31 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/HandlesClauseCompletionProvider.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/HandlesClauseCompletionProvider.vb @@ -41,7 +41,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers ' Handles or a comma If context.TargetToken.IsChildToken(Of HandlesClauseSyntax)(Function(hc) hc.HandlesKeyword) OrElse context.TargetToken.IsChildSeparatorToken(Function(hc As HandlesClauseSyntax) hc.Events) Then - Return Task.FromResult(GetTopLevelIdentifiersAsync(vbContext, context.TargetToken, cancellationToken)) + Return Task.FromResult(GetTopLevelIdentifiersAsync(vbContext, cancellationToken)) End If ' Handles x. or , x. @@ -60,7 +60,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Private Function GetTopLevelIdentifiersAsync( context As VisualBasicSyntaxContext, - token As SyntaxToken, cancellationToken As CancellationToken ) As ImmutableArray(Of ISymbol) @@ -128,21 +127,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Return ImmutableArray(Of ISymbol).CastUp(result) End Function - Private Function CreateCompletionItem(position As Integer, - symbol As ISymbol, - context As SyntaxContext) As CompletionItem - - Dim texts = CompletionUtilities.GetDisplayAndSuffixAndInsertionText(symbol, context) - - Return SymbolCompletionItem.CreateWithSymbolId( - displayText:=texts.displayText, - displayTextSuffix:=texts.suffix, - insertionText:=texts.insertionText, - symbols:=ImmutableArray.Create(symbol), - contextPosition:=context.Position, - rules:=CompletionItemRules.Default) - End Function - Private Function IsWithEvents(s As ISymbol) As Boolean Dim [property] = TryCast(s, IPropertySymbol) If [property] IsNot Nothing Then diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ExtensionMethodImportCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ExtensionMethodImportCompletionProvider.vb index 52997430a2374..a4b57da1c0500 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ExtensionMethodImportCompletionProvider.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ExtensionMethodImportCompletionProvider.vb @@ -42,7 +42,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers End Function Protected Overrides Function GetImportedNamespaces(location As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ImmutableArray(Of String) - Return ImportCompletionProviderHelper.GetImportedNamespaces(location, semanticModel, cancellationToken) + Return ImportCompletionProviderHelper.GetImportedNamespaces(location, semanticModel) End Function End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ImportCompletionProviderHelper.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ImportCompletionProviderHelper.vb index 71cc1b026e1e4..3d868c3ae8119 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ImportCompletionProviderHelper.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/ImportCompletionProviderHelper.vb @@ -12,7 +12,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers Friend NotInheritable Class ImportCompletionProviderHelper - Public Shared Function GetImportedNamespaces(location As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ImmutableArray(Of String) + Public Shared Function GetImportedNamespaces(location As SyntaxNode, semanticModel As SemanticModel) As ImmutableArray(Of String) Dim builder = ArrayBuilder(Of String).GetInstance() ' Get namespaces from import directives diff --git a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/TypeImportCompletionProvider.vb b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/TypeImportCompletionProvider.vb index dab3e8c875794..26c15b2d50561 100644 --- a/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/TypeImportCompletionProvider.vb +++ b/src/Features/VisualBasic/Portable/Completion/CompletionProviders/ImportCompletionProvider/TypeImportCompletionProvider.vb @@ -36,7 +36,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.Providers End Function Protected Overrides Function GetImportedNamespaces(location As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As ImmutableArray(Of String) - Return ImportCompletionProviderHelper.GetImportedNamespaces(location, semanticModel, cancellationToken) + Return ImportCompletionProviderHelper.GetImportedNamespaces(location, semanticModel) End Function End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/Completion/KeywordRecommenders/RecommendationHelpers.vb b/src/Features/VisualBasic/Portable/Completion/KeywordRecommenders/RecommendationHelpers.vb index 9f77307898a6e..f3e3edc51bd8d 100644 --- a/src/Features/VisualBasic/Portable/Completion/KeywordRecommenders/RecommendationHelpers.vb +++ b/src/Features/VisualBasic/Portable/Completion/KeywordRecommenders/RecommendationHelpers.vb @@ -11,11 +11,6 @@ Imports Microsoft.CodeAnalysis.VisualBasic.Utilities.IntrinsicOperators Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.KeywordRecommenders Friend Module RecommendationHelpers - - Friend Function IsInLambda(syntaxTree As SyntaxTree, token As SyntaxToken) As Boolean - Return token.GetAncestor(Of LambdaExpressionSyntax)() IsNot Nothing - End Function - Friend Function IsOnErrorStatement(node As SyntaxNode) As Boolean Return TypeOf node Is OnErrorGoToStatementSyntax OrElse TypeOf node Is OnErrorResumeNextStatementSyntax End Function diff --git a/src/Features/VisualBasic/Portable/EditAndContinue/BreakpointSpans.vb b/src/Features/VisualBasic/Portable/EditAndContinue/BreakpointSpans.vb index 566e263d036da..a8fb76ddbc6c0 100644 --- a/src/Features/VisualBasic/Portable/EditAndContinue/BreakpointSpans.vb +++ b/src/Features/VisualBasic/Portable/EditAndContinue/BreakpointSpans.vb @@ -189,7 +189,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue Return CreateSpan(node) Case SyntaxKind.SelectClause - Return TryCreateSpanForSelectClause(DirectCast(node, SelectClauseSyntax), position) + Return TryCreateSpanForSelectClause(DirectCast(node, SelectClauseSyntax)) Case SyntaxKind.WhereClause Return TryCreateSpanForWhereClause(DirectCast(node, WhereClauseSyntax)) @@ -417,7 +417,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue Return TextSpan.FromBounds(clause.Keys.First.SpanStart, clause.Span.End) End Function - Private Function TryCreateSpanForSelectClause(clause As SelectClauseSyntax, position As Integer) As TextSpan? + Private Function TryCreateSpanForSelectClause(clause As SelectClauseSyntax) As TextSpan? If clause.Variables.Count = 1 Then Return CreateSpan(clause.Variables.Single.Expression) End If diff --git a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb index 2851670d56e1e..24281bfa8f5d9 100644 --- a/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb +++ b/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb @@ -1806,7 +1806,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue Return Case EditKind.Move - ClassifyMove(_oldNode, _newNode) + ReportError(RudeEditKind.Move) Return Case EditKind.Insert @@ -1823,10 +1823,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue End Sub #Region "Move and Reorder" - Private Sub ClassifyMove(oldNode As SyntaxNode, newNode As SyntaxNode) - ReportError(RudeEditKind.Move) - End Sub - Private Sub ClassifyReorder(oldNode As SyntaxNode, newNode As SyntaxNode) Select Case newNode.Kind Case SyntaxKind.OptionStatement, diff --git a/src/Features/VisualBasic/Portable/EmbeddedLanguages/EmbeddedLanguageUtilities.vb b/src/Features/VisualBasic/Portable/EmbeddedLanguages/EmbeddedLanguageUtilities.vb index b9a143848962a..7e61f5d32c276 100644 --- a/src/Features/VisualBasic/Portable/EmbeddedLanguages/EmbeddedLanguageUtilities.vb +++ b/src/Features/VisualBasic/Portable/EmbeddedLanguages/EmbeddedLanguageUtilities.vb @@ -4,7 +4,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages Friend Module EmbeddedLanguageUtilities - Public Function EscapeText(text As String, token As SyntaxToken) As String + Public Function EscapeText(text As String) As String ' VB has no need to escape any regex characters that would be passed in through this API. Return text End Function diff --git a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb index b8b202ed555ed..8c27c3d84d811 100644 --- a/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb +++ b/src/Features/VisualBasic/Portable/EmbeddedLanguages/VisualBasicEmbeddedLanguageFeaturesProvider.vb @@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Features.EmbeddedLanguages End Sub Friend Overrides Function EscapeText(text As String, token As SyntaxToken) As String - Return EmbeddedLanguageUtilities.EscapeText(text, token) + Return EmbeddedLanguageUtilities.EscapeText(text) End Function End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb index 2c04ae613b13f..cf68d7d329329 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicMethodExtractor.VisualBasicCodeGenerator.vb @@ -104,9 +104,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Dim semanticModel = SemanticDocument.SemanticModel Dim context = InsertionPoint.GetContext() Dim postProcessor = New PostProcessor(semanticModel, context.SpanStart) - Dim statements = SpecializedCollections.EmptyEnumerable(Of StatementSyntax)() - statements = AddSplitOrMoveDeclarationOutStatementsToCallSite(statements, cancellationToken) + Dim statements = AddSplitOrMoveDeclarationOutStatementsToCallSite(cancellationToken) statements = postProcessor.MergeDeclarationStatements(statements) statements = AddAssignmentStatementToCallSite(statements, cancellationToken) statements = Await AddInvocationAtCallSiteAsync(statements, cancellationToken).ConfigureAwait(False) diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.Validator.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.Validator.vb index d270345c09551..9854cac508bca 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.Validator.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.Validator.vb @@ -12,7 +12,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod If TypeOf node Is ExpressionSyntax Then Return CheckExpression(semanticModel, DirectCast(node, ExpressionSyntax), cancellationToken) ElseIf TypeOf node Is StatementSyntax Then - Return CheckStatement(semanticModel, DirectCast(node, StatementSyntax), cancellationToken) + Return CheckStatement(DirectCast(node, StatementSyntax)) Else Return False End If @@ -30,7 +30,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Return expression.CanReplaceWithRValue(semanticModel, cancellationToken) AndAlso Not expression.ContainsImplicitMemberAccess() End Function - Private Shared Function CheckStatement(semanticModel As SemanticModel, statement As StatementSyntax, cancellationToken As CancellationToken) As Boolean + Private Shared Function CheckStatement(statement As StatementSyntax) As Boolean If statement.GetAncestor(Of WithBlockSyntax)() IsNot Nothing Then If statement.ContainsImplicitMemberAccess() Then Return False diff --git a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb index 490241e5a2f7f..04982fcbd8e91 100644 --- a/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb +++ b/src/Features/VisualBasic/Portable/ExtractMethod/VisualBasicSelectionValidator.vb @@ -29,7 +29,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExtractMethod Dim root = SemanticDocument.Root Dim model = Me.SemanticDocument.SemanticModel - Dim selectionInfo = GetInitialSelectionInfo(root, cancellationToken) + Dim selectionInfo = GetInitialSelectionInfo(root) selectionInfo = AssignInitialFinalTokens(selectionInfo, root, cancellationToken) selectionInfo = AdjustFinalTokensBasedOnContext(selectionInfo, model, cancellationToken) selectionInfo = AdjustFinalTokensIfNextStatement(selectionInfo, model, cancellationToken) @@ -449,7 +449,7 @@ result.ReadOutside().Any(Function(s) Equals(s, local)) Then Return clone End Function - Private Function GetInitialSelectionInfo(root As SyntaxNode, cancellationToken As CancellationToken) As SelectionInfo + Private Function GetInitialSelectionInfo(root As SyntaxNode) As SelectionInfo Dim adjustedSpan = GetAdjustedSpan(root, Me.OriginalSpan) Dim firstTokenInSelection = root.FindTokenOnRightOfPosition(adjustedSpan.Start, includeSkipped:=False) Dim lastTokenInSelection = root.FindTokenOnLeftOfPosition(adjustedSpan.End, includeSkipped:=False) diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb index 7a6c06fecf687..f68f3c3423564 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateConversionService.vb @@ -119,7 +119,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod End If methodSymbol = GenerateMethodSymbol(typeToGenerateIn, parameterSymbol) - If Not ValidateTypeToGenerateIn(document.Project.Solution, typeToGenerateIn, True, classInterfaceModuleStructTypes) Then + If Not ValidateTypeToGenerateIn(typeToGenerateIn, True, classInterfaceModuleStructTypes) Then typeToGenerateIn = parameterSymbol End If Return True @@ -134,7 +134,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod End If methodSymbol = GenerateMethodSymbol(typeToGenerateIn, parameterSymbol) - If Not ValidateTypeToGenerateIn(document.Project.Solution, typeToGenerateIn, True, classInterfaceModuleStructTypes) Then + If Not ValidateTypeToGenerateIn(typeToGenerateIn, True, classInterfaceModuleStructTypes) Then typeToGenerateIn = parameterSymbol End If Return True diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb index 992e5f4d5d806..279a1e3e2a737 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb @@ -142,12 +142,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod Protected Overrides Function DetermineParameterOptionality(cancellationToken As CancellationToken) As ImmutableArray(Of Boolean) Return If(Me.InvocationExpression.ArgumentList IsNot Nothing AndAlso Me.InvocationExpression.ArgumentList.GetArgumentCount() > 0, - Me.InvocationExpression.ArgumentList.Arguments.Select(Function(a) DetermineParameterOptionality(a, cancellationToken)).ToImmutableArray(), + Me.InvocationExpression.ArgumentList.Arguments.Select(AddressOf DetermineParameterOptionality).ToImmutableArray(), ImmutableArray(Of Boolean).Empty) End Function - Private Overloads Function DetermineParameterOptionality(argument As ArgumentSyntax, - cancellationToken As CancellationToken) As Boolean + Private Overloads Function DetermineParameterOptionality(argument As ArgumentSyntax) As Boolean Return TypeOf argument Is OmittedArgumentSyntax End Function diff --git a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb index f837349c47de5..84a74671eb38d 100644 --- a/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb +++ b/src/Features/VisualBasic/Portable/GenerateType/VisualBasicGenerateTypeService.vb @@ -457,7 +457,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateType Private Function GetDeclaringNamespace(containers As List(Of String), indexDone As Integer, compilationUnit As CompilationUnitSyntax) As NamespaceStatementSyntax For Each member In compilationUnit.Members - Dim namespaceDeclaration = GetDeclaringNamespace(containers, 0, member) + Dim namespaceDeclaration = GetDeclaringNamespace(containers, indexDone, member) If namespaceDeclaration IsNot Nothing Then Return namespaceDeclaration End If diff --git a/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService_IntroduceLocal.vb b/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService_IntroduceLocal.vb index 3ea3f43ab30f9..ca1d67f4e58f1 100644 --- a/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService_IntroduceLocal.vb +++ b/src/Features/VisualBasic/Portable/IntroduceVariable/VisualBasicIntroduceVariableService_IntroduceLocal.vb @@ -143,7 +143,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable Dim innermostStatements = New HashSet(Of StatementSyntax)(matches.Select(Function(expr) expr.GetAncestorOrThis(Of StatementSyntax)())) If innermostStatements.Count = 1 Then Return IntroduceLocalForSingleOccurrenceIntoBlock( - document, expression, newLocalName, declarationStatement, localAnnotation, allOccurrences, cancellationToken) + document, expression, newLocalName, declarationStatement, allOccurrences, cancellationToken) End If Dim oldInnerMostCommonBlock = matches.FindInnermostCommonExecutableBlock() @@ -164,7 +164,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable expression As ExpressionSyntax, localName As NameSyntax, localDeclaration As LocalDeclarationStatementSyntax, - localAnnotation As SyntaxAnnotation, allOccurrences As Boolean, cancellationToken As CancellationToken) As Document diff --git a/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb b/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb index f6aa4c883ef1d..71d5d51ee3021 100644 --- a/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb +++ b/src/Features/VisualBasic/Portable/ReplaceMethodWithProperty/VisualBasicReplaceMethodWithPropertyService.vb @@ -48,7 +48,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.ReplaceMethodWithP Dim methodBlockOrStatement = GetParentIfBlock(getMethodDeclaration) editor.ReplaceNode(methodBlockOrStatement, - ConvertMethodsToProperty(editor, semanticModel, getAndSetMethods, propertyName, nameChanged)) + ConvertMethodsToProperty(editor, getAndSetMethods, propertyName, nameChanged)) End Sub Private Function GetParentIfBlock(declaration As MethodStatementSyntax) As DeclarationStatementSyntax @@ -61,7 +61,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.ReplaceMethodWithP Private Function ConvertMethodsToProperty( editor As SyntaxEditor, - semanticModel As SemanticModel, getAndSetMethods As GetAndSetMethods, propertyName As String, nameChanged As Boolean) As DeclarationStatementSyntax diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.vb index eee67a742feb3..f2ad58012cdbb 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/AbstractOrdinaryMethodSignatureHelpProvider.vb @@ -2,7 +2,6 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. -Imports System.Threading Imports Microsoft.CodeAnalysis.DocumentationComments Imports Microsoft.CodeAnalysis.LanguageServices Imports Microsoft.CodeAnalysis.SignatureHelp @@ -14,8 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Protected Function ConvertMemberGroupMember(document As Document, member As ISymbol, position As Integer, - semanticModel As SemanticModel, - cancellationToken As CancellationToken) As SignatureHelpItem + semanticModel As SemanticModel) As SignatureHelpItem Dim anonymousTypeDisplayService = document.GetLanguageService(Of IAnonymousTypeDisplayService)() Dim documentationCommentFormattingService = document.GetLanguageService(Of IDocumentationCommentFormattingService)() @@ -28,7 +26,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp GetMemberGroupPreambleParts(member, semanticModel, position), GetSeparatorParts(), GetMemberGroupPostambleParts(member, semanticModel, position), - member.GetParameters().Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()) + member.GetParameters().Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()) End Function Private Function GetMemberGroupPreambleParts(symbol As ISymbol, semanticModel As SemanticModel, position As Integer) As IList(Of SymbolDisplayPart) diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/AbstractVisualBasicSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/AbstractVisualBasicSignatureHelpProvider.vb index 2c43ae872705e..1421a16fd87ef 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/AbstractVisualBasicSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/AbstractVisualBasicSignatureHelpProvider.vb @@ -2,7 +2,6 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. -Imports System.Threading Imports Microsoft.CodeAnalysis.DocumentationComments Imports Microsoft.CodeAnalysis.SignatureHelp @@ -41,7 +40,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Protected Shared Function Convert(parameter As IParameterSymbol, semanticModel As SemanticModel, - position As Integer, documentationCommentFormattingService As IDocumentationCommentFormattingService, cancellationToken As CancellationToken) As SignatureHelpSymbolParameter + position As Integer, documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpSymbolParameter Return New SignatureHelpSymbolParameter( parameter.Name, parameter.IsOptional, diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb index f624a2bd0fec0..7df4802a2c890 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/AttributeSignatureHelpProvider.vb @@ -88,7 +88,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim selectedItem = TryGetSelectedIndex(accessibleConstructors, symbolInfo) Return CreateSignatureHelpItems(accessibleConstructors.Select( - Function(c) Convert(c, within, attribute, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + Function(c) Convert(c, within, attribute, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem) End Function @@ -108,8 +108,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp attribute As AttributeSyntax, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, - documentationCommentFormattingService As IDocumentationCommentFormattingService, - cancellationToken As CancellationToken) As SignatureHelpItem + documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpItem Dim position = attribute.SpanStart Dim namedParameters = constructor.ContainingType.GetAttributeNamedParameters(semanticModel.Compilation, within). OrderBy(Function(s) s.Name). @@ -125,8 +124,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp constructor.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetPreambleParts(constructor, semanticModel, position), GetSeparatorParts(), - GetPostambleParts(constructor), - GetParameters(constructor, semanticModel, position, namedParameters, documentationCommentFormattingService, cancellationToken)) + GetPostambleParts(), + GetParameters(constructor, semanticModel, position, namedParameters, documentationCommentFormattingService)) Return item End Function @@ -134,12 +133,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp semanticModel As SemanticModel, position As Integer, namedParameters As List(Of ISymbol), - documentationCommentFormattingService As IDocumentationCommentFormattingService, - cancellationToken As CancellationToken) As IList(Of SignatureHelpSymbolParameter) + documentationCommentFormattingService As IDocumentationCommentFormattingService) As IList(Of SignatureHelpSymbolParameter) Dim result = New List(Of SignatureHelpSymbolParameter) For Each parameter In constructor.Parameters - result.Add(Convert(parameter, semanticModel, position, documentationCommentFormattingService, cancellationToken)) + result.Add(Convert(parameter, semanticModel, position, documentationCommentFormattingService)) Next For i = 0 To namedParameters.Count - 1 @@ -187,7 +185,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Return result End Function - Private Function GetPostambleParts(method As IMethodSymbol) As IList(Of SymbolDisplayPart) + Private Function GetPostambleParts() As IList(Of SymbolDisplayPart) Return {Punctuation(SyntaxKind.CloseParenToken)} End Function End Class diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/CollectionInitializerSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/CollectionInitializerSignatureHelpProvider.vb index 4ad79d421624b..59b95e56b76dc 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/CollectionInitializerSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/CollectionInitializerSignatureHelpProvider.vb @@ -63,7 +63,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim semanticModel = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False) Return CreateCollectionInitializerSignatureHelpItems( - addMethods.Select(Function(s) ConvertMemberGroupMember(document, s, collectionInitializer.OpenBraceToken.SpanStart, semanticModel, cancellationToken)).ToList(), + addMethods.Select(Function(s) ConvertMemberGroupMember(document, s, collectionInitializer.OpenBraceToken.SpanStart, semanticModel)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken)) End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb index 10e4cc5925f4e..d34dd36af7479 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/FunctionAggregationSignatureHelpProvider.vb @@ -88,7 +88,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim syntaxFacts = document.GetLanguageService(Of ISyntaxFactsService) Return CreateSignatureHelpItems( - accessibleMethods.Select(Function(m) Convert(m, functionAggregation, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + accessibleMethods.Select(Function(m) Convert(m, functionAggregation, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem:=Nothing) End Function @@ -96,22 +96,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp functionAggregation As FunctionAggregationSyntax, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, - documentationCommentFormattingService As IDocumentationCommentFormattingService, - cancellationToken As CancellationToken) As SignatureHelpItem + documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpItem Dim position = functionAggregation.SpanStart Dim item = CreateItem( method, semanticModel, position, anonymousTypeDisplayService, False, method.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), - GetPreambleParts(method, semanticModel, position), + GetPreambleParts(method), GetSeparatorParts(), GetPostambleParts(method, semanticModel, position), - GetParameterParts(method, semanticModel, position, documentationCommentFormattingService, cancellationToken)) + GetParameterParts(method, semanticModel, position, documentationCommentFormattingService)) Return item End Function - Private Function GetPreambleParts(method As IMethodSymbol, semanticModel As SemanticModel, position As Integer) As IList(Of SymbolDisplayPart) + Private Function GetPreambleParts(method As IMethodSymbol) As IList(Of SymbolDisplayPart) Dim result = New List(Of SymbolDisplayPart)() AddExtensionPreamble(method, result) result.AddMethodName(method.Name) @@ -136,7 +135,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp End Function Private Function GetParameterParts(method As IMethodSymbol, semanticModel As SemanticModel, position As Integer, - documentationCommentFormattingService As IDocumentationCommentFormattingService, cancellationToken As CancellationToken) As IList(Of SignatureHelpSymbolParameter) + documentationCommentFormattingService As IDocumentationCommentFormattingService) As IList(Of SignatureHelpSymbolParameter) ' Function () As If method.Parameters.Length <> 1 Then Return SpecializedCollections.EmptyList(Of SignatureHelpSymbolParameter)() diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.NamedType.vb b/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.NamedType.vb index fa3c2097580a4..05b8c444729ee 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.NamedType.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.NamedType.vb @@ -18,7 +18,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Return result End Function - Private Function GetPostambleParts(namedType As INamedTypeSymbol) As IList(Of SymbolDisplayPart) + Private Function GetPostambleParts() As IList(Of SymbolDisplayPart) Return {Punctuation(SyntaxKind.CloseParenToken)} End Function End Class diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb index e928471ea888d..8328a827e00d7 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/GenericNameSignatureHelpProvider.vb @@ -110,11 +110,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim _syntaxFacts = document.GetLanguageService(Of ISyntaxFactsService) Return CreateSignatureHelpItems( - accessibleSymbols.Select(Function(s) Convert(s, genericName, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + accessibleSymbols.Select(Function(s) Convert(s, genericName, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, _syntaxFacts, textSpan, cancellationToken), selectedItem:=Nothing) End Function - Private Overloads Function Convert(symbol As ISymbol, genericName As GenericNameSyntax, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, documentationCommentFormattingService As IDocumentationCommentFormattingService, cancellationToken As CancellationToken) As SignatureHelpItem + Private Overloads Function Convert(symbol As ISymbol, genericName As GenericNameSyntax, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpItem Dim position = genericName.SpanStart Dim item As SignatureHelpItem If TypeOf symbol Is INamedTypeSymbol Then @@ -126,8 +126,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp symbol.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetPreambleParts(namedType, semanticModel, position), GetSeparatorParts(), - GetPostambleParts(namedType), - namedType.TypeParameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()) + GetPostambleParts(), + namedType.TypeParameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()) Else Dim method = DirectCast(symbol, IMethodSymbol) item = CreateItem( @@ -138,7 +138,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp GetPreambleParts(method, semanticModel, position), GetSeparatorParts(), GetPostambleParts(method, semanticModel, position), - method.TypeParameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()) + method.TypeParameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()) End If Return item @@ -146,10 +146,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Private Shared ReadOnly s_minimallyQualifiedFormat As SymbolDisplayFormat = SymbolDisplayFormat.MinimallyQualifiedFormat.WithGenericsOptions(SymbolDisplayFormat.MinimallyQualifiedFormat.GenericsOptions Or SymbolDisplayGenericsOptions.IncludeVariance) - Private Overloads Function Convert(parameter As ITypeParameterSymbol, semanticModel As SemanticModel, position As Integer, documentationCommentFormattingService As IDocumentationCommentFormattingService, cancellationToken As CancellationToken) As SignatureHelpSymbolParameter + Private Overloads Function Convert(parameter As ITypeParameterSymbol, semanticModel As SemanticModel, position As Integer, documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpSymbolParameter Dim parts = New List(Of SymbolDisplayPart) parts.AddRange(parameter.ToMinimalDisplayParts(semanticModel, position, s_minimallyQualifiedFormat)) - AddConstraints(parameter, parts, semanticModel, position, cancellationToken) + AddConstraints(parameter, parts, semanticModel, position) Return New SignatureHelpSymbolParameter( parameter.Name, @@ -161,8 +161,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Private Function AddConstraints(typeParam As ITypeParameterSymbol, parts As List(Of SymbolDisplayPart), semanticModel As SemanticModel, - position As Integer, - cancellationToken As CancellationToken) As IList(Of SymbolDisplayPart) + position As Integer) As IList(Of SymbolDisplayPart) Dim constraintTypes = typeParam.ConstraintTypes Dim constraintCount = TypeParameterSpecialConstraintCount(typeParam) + constraintTypes.Length diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.ElementAccess.vb b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.ElementAccess.vb index 49aa3b2ef00a6..16b8e2d09a90f 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.ElementAccess.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.ElementAccess.vb @@ -30,15 +30,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp End If Return accessibleDefaultProperties.Select( - Function(s) ConvertIndexer(s, leftExpression.SpanStart, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)) + Function(s) ConvertIndexer(s, leftExpression.SpanStart, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)) End Function Private Function ConvertIndexer(indexer As IPropertySymbol, position As Integer, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, - documentationCommentFormattingService As IDocumentationCommentFormattingService, - cancellationToken As CancellationToken) As SignatureHelpItem + documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpItem Dim item = CreateItem( indexer, semanticModel, position, anonymousTypeDisplayService, @@ -47,7 +46,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp GetIndexerPreambleParts(indexer, semanticModel, position), GetSeparatorParts(), GetIndexerPostambleParts(indexer, semanticModel, position), - indexer.Parameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()) + indexer.Parameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()) Return item End Function diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.MemberGroup.vb b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.MemberGroup.vb index f4f2b5e15030b..9210f952b0db9 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.MemberGroup.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.MemberGroup.vb @@ -38,14 +38,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Private Function GetMemberGroupItems(accessibleMembers As ImmutableArray(Of ISymbol), document As Document, invocationExpression As InvocationExpressionSyntax, - semanticModel As SemanticModel, - cancellationToken As CancellationToken) As IEnumerable(Of SignatureHelpItem) + semanticModel As SemanticModel) As IEnumerable(Of SignatureHelpItem) If accessibleMembers.Length = 0 Then Return SpecializedCollections.EmptyEnumerable(Of SignatureHelpItem)() End If Return accessibleMembers.Select( - Function(s) ConvertMemberGroupMember(document, s, invocationExpression.SpanStart, semanticModel, cancellationToken)) + Function(s) ConvertMemberGroupMember(document, s, invocationExpression.SpanStart, semanticModel)) End Function End Class End Namespace diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb index 2a3a99ac70e8f..6920a20478f96 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/InvocationExpressionSignatureHelpProvider.vb @@ -119,7 +119,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim accessibleMembers = New ImmutableArray(Of ISymbol) If memberGroup.Length > 0 Then accessibleMembers = GetAccessibleMembers(invocationExpression, semanticModel, within, memberGroup, cancellationToken) - items.AddRange(GetMemberGroupItems(accessibleMembers, document, invocationExpression, semanticModel, cancellationToken)) + items.AddRange(GetMemberGroupItems(accessibleMembers, document, invocationExpression, semanticModel)) End If If expressionType.IsDelegateType() Then diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.DelegateType.vb b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.DelegateType.vb index bbf2975e8f122..d1428e90fbcfe 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.DelegateType.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.DelegateType.vb @@ -2,7 +2,6 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. -Imports System.Threading Imports Microsoft.CodeAnalysis.DocumentationComments Imports Microsoft.CodeAnalysis.LanguageServices Imports Microsoft.CodeAnalysis.SignatureHelp @@ -16,8 +15,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, documentationCommentFormattingService As IDocumentationCommentFormattingService, - delegateType As INamedTypeSymbol, - cancellationToken As CancellationToken) As (items As IList(Of SignatureHelpItem), selectedItem As Integer?) + delegateType As INamedTypeSymbol) As (items As IList(Of SignatureHelpItem), selectedItem As Integer?) Dim invokeMethod = delegateType.DelegateInvokeMethod If invokeMethod Is Nothing Then Return (Nothing, Nothing) @@ -31,8 +29,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp documentationFactory:=invokeMethod.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), prefixParts:=GetDelegateTypePreambleParts(invokeMethod, semanticModel, position), separatorParts:=GetSeparatorParts(), - suffixParts:=GetDelegateTypePostambleParts(invokeMethod), - parameters:=GetDelegateTypeParameters(invokeMethod, semanticModel, position, cancellationToken)) + suffixParts:=GetDelegateTypePostambleParts(), + parameters:=GetDelegateTypeParameters(invokeMethod, semanticModel, position)) Return (SpecializedCollections.SingletonList(item), 0) End Function @@ -44,7 +42,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Return result End Function - Private Function GetDelegateTypeParameters(invokeMethod As IMethodSymbol, semanticModel As SemanticModel, position As Integer, cancellationToken As CancellationToken) As IList(Of SignatureHelpSymbolParameter) + Private Function GetDelegateTypeParameters(invokeMethod As IMethodSymbol, semanticModel As SemanticModel, position As Integer) As IList(Of SignatureHelpSymbolParameter) Const TargetName As String = "target" Dim parts = New List(Of SymbolDisplayPart)() @@ -85,7 +83,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp displayParts:=parts)} End Function - Private Function GetDelegateTypePostambleParts(invokeMethod As IMethodSymbol) As IList(Of SymbolDisplayPart) + Private Function GetDelegateTypePostambleParts() As IList(Of SymbolDisplayPart) Return {Punctuation(SyntaxKind.CloseParenToken)} End Function End Class diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.NormalType.vb b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.NormalType.vb index a1625f14543e2..6bf2c8f3fc00f 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.NormalType.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.NormalType.vb @@ -33,7 +33,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim documentationCommentFormattingService = document.GetLanguageService(Of IDocumentationCommentFormattingService)() Dim items = accessibleConstructors.Select( - Function(c) ConvertNormalTypeConstructor(c, objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList() + Function(c) ConvertNormalTypeConstructor(c, objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList() Dim currentConstructor = semanticModel.GetSymbolInfo(objectCreationExpression, cancellationToken) Dim selectedItem = TryGetSelectedIndex(accessibleConstructors, currentConstructor) @@ -43,8 +43,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Private Function ConvertNormalTypeConstructor(constructor As IMethodSymbol, objectCreationExpression As ObjectCreationExpressionSyntax, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, - documentationCommentFormattingService As IDocumentationCommentFormattingService, - cancellationToken As CancellationToken) As SignatureHelpItem + documentationCommentFormattingService As IDocumentationCommentFormattingService) As SignatureHelpItem Dim position = objectCreationExpression.SpanStart Dim item = CreateItem( constructor, semanticModel, position, @@ -52,8 +51,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp constructor.IsParams(), constructor.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetNormalTypePreambleParts(constructor, semanticModel, position), GetSeparatorParts(), - GetNormalTypePostambleParts(constructor), - constructor.Parameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()) + GetNormalTypePostambleParts(), + constructor.Parameters.Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()) Return item End Function @@ -64,7 +63,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Return result End Function - Private Function GetNormalTypePostambleParts(method As IMethodSymbol) As IList(Of SymbolDisplayPart) + Private Function GetNormalTypePostambleParts() As IList(Of SymbolDisplayPart) Return {Punctuation(SyntaxKind.CloseParenToken)} End Function End Class diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb index 8067d86d989a9..80c5a5ad1cae2 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/ObjectCreationExpressionSignatureHelpProvider.vb @@ -86,7 +86,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim syntaxFacts = document.GetLanguageService(Of ISyntaxFactsService) Dim itemsAndSelected = If(type.TypeKind = TypeKind.Delegate, - GetDelegateTypeConstructors(objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, type, cancellationToken), + GetDelegateTypeConstructors(objectCreationExpression, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, type), GetNormalTypeConstructors(document, objectCreationExpression, semanticModel, anonymousTypeDisplayService, type, within, cancellationToken)) Return CreateSignatureHelpItems(itemsAndSelected.Items, diff --git a/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb b/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb index d4211c9c41704..4b23f6e4e7ea6 100644 --- a/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb +++ b/src/Features/VisualBasic/Portable/SignatureHelp/RaiseEventStatementSignatureHelpProvider.vb @@ -95,7 +95,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Dim syntaxFacts = document.GetLanguageService(Of ISyntaxFactsService) Return CreateSignatureHelpItems( - allowedEvents.Select(Function(e) Convert(e, raiseEventStatement, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService, cancellationToken)).ToList(), + allowedEvents.Select(Function(e) Convert(e, raiseEventStatement, semanticModel, anonymousTypeDisplayService, documentationCommentFormattingService)).ToList(), textSpan, GetCurrentArgumentState(root, position, syntaxFacts, textSpan, cancellationToken), selectedItem:=Nothing) End Function @@ -104,8 +104,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp raiseEventStatement As RaiseEventStatementSyntax, semanticModel As SemanticModel, anonymousTypeDisplayService As IAnonymousTypeDisplayService, - documentationCommentFormattingService As IDocumentationCommentFormattingService, - cancellationToken As CancellationToken + documentationCommentFormattingService As IDocumentationCommentFormattingService ) As SignatureHelpItem Dim position = raiseEventStatement.SpanStart @@ -119,8 +118,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp eventSymbol.GetDocumentationPartsFactory(semanticModel, position, documentationCommentFormattingService), GetPreambleParts(eventSymbol, semanticModel, position), GetSeparatorParts(), - GetPostambleParts(eventSymbol, semanticModel, position), - type.DelegateInvokeMethod.GetParameters().Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService, cancellationToken)).ToList()) + GetPostambleParts(), + type.DelegateInvokeMethod.GetParameters().Select(Function(p) Convert(p, semanticModel, position, documentationCommentFormattingService)).ToList()) Return item End Function @@ -146,11 +145,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SignatureHelp Return result End Function - Private Function GetPostambleParts( - eventSymbol As IEventSymbol, - semanticModel As SemanticModel, - position As Integer) As IList(Of SymbolDisplayPart) - + Private Function GetPostambleParts() As IList(Of SymbolDisplayPart) Return {Punctuation(SyntaxKind.CloseParenToken)} End Function End Class diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationService.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationService.cs index 08d28d34753f9..45c5bbe355df2 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationService.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationService.cs @@ -382,7 +382,7 @@ public override TDeclarationNode RemoveAttribute( case MemberDeclarationSyntax member: { // Handle all members including types. - var newAttributeLists = RemoveAttributeFromAttributeLists(member.GetAttributes(), attributeToRemove, options, out positionOfRemovedNode, out triviaOfRemovedNode); + var newAttributeLists = RemoveAttributeFromAttributeLists(member.GetAttributes(), attributeToRemove, out positionOfRemovedNode, out triviaOfRemovedNode); var newMember = member.WithAttributeLists(newAttributeLists); return Cast(AppendTriviaAtPosition(newMember, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)); } @@ -390,7 +390,7 @@ public override TDeclarationNode RemoveAttribute( case AccessorDeclarationSyntax accessor: { // Handle accessors - var newAttributeLists = RemoveAttributeFromAttributeLists(accessor.AttributeLists, attributeToRemove, options, out positionOfRemovedNode, out triviaOfRemovedNode); + var newAttributeLists = RemoveAttributeFromAttributeLists(accessor.AttributeLists, attributeToRemove, out positionOfRemovedNode, out triviaOfRemovedNode); var newAccessor = accessor.WithAttributeLists(newAttributeLists); return Cast(AppendTriviaAtPosition(newAccessor, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)); } @@ -398,7 +398,7 @@ public override TDeclarationNode RemoveAttribute( case CompilationUnitSyntax compilationUnit: { // Handle global attributes - var newAttributeLists = RemoveAttributeFromAttributeLists(compilationUnit.AttributeLists, attributeToRemove, options, out positionOfRemovedNode, out triviaOfRemovedNode); + var newAttributeLists = RemoveAttributeFromAttributeLists(compilationUnit.AttributeLists, attributeToRemove, out positionOfRemovedNode, out triviaOfRemovedNode); var newCompilationUnit = compilationUnit.WithAttributeLists(newAttributeLists); return Cast(AppendTriviaAtPosition(newCompilationUnit, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)); } @@ -406,14 +406,14 @@ public override TDeclarationNode RemoveAttribute( case ParameterSyntax parameter: { // Handle parameters - var newAttributeLists = RemoveAttributeFromAttributeLists(parameter.AttributeLists, attributeToRemove, options, out positionOfRemovedNode, out triviaOfRemovedNode); + var newAttributeLists = RemoveAttributeFromAttributeLists(parameter.AttributeLists, attributeToRemove, out positionOfRemovedNode, out triviaOfRemovedNode); var newParameter = parameter.WithAttributeLists(newAttributeLists); return Cast(AppendTriviaAtPosition(newParameter, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)); } case TypeParameterSyntax typeParameter: { - var newAttributeLists = RemoveAttributeFromAttributeLists(typeParameter.AttributeLists, attributeToRemove, options, out positionOfRemovedNode, out triviaOfRemovedNode); + var newAttributeLists = RemoveAttributeFromAttributeLists(typeParameter.AttributeLists, attributeToRemove, out positionOfRemovedNode, out triviaOfRemovedNode); var newTypeParameter = typeParameter.WithAttributeLists(newAttributeLists); return Cast(AppendTriviaAtPosition(newTypeParameter, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)); } @@ -425,7 +425,6 @@ public override TDeclarationNode RemoveAttribute( private static SyntaxList RemoveAttributeFromAttributeLists( SyntaxList attributeLists, SyntaxNode attributeToRemove, - CodeGenerationOptions options, out int positionOfRemovedNode, out SyntaxTriviaList triviaOfRemovedNode) { @@ -550,7 +549,7 @@ public override SyntaxNode CreateFieldDeclaration(IFieldSymbol field, CodeGenera { return destination == CodeGenerationDestination.EnumType ? EnumMemberGenerator.GenerateEnumMemberDeclaration(field, null, options) - : (SyntaxNode)FieldGenerator.GenerateFieldDeclaration(field, destination, options); + : (SyntaxNode)FieldGenerator.GenerateFieldDeclaration(field, options); } public override SyntaxNode CreateMethodDeclaration( @@ -574,7 +573,7 @@ public override SyntaxNode CreateMethodDeclaration( if (method.IsDestructor()) { - return DestructorGenerator.GenerateDestructorDeclaration(method, destination, options); + return DestructorGenerator.GenerateDestructorDeclaration(method, options); } options = options.With(options: options.Options ?? Workspace.Options); @@ -582,17 +581,17 @@ public override SyntaxNode CreateMethodDeclaration( if (method.IsConstructor()) { return ConstructorGenerator.GenerateConstructorDeclaration( - method, destination, Workspace, options, options.ParseOptions); + method, Workspace, options, options.ParseOptions); } else if (method.IsUserDefinedOperator()) { return OperatorGenerator.GenerateOperatorDeclaration( - method, destination, Workspace, options, options.ParseOptions); + method, Workspace, options, options.ParseOptions); } else if (method.IsConversion()) { return ConversionGenerator.GenerateConversionDeclaration( - method, destination, Workspace, options, options.ParseOptions); + method, Workspace, options, options.ParseOptions); } else if (method.IsLocalFunction()) { @@ -625,7 +624,7 @@ public override SyntaxNode CreateNamespaceDeclaration( return NamespaceGenerator.GenerateNamespaceDeclaration(this, @namespace, options, cancellationToken); } - private static TDeclarationNode UpdateDeclarationModifiers(TDeclarationNode declaration, Func computeNewModifiersList, CodeGenerationOptions options) + private static TDeclarationNode UpdateDeclarationModifiers(TDeclarationNode declaration, Func computeNewModifiersList) => declaration switch { BaseTypeDeclarationSyntax typeDeclaration => Cast(typeDeclaration.WithModifiers(computeNewModifiersList(typeDeclaration.Modifiers))), @@ -638,13 +637,13 @@ private static TDeclarationNode UpdateDeclarationModifiers(TDe public override TDeclarationNode UpdateDeclarationModifiers(TDeclarationNode declaration, IEnumerable newModifiers, CodeGenerationOptions options, CancellationToken cancellationToken) { SyntaxTokenList computeNewModifiersList(SyntaxTokenList modifiersList) => newModifiers.ToSyntaxTokenList(); - return UpdateDeclarationModifiers(declaration, computeNewModifiersList, options); + return UpdateDeclarationModifiers(declaration, computeNewModifiersList); } public override TDeclarationNode UpdateDeclarationAccessibility(TDeclarationNode declaration, Accessibility newAccessibility, CodeGenerationOptions options, CancellationToken cancellationToken) { SyntaxTokenList computeNewModifiersList(SyntaxTokenList modifiersList) => UpdateDeclarationAccessibility(modifiersList, newAccessibility, options); - return UpdateDeclarationModifiers(declaration, computeNewModifiersList, options); + return UpdateDeclarationModifiers(declaration, computeNewModifiersList); } private static SyntaxTokenList UpdateDeclarationAccessibility(SyntaxTokenList modifiersList, Accessibility newAccessibility, CodeGenerationOptions options) diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpDeclarationComparer.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpDeclarationComparer.cs index b1214ca1f3dac..5785c396a4ec9 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpDeclarationComparer.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpDeclarationComparer.cs @@ -318,7 +318,7 @@ private enum Accessibility Private } - private static int GetAccessibilityPrecedence(SyntaxNode declaration, SyntaxNode parent, SyntaxTokenList modifiers) + private static int GetAccessibilityPrecedence(SyntaxTokenList modifiers, SyntaxNode parent) { if (ContainsToken(modifiers, SyntaxKind.PublicKeyword)) { @@ -392,8 +392,8 @@ private static bool EqualReadOnlyness(SyntaxTokenList x, SyntaxTokenList y, out private static bool EqualAccessibility(SyntaxNode x, SyntaxTokenList xModifiers, SyntaxNode y, SyntaxTokenList yModifiers, out int comparisonResult) { - var xAccessibility = GetAccessibilityPrecedence(x, x.Parent ?? y.Parent, xModifiers); - var yAccessibility = GetAccessibilityPrecedence(y, y.Parent ?? x.Parent, yModifiers); + var xAccessibility = GetAccessibilityPrecedence(xModifiers, x.Parent ?? y.Parent); + var yAccessibility = GetAccessibilityPrecedence(yModifiers, y.Parent ?? x.Parent); comparisonResult = xAccessibility - yAccessibility; return comparisonResult == 0; diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/ConstructorGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/ConstructorGenerator.cs index 7852e985989b3..d640db82a6845 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/ConstructorGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/ConstructorGenerator.cs @@ -29,7 +29,7 @@ internal static TypeDeclarationSyntax AddConstructorTo( IList availableIndices) { var constructorDeclaration = GenerateConstructorDeclaration( - constructor, GetDestination(destination), workspace, options, + constructor, workspace, options, destination?.SyntaxTree.Options ?? options.ParseOptions); // Generate after the last constructor, or after the last field, or at the start of the @@ -41,8 +41,10 @@ internal static TypeDeclarationSyntax AddConstructorTo( } internal static ConstructorDeclarationSyntax GenerateConstructorDeclaration( - IMethodSymbol constructor, CodeGenerationDestination destination, - Workspace workspace, CodeGenerationOptions options, ParseOptions parseOptions) + IMethodSymbol constructor, + Workspace workspace, + CodeGenerationOptions options, + ParseOptions parseOptions) { options ??= CodeGenerationOptions.Default; diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs index 861aabc0233a7..6850cc8db48d1 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/ConversionGenerator.cs @@ -23,7 +23,7 @@ internal static TypeDeclarationSyntax AddConversionTo( IList availableIndices) { var methodDeclaration = GenerateConversionDeclaration( - method, GetDestination(destination), workspace, options, + method, workspace, options, destination?.SyntaxTree.Options ?? options.ParseOptions); var members = Insert(destination.Members, methodDeclaration, options, availableIndices, after: LastOperator); @@ -33,19 +33,17 @@ internal static TypeDeclarationSyntax AddConversionTo( internal static ConversionOperatorDeclarationSyntax GenerateConversionDeclaration( IMethodSymbol method, - CodeGenerationDestination destination, Workspace workspace, CodeGenerationOptions options, ParseOptions parseOptions) { - var declaration = GenerateConversionDeclarationWorker(method, destination, workspace, options, parseOptions); + var declaration = GenerateConversionDeclarationWorker(method, workspace, options, parseOptions); return AddFormatterAndCodeGeneratorAnnotationsTo(AddAnnotationsTo(method, ConditionallyAddDocumentationCommentTo(declaration, method, options))); } private static ConversionOperatorDeclarationSyntax GenerateConversionDeclarationWorker( IMethodSymbol method, - CodeGenerationDestination destination, Workspace workspace, CodeGenerationOptions options, ParseOptions parseOptions) @@ -64,7 +62,7 @@ private static ConversionOperatorDeclarationSyntax GenerateConversionDeclaration var declaration = SyntaxFactory.ConversionOperatorDeclaration( attributeLists: AttributeGenerator.GenerateAttributeLists(method.GetAttributes(), options), - modifiers: GenerateModifiers(method), + modifiers: GenerateModifiers(), implicitOrExplicitKeyword: keyword, operatorKeyword: SyntaxFactory.Token(SyntaxKind.OperatorKeyword), type: method.ReturnType.GenerateTypeSyntax(), @@ -97,7 +95,7 @@ private static ConversionOperatorDeclarationSyntax UseExpressionBodyIfDesired( return declaration; } - private static SyntaxTokenList GenerateModifiers(IMethodSymbol method) + private static SyntaxTokenList GenerateModifiers() { return SyntaxFactory.TokenList( SyntaxFactory.Token(SyntaxKind.PublicKeyword), diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/DestructorGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/DestructorGenerator.cs index ba855747a261c..204276c76f85d 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/DestructorGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/DestructorGenerator.cs @@ -23,7 +23,7 @@ internal static TypeDeclarationSyntax AddDestructorTo( CodeGenerationOptions options, IList availableIndices) { - var destructorDeclaration = GenerateDestructorDeclaration(destructor, GetDestination(destination), options); + var destructorDeclaration = GenerateDestructorDeclaration(destructor, options); // Generate after the last constructor, or after the last field, or at the start of the // type. @@ -34,7 +34,7 @@ internal static TypeDeclarationSyntax AddDestructorTo( } internal static DestructorDeclarationSyntax GenerateDestructorDeclaration( - IMethodSymbol destructor, CodeGenerationDestination destination, CodeGenerationOptions options) + IMethodSymbol destructor, CodeGenerationOptions options) { options ??= CodeGenerationOptions.Default; diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/FieldGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/FieldGenerator.cs index b0bccaa8e0e4e..497996972650c 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/FieldGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/FieldGenerator.cs @@ -52,7 +52,7 @@ internal static CompilationUnitSyntax AddFieldTo( CodeGenerationOptions options, IList availableIndices) { - var declaration = GenerateFieldDeclaration(field, CodeGenerationDestination.CompilationUnit, options); + var declaration = GenerateFieldDeclaration(field, options); // Place the field after the last field or const, or at the start of the type // declaration. @@ -67,7 +67,7 @@ internal static TypeDeclarationSyntax AddFieldTo( CodeGenerationOptions options, IList availableIndices) { - var declaration = GenerateFieldDeclaration(field, GetDestination(destination), options); + var declaration = GenerateFieldDeclaration(field, options); // Place the field after the last field or const, or at the start of the type // declaration. @@ -78,7 +78,7 @@ internal static TypeDeclarationSyntax AddFieldTo( } public static FieldDeclarationSyntax GenerateFieldDeclaration( - IFieldSymbol field, CodeGenerationDestination destination, CodeGenerationOptions options) + IFieldSymbol field, CodeGenerationOptions options) { var reusableSyntax = GetReuseableSyntaxNodeForSymbol(field, options); if (reusableSyntax != null) diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/OperatorGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/OperatorGenerator.cs index 9bc557aa44847..90487775b8ad8 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/OperatorGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/OperatorGenerator.cs @@ -24,7 +24,7 @@ internal static TypeDeclarationSyntax AddOperatorTo( IList availableIndices) { var methodDeclaration = GenerateOperatorDeclaration( - method, GetDestination(destination), workspace, options, + method, workspace, options, destination?.SyntaxTree.Options ?? options.ParseOptions); var members = Insert(destination.Members, methodDeclaration, options, availableIndices, after: LastOperator); @@ -34,7 +34,6 @@ internal static TypeDeclarationSyntax AddOperatorTo( internal static OperatorDeclarationSyntax GenerateOperatorDeclaration( IMethodSymbol method, - CodeGenerationDestination destination, Workspace workspace, CodeGenerationOptions options, ParseOptions parseOptions) @@ -88,7 +87,7 @@ private static OperatorDeclarationSyntax GenerateOperatorDeclarationWorker( var operatorDecl = SyntaxFactory.OperatorDeclaration( attributeLists: AttributeGenerator.GenerateAttributeLists(method.GetAttributes(), options), - modifiers: GenerateModifiers(method), + modifiers: GenerateModifiers(), returnType: method.ReturnType.GenerateTypeSyntax(), operatorKeyword: SyntaxFactory.Token(SyntaxKind.OperatorKeyword), operatorToken: operatorToken, @@ -119,7 +118,7 @@ private static OperatorDeclarationSyntax UseExpressionBodyIfDesired( return operatorDeclaration; } - private static SyntaxTokenList GenerateModifiers(IMethodSymbol method) + private static SyntaxTokenList GenerateModifiers() { return SyntaxFactory.TokenList( SyntaxFactory.Token(SyntaxKind.PublicKeyword), diff --git a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs index 41b15b10d60ae..e79f3f3686b28 100644 --- a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs +++ b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs @@ -222,7 +222,7 @@ public override SyntaxToken VisitToken(SyntaxToken token) token.ValueText == _replacementText || isOldText || _possibleNameConflicts.Contains(token.ValueText) || - IsPossiblyDestructorConflict(token, _replacementText); + IsPossiblyDestructorConflict(token); if (tokenNeedsConflictCheck) { @@ -237,7 +237,7 @@ public override SyntaxToken VisitToken(SyntaxToken token) return newToken; } - private bool IsPossiblyDestructorConflict(SyntaxToken token, string replacementText) + private bool IsPossiblyDestructorConflict(SyntaxToken token) { return _replacementText == "Finalize" && token.IsKind(SyntaxKind.IdentifierToken) && diff --git a/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpParenthesizedPatternReducer.cs b/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpParenthesizedPatternReducer.cs index 6c3146a08dbca..4cf796bf94ad8 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpParenthesizedPatternReducer.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/Reducers/CSharpParenthesizedPatternReducer.cs @@ -31,7 +31,7 @@ private static SyntaxNode SimplifyParentheses( OptionSet optionSet, CancellationToken cancellationToken) { - if (node.CanRemoveParentheses(semanticModel)) + if (node.CanRemoveParentheses()) { var resultNode = CSharpSyntaxFacts.Instance.Unparenthesize(node); return SimplificationHelpers.CopyAnnotations(from: node, to: resultNode); diff --git a/src/Workspaces/CSharpTest/OrganizeImports/OrganizeUsingsTests.cs b/src/Workspaces/CSharpTest/OrganizeImports/OrganizeUsingsTests.cs index 13e985ffb840d..03edc3439344b 100644 --- a/src/Workspaces/CSharpTest/OrganizeImports/OrganizeUsingsTests.cs +++ b/src/Workspaces/CSharpTest/OrganizeImports/OrganizeUsingsTests.cs @@ -20,8 +20,7 @@ public class OrganizeUsingsTests protected async Task CheckAsync( string initial, string final, bool placeSystemNamespaceFirst = false, - bool separateImportGroups = false, - CSharpParseOptions options = null) + bool separateImportGroups = false) { using var workspace = new AdhocWorkspace(); var project = workspace.CurrentSolution.AddProject("Project", "Project.dll", LanguageNames.CSharp); diff --git a/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs b/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs index 966c618a7e61c..e8dc573119dc5 100644 --- a/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs +++ b/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs @@ -32,7 +32,6 @@ internal DeclarationModifiers( bool isWithEvents = false, bool isPartial = false, bool isAsync = false, - bool isWriteOnly = false, bool isRef = false, bool isVolatile = false, bool isExtern = false) diff --git a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs index 40015bfaed7c0..dc2f91648175b 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/Declarations/DeclarationFinder.cs @@ -102,7 +102,7 @@ private static async Task AddMetadataDeclarationsWithNormalQueryAsync( project.Solution, referenceOpt, loadOnly: false, cancellationToken: cancellationToken).ConfigureAwait(false); var symbols = await info.FindAsync( - query, assembly, project.Id, filter, cancellationToken).ConfigureAwait(false); + query, assembly, filter, cancellationToken).ConfigureAwait(false); list.AddRange(symbols); } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs index a579c38b46247..f07dbe2783913 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs @@ -63,8 +63,6 @@ public static IAliasSymbol GetAliasInfo( public static ImmutableArray GetIdentifierOrGlobalNamespaceTokensWithText( ISyntaxFactsService syntaxFacts, - Document document, - VersionStamp version, SemanticModel model, SyntaxNode root, SourceText sourceText, @@ -76,22 +74,22 @@ public static ImmutableArray GetIdentifierOrGlobalNamespaceTokensWi var entry = GetCachedEntry(model); if (entry == null) { - return GetIdentifierOrGlobalNamespaceTokensWithText(syntaxFacts, document, version, root, sourceText, normalized, cancellationToken); + return GetIdentifierOrGlobalNamespaceTokensWithText(syntaxFacts, root, sourceText, normalized, cancellationToken); } return entry.IdentifierCache.GetOrAdd(normalized, key => GetIdentifierOrGlobalNamespaceTokensWithText( - syntaxFacts, document, version, root, sourceText, key, cancellationToken)); + syntaxFacts, root, sourceText, key, cancellationToken)); } private static ImmutableArray GetIdentifierOrGlobalNamespaceTokensWithText( - ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SyntaxNode root, SourceText sourceText, + ISyntaxFactsService syntaxFacts, SyntaxNode root, SourceText sourceText, string text, CancellationToken cancellationToken) { // identifier is not escaped if (sourceText != null) { - return GetTokensFromText(syntaxFacts, document, version, root, sourceText, text, IsCandidate, cancellationToken); + return GetTokensFromText(syntaxFacts, root, sourceText, text, IsCandidate, cancellationToken); } // identifier is escaped @@ -101,18 +99,14 @@ bool IsCandidate(SyntaxToken t) => syntaxFacts.IsGlobalNamespaceKeyword(t) || (syntaxFacts.IsIdentifier(t) && syntaxFacts.TextMatch(t.ValueText, text)); } - private static ImmutableArray GetTokensFromText( - ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SyntaxNode root, - SourceText content, string text, Func candidate, CancellationToken cancellationToken) - { - return text.Length > 0 - ? GetTokensFromText(syntaxFacts, root, content, text, candidate, cancellationToken) - : ImmutableArray.Empty; - } - private static ImmutableArray GetTokensFromText( ISyntaxFactsService syntaxFacts, SyntaxNode root, SourceText content, string text, Func candidate, CancellationToken cancellationToken) { + if (text.Length == 0) + { + return ImmutableArray.Empty; + } + var result = ImmutableArray.CreateBuilder(); var index = 0; diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs index 87a98b6571a93..9606c3831914a 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/AbstractReferenceFinder.cs @@ -194,14 +194,13 @@ protected static async Task> GetIdentifierOrGlobalNa return ImmutableArray.Empty; var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false); - var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false); SourceText text = null; if (!info.ProbablyContainsEscapedIdentifier(identifier)) text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); return FindReferenceCache.GetIdentifierOrGlobalNamespaceTokensWithText( - syntaxFacts, document, version, semanticModel, root, text, identifier, cancellationToken); + syntaxFacts, semanticModel, root, text, identifier, cancellationToken); } protected static Func GetStandardSymbolsMatchFunction( diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs index 0e2c5729aa156..650f1556b6195 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ParameterSymbolReferenceFinder.cs @@ -226,9 +226,7 @@ private void CascadeBetweenPropertyAndAccessorParameters( { if (containingMethod.AssociatedSymbol is IPropertySymbol property) { - AddParameterAtIndex( - parameter, results, - ordinal, property.Parameters); + AddParameterAtIndex(results, ordinal, property.Parameters); } } else if (containingSymbol is IPropertySymbol containingProperty) @@ -261,24 +259,19 @@ private void CascadeBetweenDelegateMethodParameters( var beginInvokeMethod = containingType.GetMembers(WellKnownMemberNames.DelegateBeginInvokeName) .OfType() .FirstOrDefault(); - AddParameterAtIndex( - parameter, results, - ordinal, beginInvokeMethod?.Parameters); + AddParameterAtIndex(results, ordinal, beginInvokeMethod?.Parameters); } else if (containingMethod.ContainingType.IsDelegateType() && containingMethod.Name == WellKnownMemberNames.DelegateBeginInvokeName) { // cascade to the corresponding parameter in the Invoke method. - AddParameterAtIndex( - parameter, results, - ordinal, containingType.DelegateInvokeMethod?.Parameters); + AddParameterAtIndex(results, ordinal, containingType.DelegateInvokeMethod?.Parameters); } } } } private static void AddParameterAtIndex( - IParameterSymbol parameter, ArrayBuilder results, int ordinal, ImmutableArray? parameters) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs index 7c4a120f64c86..cce967d399373 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/NoOpStreamingFindReferencesProgress.cs @@ -22,7 +22,9 @@ private NoOpStreamingFindReferencesProgress() { } +#pragma warning disable IDE0060 // Remove unused parameter public Task ReportProgressAsync(int current, int maximum) => Task.CompletedTask; +#pragma warning restore IDE0060 // Remove unused parameter public Task OnCompletedAsync() => Task.CompletedTask; public Task OnStartedAsync() => Task.CompletedTask; diff --git a/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs b/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs index 9d4ea03d84a01..ea7f10c93ca4c 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/ReferenceLocationExtensions.cs @@ -34,7 +34,7 @@ public static async Task>> FindReferencingSym { var document = documentGroup.Key; var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - AddSymbols(document, semanticModel, documentGroup, result); + AddSymbols(semanticModel, documentGroup, result); } GC.KeepAlive(compilation); @@ -45,7 +45,6 @@ public static async Task>> FindReferencingSym } private static void AddSymbols( - Document document, SemanticModel semanticModel, IEnumerable references, Dictionary> result) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs index 97a7b4ed55349..163a6c3608716 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolTree/SymbolTreeInfo.cs @@ -168,7 +168,7 @@ public SymbolTreeInfo WithChecksum(Checksum checksum) } public Task> FindAsync( - SearchQuery query, IAssemblySymbol assembly, ProjectId assemblyProjectId, SymbolFilter filter, CancellationToken cancellationToken) + SearchQuery query, IAssemblySymbol assembly, SymbolFilter filter, CancellationToken cancellationToken) { // All entrypoints to this function are Find functions that are only searching // for specific strings (i.e. they never do a custom search). diff --git a/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingLogger.cs b/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingLogger.cs index e11dbe482768c..43635580240b8 100644 --- a/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingLogger.cs +++ b/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingLogger.cs @@ -24,7 +24,7 @@ internal enum MergeInfo InsertedMergeConflictCommentsAtAdjustedLocation } - internal static void LogSession(Workspace workspace, LinkedFileDiffMergingSessionInfo sessionInfo) + internal static void LogSession(LinkedFileDiffMergingSessionInfo sessionInfo) { if (sessionInfo.LinkedFileGroups.Count > 1) { diff --git a/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingSession.cs b/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingSession.cs index 7d5674962ed12..c20824015693a 100644 --- a/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingSession.cs +++ b/src/Workspaces/Core/Portable/LinkedFileDiffMerging/LinkedFileDiffMergingSession.cs @@ -324,7 +324,7 @@ private void LogLinkedFileDiffMergingSessionInfo(LinkedFileDiffMergingSessionInf return; } - LinkedFileDiffMergingLogger.LogSession(this._newSolution.Workspace, sessionInfo); + LinkedFileDiffMergingLogger.LogSession(sessionInfo); } internal class LinkedFileDiffMergingSessionInfo diff --git a/src/Workspaces/Core/Portable/Options/EditorConfig/EditorConfigDocumentOptionsProviderFactory.cs b/src/Workspaces/Core/Portable/Options/EditorConfig/EditorConfigDocumentOptionsProviderFactory.cs index 7396f5948d843..1da1804f55e7d 100644 --- a/src/Workspaces/Core/Portable/Options/EditorConfig/EditorConfigDocumentOptionsProviderFactory.cs +++ b/src/Workspaces/Core/Portable/Options/EditorConfig/EditorConfigDocumentOptionsProviderFactory.cs @@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.Options.EditorConfig { internal static class EditorConfigDocumentOptionsProviderFactory { - public static IDocumentOptionsProvider Create(Workspace workspace) + public static IDocumentOptionsProvider Create() => new EditorConfigDocumentOptionsProvider(); private const string LocalRegistryPath = @"Roslyn\Internal\OnOff\Features\"; diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs index b966e94f7c57e..5ad54377dde24 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.Session.cs @@ -320,7 +320,7 @@ private async Task IdentifyConflictsAsync( var newDocument = conflictResolution.CurrentSolution.GetDocument(documentId); var syntaxRoot = await newDocument.GetSyntaxRootAsync(_cancellationToken).ConfigureAwait(false); - var nodesOrTokensWithConflictCheckAnnotations = GetNodesOrTokensToCheckForConflicts(documentId, syntaxRoot); + var nodesOrTokensWithConflictCheckAnnotations = GetNodesOrTokensToCheckForConflicts(syntaxRoot); foreach (var (syntax, annotation) in nodesOrTokensWithConflictCheckAnnotations) { if (annotation.IsRenameLocation) @@ -352,7 +352,7 @@ private async Task IdentifyConflictsAsync( var syntaxFactsService = newDocument.Project.LanguageServices.GetService(); // Get all tokens that need conflict check - var nodesOrTokensWithConflictCheckAnnotations = GetNodesOrTokensToCheckForConflicts(documentId, syntaxRoot); + var nodesOrTokensWithConflictCheckAnnotations = GetNodesOrTokensToCheckForConflicts(syntaxRoot); var complexifiedLocationSpanForThisDocument = _conflictLocations @@ -440,7 +440,7 @@ private async Task IdentifyConflictsAsync( var baseDocument = conflictResolution.OldSolution.GetDocument(unprocessedDocumentIdWithPotentialDeclarationConflicts); var baseSyntaxTree = await baseDocument.GetSyntaxTreeAsync(_cancellationToken).ConfigureAwait(false); - var nodesOrTokensWithConflictCheckAnnotations = GetNodesOrTokensToCheckForConflicts(unprocessedDocumentIdWithPotentialDeclarationConflicts, syntaxRoot); + var nodesOrTokensWithConflictCheckAnnotations = GetNodesOrTokensToCheckForConflicts(syntaxRoot); foreach (var (syntax, annotation) in nodesOrTokensWithConflictCheckAnnotations) { var tokenOrNode = syntax; @@ -494,7 +494,6 @@ private bool IsConflictFreeChange( /// Gets the list of the nodes that were annotated for a conflict check /// private IEnumerable<(SyntaxNodeOrToken syntax, RenameActionAnnotation annotation)> GetNodesOrTokensToCheckForConflicts( - DocumentId documentId, SyntaxNode syntaxRoot) { return syntaxRoot.DescendantNodesAndTokens(descendIntoTrivia: true) diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs b/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs index 1631b53c1d1c3..0628d4e288cb8 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs @@ -470,7 +470,7 @@ private static async Task AddLocationsToRenameInStringsAsync( if (renameStringsAndPositions.Any()) { AddLocationsToRenameInStringsAndComments(document, root.SyntaxTree, renameText, - renameStringsAndPositions, renameLocations, isRenameInStrings: true, isRenameInComments: false); + renameStringsAndPositions, renameLocations); } } @@ -488,7 +488,7 @@ private static async Task AddLocationsToRenameInCommentsAsync( if (renameStringsAndPositions.Any()) { AddLocationsToRenameInStringsAndComments(document, root.SyntaxTree, renameText, - renameStringsAndPositions, renameLocations, isRenameInStrings: false, isRenameInComments: true); + renameStringsAndPositions, renameLocations); } } @@ -497,9 +497,7 @@ private static void AddLocationsToRenameInStringsAndComments( SyntaxTree tree, string renameText, IEnumerable> renameStringsAndPositions, - ArrayBuilder renameLocations, - bool isRenameInStrings, - bool isRenameInComments) + ArrayBuilder renameLocations) { var regex = GetRegexForMatch(renameText); foreach (var renameStringAndPosition in renameStringsAndPositions) diff --git a/src/Workspaces/Core/Portable/Rename/Renamer.RenameSymbolDocumentAction.cs b/src/Workspaces/Core/Portable/Rename/Renamer.RenameSymbolDocumentAction.cs index 9311b901a2be3..083b6944d3bd6 100644 --- a/src/Workspaces/Core/Portable/Rename/Renamer.RenameSymbolDocumentAction.cs +++ b/src/Workspaces/Core/Portable/Rename/Renamer.RenameSymbolDocumentAction.cs @@ -47,7 +47,6 @@ internal override async Task GetModifiedSolutionAsync(Document documen // that are the same name as the analysis var matchingTypeDeclaration = await GetMatchingTypeDeclarationAsync( document.WithName(_analysis.OriginalDocumentName), - _analysis.OriginalSymbolName, cancellationToken).ConfigureAwait(false); if (matchingTypeDeclaration is object) @@ -65,7 +64,7 @@ internal override async Task GetModifiedSolutionAsync(Document documen /// Finds a matching type such that the display name of the type matches the name passed in, ignoring case. Case isn't used because /// documents with name "Foo.cs" and "foo.cs" should still have the same type name /// - private static async Task GetMatchingTypeDeclarationAsync(Document document, string name, CancellationToken cancellationToken) + private static async Task GetMatchingTypeDeclarationAsync(Document document, CancellationToken cancellationToken) { var syntaxRoot = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var syntaxFacts = document.GetRequiredLanguageService(); @@ -95,7 +94,7 @@ internal override async Task GetModifiedSolutionAsync(Document documen return null; } - var matchingDeclaration = await GetMatchingTypeDeclarationAsync(document, originalSymbolName, cancellationToken).ConfigureAwait(false); + var matchingDeclaration = await GetMatchingTypeDeclarationAsync(document, cancellationToken).ConfigureAwait(false); if (matchingDeclaration is null) { diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs index 52c58cf0925c4..6ede4a98ebf46 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ISymbolExtensions.cs @@ -107,10 +107,10 @@ private static bool IsBrowsingProhibited( return false; } - return IsBrowsingProhibitedByEditorBrowsableAttribute(symbol, attributes, hideAdvancedMembers, compilation, editorBrowsableAttributeConstructor) - || IsBrowsingProhibitedByTypeLibTypeAttribute(symbol, attributes, compilation, typeLibTypeAttributeConstructors) - || IsBrowsingProhibitedByTypeLibFuncAttribute(symbol, attributes, compilation, typeLibFuncAttributeConstructors) - || IsBrowsingProhibitedByTypeLibVarAttribute(symbol, attributes, compilation, typeLibVarAttributeConstructors) + return IsBrowsingProhibitedByEditorBrowsableAttribute(attributes, hideAdvancedMembers, compilation, editorBrowsableAttributeConstructor) + || IsBrowsingProhibitedByTypeLibTypeAttribute(attributes, compilation, typeLibTypeAttributeConstructors) + || IsBrowsingProhibitedByTypeLibFuncAttribute(attributes, compilation, typeLibFuncAttributeConstructors) + || IsBrowsingProhibitedByTypeLibVarAttribute(attributes, compilation, typeLibVarAttributeConstructors) || IsBrowsingProhibitedByHideModuleNameAttribute(symbol, compilation, hideModuleNameAttribute, attributes); } @@ -136,7 +136,7 @@ private static bool IsBrowsingProhibitedByHideModuleNameAttribute( } private static bool IsBrowsingProhibitedByEditorBrowsableAttribute( - ISymbol symbol, ImmutableArray attributes, bool hideAdvancedMembers, Compilation compilation, IMethodSymbol? constructor) + ImmutableArray attributes, bool hideAdvancedMembers, Compilation compilation, IMethodSymbol? constructor) { constructor ??= EditorBrowsableHelpers.GetSpecialEditorBrowsableAttributeConstructor(compilation); if (constructor == null) @@ -166,30 +166,27 @@ private static bool IsBrowsingProhibitedByEditorBrowsableAttribute( } private static bool IsBrowsingProhibitedByTypeLibTypeAttribute( - ISymbol symbol, ImmutableArray attributes, Compilation compilation, List? constructors) + ImmutableArray attributes, Compilation compilation, List? constructors) { return IsBrowsingProhibitedByTypeLibAttributeWorker( - symbol, attributes, constructors ?? EditorBrowsableHelpers.GetSpecialTypeLibTypeAttributeConstructors(compilation), TypeLibTypeFlagsFHidden); } private static bool IsBrowsingProhibitedByTypeLibFuncAttribute( - ISymbol symbol, ImmutableArray attributes, Compilation compilation, List? constructors) + ImmutableArray attributes, Compilation compilation, List? constructors) { return IsBrowsingProhibitedByTypeLibAttributeWorker( - symbol, attributes, constructors ?? EditorBrowsableHelpers.GetSpecialTypeLibFuncAttributeConstructors(compilation), TypeLibFuncFlagsFHidden); } private static bool IsBrowsingProhibitedByTypeLibVarAttribute( - ISymbol symbol, ImmutableArray attributes, Compilation compilation, List? constructors) + ImmutableArray attributes, Compilation compilation, List? constructors) { return IsBrowsingProhibitedByTypeLibAttributeWorker( - symbol, attributes, constructors ?? EditorBrowsableHelpers.GetSpecialTypeLibVarAttributeConstructors(compilation), TypeLibVarFlagsFHidden); @@ -200,7 +197,7 @@ private static bool IsBrowsingProhibitedByTypeLibVarAttribute( private const int TypeLibVarFlagsFHidden = 0x0040; private static bool IsBrowsingProhibitedByTypeLibAttributeWorker( - ISymbol symbol, ImmutableArray attributes, List attributeConstructors, int hiddenFlag) + ImmutableArray attributes, List attributeConstructors, int hiddenFlag) { foreach (var attribute in attributes) { diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs index 50e837e05e77e..6b01f57e8d260 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/SyntaxGeneratorExtensions.cs @@ -49,7 +49,7 @@ public static (ImmutableArray fields, ISymbol constructor) CreateFieldD bool addNullChecks, bool preferThrowExpression) { - var fields = factory.CreateFieldsForParameters(parameters, parameterToNewFieldMap); + var fields = CreateFieldsForParameters(parameters, parameterToNewFieldMap); var statements = factory.CreateAssignmentStatements( semanticModel, parameters, parameterToExistingFieldMap, parameterToNewFieldMap, addNullChecks, preferThrowExpression).SelectAsArray( @@ -92,7 +92,6 @@ private static bool ShouldGenerateThisConstructorCall( } public static ImmutableArray CreateFieldsForParameters( - this SyntaxGenerator factory, IList parameters, IDictionary parameterToNewFieldMap) { @@ -412,7 +411,6 @@ private static SyntaxNode WrapWithRefIfNecessary(SyntaxGenerator codeFactory, IP : body; public static IEventSymbol OverrideEvent( - this SyntaxGenerator codeFactory, IEventSymbol overriddenEvent, DeclarationModifiers modifiers, INamedTypeSymbol newContainingType) @@ -448,7 +446,7 @@ public static async Task OverrideAsync( } else if (symbol is IEventSymbol ev) { - return generator.OverrideEvent(ev, modifiers, containingType); + return OverrideEvent(ev, modifiers, containingType); } else { diff --git a/src/Workspaces/Core/Portable/Shared/Utilities/EnumValueUtilities.cs b/src/Workspaces/Core/Portable/Shared/Utilities/EnumValueUtilities.cs index e69eeb1dc770e..302a64397ac1a 100644 --- a/src/Workspaces/Core/Portable/Shared/Utilities/EnumValueUtilities.cs +++ b/src/Workspaces/Core/Portable/Shared/Utilities/EnumValueUtilities.cs @@ -25,7 +25,7 @@ public static object GetNextEnumValue(INamedTypeSymbol enumType) .OrderByDescending(f => f).ToList(); var existingConstants = orderedExistingConstants.ToSet(); - if (LooksLikeFlagsEnum(enumType, orderedExistingConstants)) + if (LooksLikeFlagsEnum(orderedExistingConstants)) { if (orderedExistingConstants.Count == 0) { @@ -108,7 +108,7 @@ private static bool GreaterThanOrEqualsZero(IComparable value) _ => false, }; - private static bool LooksLikeFlagsEnum(INamedTypeSymbol enumType, List existingConstants) + private static bool LooksLikeFlagsEnum(List existingConstants) { if (existingConstants.Count >= 1 && IntegerUtilities.HasOneBitSet(existingConstants[0]) && diff --git a/src/Workspaces/Core/Portable/Versions/Extensions.cs b/src/Workspaces/Core/Portable/Versions/Extensions.cs deleted file mode 100644 index 84c3145a78990..0000000000000 --- a/src/Workspaces/Core/Portable/Versions/Extensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.CodeAnalysis.Versions -{ - internal static class Extensions - { - public static bool CanReusePersistedTextVersion(this Document document, VersionStamp textVersion, VersionStamp persistedVersion) - { - var canReuse = VersionStamp.CanReusePersistedVersion(textVersion, persistedVersion); - - PersistedVersionStampLogger.LogPersistedTextVersionUsage(canReuse); - return canReuse; - } - - public static bool CanReusePersistedSyntaxTreeVersion(this Document document, VersionStamp syntaxVersion, VersionStamp persistedVersion) - { - var canReuse = VersionStamp.CanReusePersistedVersion(syntaxVersion, persistedVersion); - - PersistedVersionStampLogger.LogPersistedSyntaxTreeVersionUsage(canReuse); - return canReuse; - } - - public static bool CanReusePersistedProjectVersion(this Project project, VersionStamp projectVersion, VersionStamp persistedVersion) - { - var canReuse = VersionStamp.CanReusePersistedVersion(projectVersion, persistedVersion); - - PersistedVersionStampLogger.LogPersistedProjectVersionUsage(canReuse); - return canReuse; - } - - public static bool CanReusePersistedDependentProjectVersion(this Project project, VersionStamp dependentProjectVersion, VersionStamp persistedVersion) - { - var canReuse = VersionStamp.CanReusePersistedVersion(dependentProjectVersion, persistedVersion); - - PersistedVersionStampLogger.LogPersistedDependentProjectVersionUsage(canReuse); - return canReuse; - } - } -} diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs index 23c8756f53413..dd9c0bfb90615 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/ProjectState.cs @@ -726,7 +726,7 @@ public ProjectState UpdateAdditionalDocument(TextDocumentState newDocument, bool latestDocumentTopLevelChangeVersion: dependentSemanticVersion); } - public ProjectState UpdateAnalyzerConfigDocument(AnalyzerConfigDocumentState newDocument, bool textChanged, bool recalculateDependentVersions) + public ProjectState UpdateAnalyzerConfigDocument(AnalyzerConfigDocumentState newDocument) { Debug.Assert(this.ContainsAnalyzerConfigDocument(newDocument.Id)); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs b/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs index e52fda9850e90..02775ea0f979f 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/Solution.cs @@ -116,10 +116,13 @@ private static Project CreateProject(ProjectId projectId, Solution solution) return new Project(solution, state); } +#pragma warning disable IDE0060 // Remove unused parameter 'cancellationToken' - shipped public API /// /// Gets the associated with an assembly symbol. /// - public Project? GetProject(IAssemblySymbol assemblySymbol, CancellationToken cancellationToken = default) + public Project? GetProject(IAssemblySymbol assemblySymbol, + CancellationToken cancellationToken = default) +#pragma warning restore IDE0060 // Remove unused parameter { var projectState = _state.GetProjectState(assemblySymbol); diff --git a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs index 568c5b6235f37..b33af65e8b872 100644 --- a/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs +++ b/src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs @@ -1274,7 +1274,7 @@ public SolutionState WithAnalyzerConfigDocumentText(DocumentId documentId, Sourc return this; } - return UpdateAnalyzerConfigDocumentState(oldDocument.UpdateText(text, mode), textChanged: true); + return UpdateAnalyzerConfigDocumentState(oldDocument.UpdateText(text, mode)); } /// @@ -1319,7 +1319,7 @@ public SolutionState WithAnalyzerConfigDocumentText(DocumentId documentId, TextA return this; } - return UpdateAnalyzerConfigDocumentState(oldDocument.UpdateText(textAndVersion, mode), textChanged: true); + return UpdateAnalyzerConfigDocumentState(oldDocument.UpdateText(textAndVersion, mode)); } /// @@ -1397,7 +1397,7 @@ public SolutionState UpdateAnalyzerConfigDocumentTextLoader(DocumentId documentI // Assumes that text has changed. User could have closed a doc without saving and we are loading text from closed file with // old content. Also this should make sure we don't re-use latest doc version with data associated with opened document. - return UpdateAnalyzerConfigDocumentState(oldDocument.UpdateText(loader, mode), textChanged: true, recalculateDependentVersions: true); + return UpdateAnalyzerConfigDocumentState(oldDocument.UpdateText(loader, mode)); } private SolutionState UpdateDocumentState(DocumentState newDocument, bool textChanged = false, bool recalculateDependentVersions = false) @@ -1430,10 +1430,10 @@ private SolutionState UpdateAdditionalDocumentState(TextDocumentState newDocumen return ForkProject(newProject); } - private SolutionState UpdateAnalyzerConfigDocumentState(AnalyzerConfigDocumentState newDocument, bool textChanged = false, bool recalculateDependentVersions = false) + private SolutionState UpdateAnalyzerConfigDocumentState(AnalyzerConfigDocumentState newDocument) { var oldProject = GetProjectState(newDocument.Id.ProjectId)!; - var newProject = oldProject.UpdateAnalyzerConfigDocument(newDocument, textChanged, recalculateDependentVersions); + var newProject = oldProject.UpdateAnalyzerConfigDocument(newDocument); // This method shouldn't have been called if the document has not changed. Debug.Assert(oldProject != newProject); diff --git a/src/Workspaces/Core/Portable/Workspace/Workspace.cs b/src/Workspaces/Core/Portable/Workspace/Workspace.cs index 6d71f556d378c..07418f38f797d 100644 --- a/src/Workspaces/Core/Portable/Workspace/Workspace.cs +++ b/src/Workspaces/Core/Portable/Workspace/Workspace.cs @@ -94,7 +94,7 @@ protected Workspace(HostServices host, string? workspaceKind) _latestSolution = CreateSolution(info, emptyOptions, analyzerReferences: SpecializedCollections.EmptyReadOnlyList()); - _optionService.RegisterDocumentOptionsProvider(EditorConfigDocumentOptionsProviderFactory.Create(this)); + _optionService.RegisterDocumentOptionsProvider(EditorConfigDocumentOptionsProviderFactory.Create()); } internal void LogTestMessage(string message) diff --git a/src/Workspaces/Core/Portable/Workspace/Workspace_Editor.cs b/src/Workspaces/Core/Portable/Workspace/Workspace_Editor.cs index 3098a55380fd2..d58929bb0edf8 100644 --- a/src/Workspaces/Core/Portable/Workspace/Workspace_Editor.cs +++ b/src/Workspaces/Core/Portable/Workspace/Workspace_Editor.cs @@ -523,7 +523,9 @@ private void OnAdditionalOrAnalyzerConfigDocumentOpened( this.RegisterText(textContainer); } +#pragma warning disable IDE0060 // Remove unused parameter 'updateActiveContext' - shipped public API. protected internal void OnDocumentClosed(DocumentId documentId, TextLoader reloader, bool updateActiveContext = false) +#pragma warning restore IDE0060 // Remove unused parameter { // The try/catch here is to find additional telemetry for https://devdiv.visualstudio.com/DevDiv/_queries/query/71ee8553-7220-4b2a-98cf-20edab701fd1/, // where we have one theory that OnDocumentClosed is running but failing somewhere in the middle and thus failing to get to the RaiseDocumentClosedEventAsync() line. diff --git a/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs b/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs index 2a2e306c9ee8b..83c116da11068 100644 --- a/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs +++ b/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs @@ -37,7 +37,9 @@ private protected async Task AssertFormatAsync( string code, IEnumerable spans, string language, +#pragma warning disable IDE0060 // Remove unused parameter - TODO: File a test bug as quite a few formatting tests pass in 'debugMode: true', but the value is ignored. bool debugMode = false, +#pragma warning restore IDE0060 // Remove unused parameter OptionsCollection? changedOptionSet = null, bool treeCompare = true, ParseOptions? parseOptions = null) diff --git a/src/Workspaces/Remote/ServiceHub/ExternalAccess/Pythia/Api/PythiaServiceBase.cs b/src/Workspaces/Remote/ServiceHub/ExternalAccess/Pythia/Api/PythiaServiceBase.cs index 944f60b5035dd..9bf986157cded 100644 --- a/src/Workspaces/Remote/ServiceHub/ExternalAccess/Pythia/Api/PythiaServiceBase.cs +++ b/src/Workspaces/Remote/ServiceHub/ExternalAccess/Pythia/Api/PythiaServiceBase.cs @@ -35,10 +35,14 @@ public Task GetSolutionAsync(JObject solutionInfo, CancellationToken c return CreateSolutionService(pinnedSolutionInfo).GetSolutionAsync(pinnedSolutionInfo, cancellationToken); } +#pragma warning disable IDE0060 // Remove unused parameter - Avoiding breaking change in External access API protected Task RunServiceAsync(Func> callAsync, CancellationToken cancellationToken, [CallerMemberName] string? callerName = null) +#pragma warning restore IDE0060 // Remove unused parameter => base.RunServiceAsync(callAsync, cancellationToken); +#pragma warning disable IDE0060 // Remove unused parameter - Avoiding breaking change in External access API protected Task RunServiceAsync(Func callAsync, CancellationToken cancellationToken, [CallerMemberName] string? callerName = null) +#pragma warning restore IDE0060 // Remove unused parameter => base.RunServiceAsync(callAsync, cancellationToken); } } diff --git a/src/Workspaces/Remote/ServiceHub/Services/LanguageServer.cs b/src/Workspaces/Remote/ServiceHub/Services/LanguageServer.cs index 4de63264fef23..cd142b7b0f7d4 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/LanguageServer.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/LanguageServer.cs @@ -42,7 +42,7 @@ public LanguageServer(Stream stream, IServiceProvider serviceProvider) } [JsonRpcMethod(Methods.InitializeName)] - public Task InitializeAsync(JToken input, CancellationToken cancellationToken) + public Task InitializeAsync(JToken _1, CancellationToken _2) { return Task.FromResult(new InitializeResult() { @@ -60,7 +60,7 @@ public Task InitializedAsync() } [JsonRpcMethod(Methods.ShutdownName)] - public void Shutdown(CancellationToken cancellationToken) + public void Shutdown(CancellationToken _) { // our language server shutdown when VS shutdown // we have this so that we don't get log file every time VS shutdown diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeStyle/TypeStyle/TypeStyleHelper.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeStyle/TypeStyle/TypeStyleHelper.cs index 97f3ddb36372e..bca7aef92d917 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeStyle/TypeStyle/TypeStyleHelper.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/CodeStyle/TypeStyle/TypeStyleHelper.cs @@ -152,7 +152,7 @@ private static bool IsPossibleCreationOrConversionMethod(IMethodSymbol methodSym var containingType = semanticModel.GetTypeInfo(containingTypeName, cancellationToken).Type; return IsPossibleCreationMethod(methodSymbol, typeInDeclaration, containingType) - || IsPossibleConversionMethod(methodSymbol, typeInDeclaration, containingType, semanticModel); + || IsPossibleConversionMethod(methodSymbol); } /// @@ -175,10 +175,7 @@ private static bool IsPossibleCreationMethod(IMethodSymbol methodSymbol, /// If we have a method ToXXX and its return type is also XXX, then type name is apparent /// e.g: Convert.ToString. /// - private static bool IsPossibleConversionMethod(IMethodSymbol methodSymbol, - ITypeSymbol typeInDeclaration, - ITypeSymbol containingType, - SemanticModel semanticModel) + private static bool IsPossibleConversionMethod(IMethodSymbol methodSymbol) { var returnType = methodSymbol.ReturnType; var returnTypeName = returnType.IsNullable() diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/BlockSyntaxExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/BlockSyntaxExtensions.cs index ea036a99465e2..99254f71eb511 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/BlockSyntaxExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/BlockSyntaxExtensions.cs @@ -14,7 +14,7 @@ namespace Microsoft.CodeAnalysis.CSharp.Extensions internal static class BlockSyntaxExtensions { public static bool TryConvertToExpressionBody( - this BlockSyntax block, SyntaxKind declarationKind, + this BlockSyntax block, ParseOptions options, ExpressionBodyPreference preference, out ExpressionSyntax expression, out SyntaxToken semicolonToken) @@ -58,7 +58,7 @@ public static bool TryConvertToArrowExpressionBody( if (!acceptableVersion || !block.TryConvertToExpressionBody( - declarationKind, options, preference, + options, preference, out var expression, out semicolonToken)) { arrowExpression = null; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs index 67e76c8632881..467f9784a5093 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/ParenthesizedExpressionSyntaxExtensions.cs @@ -667,7 +667,7 @@ private static bool IsSimpleOrDottedName(ExpressionSyntax expression) #if !CODE_STYLE - public static bool CanRemoveParentheses(this ParenthesizedPatternSyntax node, SemanticModel semanticModel) + public static bool CanRemoveParentheses(this ParenthesizedPatternSyntax node) { if (node.OpenParenToken.IsMissing || node.CloseParenToken.IsMissing) { @@ -716,11 +716,11 @@ public static bool CanRemoveParentheses(this ParenthesizedPatternSyntax node, Se // - If the parent is not an expression, do not remove parentheses // - Otherwise, parentheses may be removed if doing so does not change operator associations. return node.Parent is PatternSyntax patternParent && - !RemovalChangesAssociation(node, patternParent, semanticModel); + !RemovalChangesAssociation(node, patternParent); } private static bool RemovalChangesAssociation( - ParenthesizedPatternSyntax node, PatternSyntax parentPattern, SemanticModel semanticModel) + ParenthesizedPatternSyntax node, PatternSyntax parentPattern) { var pattern = node.Pattern; var precedence = pattern.GetOperatorPrecedence(); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs index 51b57731e51b1..39f1a18d7ea38 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Extensions/SyntaxTreeExtensions.cs @@ -20,7 +20,9 @@ public static ISet GetPrecedingModifiers( => syntaxTree.GetPrecedingModifiers(position, tokenOnLeftOfPosition, out var _); public static ISet GetPrecedingModifiers( +#pragma warning disable IDE0060 // Remove unused parameter - Unused this parameter for consistency with other extension methods. this SyntaxTree syntaxTree, +#pragma warning restore IDE0060 // Remove unused parameter int position, SyntaxToken tokenOnLeftOfPosition, out int positionBeforeModifiers) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Lightup/SyntaxFactoryEx.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Lightup/SyntaxFactoryEx.cs index 2a1e58e0f76e2..b69c6e5e534dd 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Lightup/SyntaxFactoryEx.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Lightup/SyntaxFactoryEx.cs @@ -43,7 +43,9 @@ public static PatternSyntax TypePattern(TypeSyntax type) return TypePatternAccessor(type); } +#pragma warning disable IDE0060 // Remove unused parameter private static Func ThrowNotSupportedOnFallback(string typeName, string methodName) +#pragma warning restore IDE0060 // Remove unused parameter { return _ => throw new NotSupportedException(CSharpCompilerExtensionsResources._0_1_is_not_supported_in_this_version); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs index c2b9b900257e7..e7df51db6d777 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Simplification/Simplifiers/CastSimplifier.cs @@ -132,7 +132,7 @@ private static bool IsCastSafeToRemove( return !expressionToOuterType.IsExplicit && (HaveSameUserDefinedConversion(expressionToCastType, expressionToOuterType) || HaveSameUserDefinedConversion(castToOuterType, expressionToOuterType)) && - UserDefinedConversionIsAllowed(castNode, semanticModel); + UserDefinedConversionIsAllowed(castNode); } else if (expressionToOuterType.IsUserDefined) { @@ -260,7 +260,7 @@ private static bool CastCanDefinitelyBeRemoved( if (IsObjectCastInInterpolation(castNode, castType)) return true; - if (IsEnumToNumericCastThatCanDefinitelyBeRemoved(castNode, castedExpressionNode, castType, castedExpressionType, semanticModel, cancellationToken)) + if (IsEnumToNumericCastThatCanDefinitelyBeRemoved(castNode, castType, castedExpressionType, semanticModel, cancellationToken)) return true; return false; @@ -276,7 +276,6 @@ private static bool IsObjectCastInInterpolation(ExpressionSyntax castNode, IType private static bool IsEnumToNumericCastThatCanDefinitelyBeRemoved( ExpressionSyntax castNode, - ExpressionSyntax castedExpressionNode, ITypeSymbol castType, ITypeSymbol castedExpressionType, SemanticModel semanticModel, @@ -363,7 +362,7 @@ private static bool CastMustBePreserved( // `dynamic` changes the semantics of everything and is rarely safe to remove. We could consider removing // absolutely safe casts (i.e. `(dynamic)(dynamic)a`), but it's likely not worth the effort, so we just // disallow touching them entirely. - if (InvolvesDynamic(castNode, castedExpressionNode, castType, castedExpressionType, semanticModel, cancellationToken)) + if (InvolvesDynamic(castNode, castType, castedExpressionType, semanticModel, cancellationToken)) return true; // If removing the cast would cause the compiler to issue a specific warning, then we have to preserve it. @@ -389,7 +388,7 @@ private static bool CastMustBePreserved( // This cast can be removed with no runtime or static-semantics change. However, the compiler warns here // that this could be confusing (since it's not clear it's calling `==(object,object)` instead of // `==(string,string)`), so we have to preserve this. - if (CastIsRequiredToPreventUnintendedComparisonWarning(castNode, castedExpressionNode, castType, semanticModel, conversion, cancellationToken)) + if (CastIsRequiredToPreventUnintendedComparisonWarning(castNode, castedExpressionNode, castType, semanticModel, cancellationToken)) return true; // Identity fp-casts can actually change the runtime value of the fp number. This can happen because the @@ -399,19 +398,19 @@ private static bool CastMustBePreserved( if (IdentityFloatingPointCastMustBePreserved(castNode, castedExpressionNode, castType, castedExpressionType, semanticModel, conversion, cancellationToken)) return true; - if (PointerOrIntPtrCastMustBePreserved(castType, conversion)) + if (PointerOrIntPtrCastMustBePreserved(conversion)) return true; // If we have something like `((int)default).ToString()`. `default` has no type of it's own, but instead can // be target typed. However `(...).ToString()` is not a location where a target type can appear. So don't // even bother removing this. - if (IsTypeLessExpressionNotInTargetTypedLocation(castNode, castedExpressionNode, castType, castedExpressionType)) + if (IsTypeLessExpressionNotInTargetTypedLocation(castNode, castedExpressionType)) return true; return false; } - private static bool IsTypeLessExpressionNotInTargetTypedLocation(ExpressionSyntax castNode, ExpressionSyntax castedExpressionNode, ITypeSymbol castType, ITypeSymbol castedExpressionType) + private static bool IsTypeLessExpressionNotInTargetTypedLocation(ExpressionSyntax castNode, ITypeSymbol castedExpressionType) { // If we have something like `((int)default).ToString()`. `default` has no type of it's own, but instead can // be target typed. However `(...).ToString()` is not a location where a target type can appear. So don't @@ -516,7 +515,7 @@ private static bool IsExplicitCastThatMustBePreserved(Conversion conversion) return false; } - private static bool PointerOrIntPtrCastMustBePreserved(ITypeSymbol castType, Conversion conversion) + private static bool PointerOrIntPtrCastMustBePreserved(Conversion conversion) { if (!conversion.IsIdentity) return false; @@ -532,7 +531,6 @@ private static bool PointerOrIntPtrCastMustBePreserved(ITypeSymbol castType, Con private static bool InvolvesDynamic( ExpressionSyntax castNode, - ExpressionSyntax castedExpressionNode, ITypeSymbol castType, ITypeSymbol castedExpressionType, SemanticModel semanticModel, @@ -982,7 +980,7 @@ private static bool IsRequiredImplicitNumericConversion(ITypeSymbol sourceType, private static bool CastIsRequiredToPreventUnintendedComparisonWarning( ExpressionSyntax castNode, ExpressionSyntax castedExpressionNode, ITypeSymbol castType, - SemanticModel semanticModel, Conversion conversion, CancellationToken cancellationToken) + SemanticModel semanticModel, CancellationToken cancellationToken) { // Based on the check in DiagnosticPass.CheckRelationals. @@ -1103,7 +1101,7 @@ private static Conversion GetSpeculatedExpressionToOuterTypeConversion(Expressio return speculationAnalyzer.SpeculativeSemanticModel.ClassifyConversion(speculatedExpression, speculatedExpressionOuterType); } - private static bool UserDefinedConversionIsAllowed(ExpressionSyntax expression, SemanticModel semanticModel) + private static bool UserDefinedConversionIsAllowed(ExpressionSyntax expression) { expression = expression.WalkUpParentheses(); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/SpeculationAnalyzer.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/SpeculationAnalyzer.cs index 63a37a041c113..7c350f0d90e02 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/SpeculationAnalyzer.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Utilities/SpeculationAnalyzer.cs @@ -236,7 +236,7 @@ public bool ReplacementChangesSemanticsOfUnchangedLambda(ExpressionSyntax origin } var replacedIdentifierNodes = replacedLambdaBody.DescendantNodes().OfType().Where(node => paramNames.Contains(node.Identifier.ValueText)); - return ReplacementChangesSemanticsForNodes(originalIdentifierNodes, replacedIdentifierNodes, originalLambdaBody, replacedLambdaBody); + return ReplacementChangesSemanticsForNodes(originalIdentifierNodes, replacedIdentifierNodes, originalLambdaBody); } private bool HaveSameParameterType(ParameterSyntax originalParam, ParameterSyntax replacedParam) @@ -249,8 +249,7 @@ private bool HaveSameParameterType(ParameterSyntax originalParam, ParameterSynta private bool ReplacementChangesSemanticsForNodes( IEnumerable originalIdentifierNodes, IEnumerable replacedIdentifierNodes, - SyntaxNode originalRoot, - SyntaxNode replacedRoot) + SyntaxNode originalRoot) { Debug.Assert(originalIdentifierNodes.Any()); Debug.Assert(originalIdentifierNodes.Count() == replacedIdentifierNodes.Count()); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/INamedTypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/INamedTypeSymbolExtensions.cs index edce6afca76c1..69681f61dfc2f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/INamedTypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/INamedTypeSymbolExtensions.cs @@ -362,11 +362,10 @@ private static ImmutableArray GetTypesToImplement( { return interfacesOrAbstractClasses.First().TypeKind == TypeKind.Interface ? GetInterfacesToImplement(classOrStructType, interfacesOrAbstractClasses, allowReimplementation, cancellationToken) - : GetAbstractClassesToImplement(classOrStructType, interfacesOrAbstractClasses); + : GetAbstractClassesToImplement(interfacesOrAbstractClasses); } private static ImmutableArray GetAbstractClassesToImplement( - INamedTypeSymbol classOrStructType, IEnumerable abstractClasses) { return abstractClasses.SelectMany(a => a.GetBaseTypesAndThis()) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/BottomUpBaseIndentationFinder.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/BottomUpBaseIndentationFinder.cs index 0a838d1deae11..047d2cb899b26 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/BottomUpBaseIndentationFinder.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/BottomUpBaseIndentationFinder.cs @@ -98,7 +98,7 @@ public int GetIndentationOfCurrentPosition( return GetIndentationOfCurrentPosition( tree.GetRoot(cancellationToken), - token, list, position, extraSpaces, + list, position, extraSpaces, t => tree.GetTokenColumn(t, _tabSize), cancellationToken); } @@ -127,19 +127,18 @@ public int GetIndentationOfCurrentPosition( } } - return GetIndentationOfCurrentPosition(root, token, list, token.SpanStart, /* extraSpaces */ 0, tokenColumnGetter, cancellationToken); + return GetIndentationOfCurrentPosition(root, list, token.SpanStart, /* extraSpaces */ 0, tokenColumnGetter, cancellationToken); } private int GetIndentationOfCurrentPosition( SyntaxNode root, - SyntaxToken token, List list, int position, int extraSpaces, Func tokenColumnGetter, CancellationToken cancellationToken) { - var tuple = GetIndentationRuleOfCurrentPosition(root, token, list, position); + var tuple = GetIndentationRuleOfCurrentPosition(root, list, position); var indentationLevel = tuple.indentation; var operation = tuple.operation; @@ -180,7 +179,7 @@ private int GetIndentationOfCurrentPosition( } private (int indentation, IndentBlockOperation? operation) GetIndentationRuleOfCurrentPosition( - SyntaxNode root, SyntaxToken token, List list, int position) + SyntaxNode root, List list, int position) { var indentationLevel = 0; var operations = GetIndentBlockOperationsFromSmallestSpan(root, list, position); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/TriviaEngine/AbstractTriviaFormatter.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/TriviaEngine/AbstractTriviaFormatter.cs index e39d54eb64c72..30506a7f5203f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/TriviaEngine/AbstractTriviaFormatter.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Formatting/TriviaEngine/AbstractTriviaFormatter.cs @@ -515,7 +515,7 @@ private LineColumnDelta Apply( } var lines = GetRuleLines(rule, lineColumnAfterTrivia1, existingWhitespaceBetween); - var spaceOrIndentations = GetRuleSpacesOrIndentation(lineColumnBeforeTrivia1, trivia1, lineColumnAfterTrivia1, existingWhitespaceBetween, trivia2, rule); + var spaceOrIndentations = GetRuleSpacesOrIndentation(lineColumnBeforeTrivia1, lineColumnAfterTrivia1, existingWhitespaceBetween, trivia2, rule); return new LineColumnDelta( lines, @@ -525,7 +525,7 @@ private LineColumnDelta Apply( } private int GetRuleSpacesOrIndentation( - LineColumn lineColumnBeforeTrivia1, SyntaxTrivia trivia1, LineColumn lineColumnAfterTrivia1, LineColumnDelta existingWhitespaceBetween, SyntaxTrivia trivia2, LineColumnRule rule) + LineColumn lineColumnBeforeTrivia1, LineColumn lineColumnAfterTrivia1, LineColumnDelta existingWhitespaceBetween, SyntaxTrivia trivia2, LineColumnRule rule) { var lineColumnAfterExistingWhitespace = lineColumnAfterTrivia1.With(existingWhitespaceBetween); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs index ce05b3b0dfd97..5a2e9d5892c1e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Utilities/SymbolEquivalenceComparer.EquivalenceVisitor.cs @@ -125,7 +125,7 @@ private bool AreEquivalentWorker(ISymbol x, ISymbol y, SymbolKind k, Dictionary< { SymbolKind.ArrayType => ArrayTypesAreEquivalent((IArrayTypeSymbol)x, (IArrayTypeSymbol)y, equivalentTypesWithDifferingAssemblies), SymbolKind.Assembly => AssembliesAreEquivalent((IAssemblySymbol)x, (IAssemblySymbol)y), - SymbolKind.DynamicType => DynamicTypesAreEquivalent((IDynamicTypeSymbol)x, (IDynamicTypeSymbol)y), + SymbolKind.DynamicType => true, SymbolKind.Event => EventsAreEquivalent((IEventSymbol)x, (IEventSymbol)y, equivalentTypesWithDifferingAssemblies), SymbolKind.Field => FieldsAreEquivalent((IFieldSymbol)x, (IFieldSymbol)y, equivalentTypesWithDifferingAssemblies), SymbolKind.Label => LabelsAreEquivalent((ILabelSymbol)x, (ILabelSymbol)y), @@ -156,9 +156,6 @@ private bool ArrayTypesAreEquivalent(IArrayTypeSymbol x, IArrayTypeSymbol y, Dic private bool AssembliesAreEquivalent(IAssemblySymbol x, IAssemblySymbol y) => _symbolEquivalenceComparer._assemblyComparerOpt?.Equals(x, y) ?? true; - private bool DynamicTypesAreEquivalent(IDynamicTypeSymbol x, IDynamicTypeSymbol y) - => true; - private bool FieldsAreEquivalent(IFieldSymbol x, IFieldSymbol y, Dictionary equivalentTypesWithDifferingAssemblies) { return diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ExpressionSyntaxExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ExpressionSyntaxExtensions.vb index 65bbb1f3a2b86..a9e0c16c71f7b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ExpressionSyntaxExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ExpressionSyntaxExtensions.vb @@ -220,8 +220,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions End Select End Function +#Disable Warning IDE0060 ' Remove unused parameter Public Function IsInOutContext(expression As ExpressionSyntax) As Boolean +#Enable Warning IDE0060 ' Remove unused parameter ' NOTE(cyrusn): VB has no concept of an out context. Even when a parameter has an ' '' attribute on it, it's still treated as ref by VB. So we always return false ' here. @@ -268,8 +270,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Return False End Function +#Disable Warning IDE0060 ' Remove unused parameter Public Function IsInInContext(expression As ExpressionSyntax) As Boolean +#Enable Warning IDE0060 ' Remove unused parameter ' NOTE: VB does not support in parameters. Always return False here. Return False End Function diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/InvocationExpressionSyntaxExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/InvocationExpressionSyntaxExtensions.vb index a8809b8247e89..9a77219f0c1db 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/InvocationExpressionSyntaxExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/InvocationExpressionSyntaxExtensions.vb @@ -3,19 +3,18 @@ ' See the LICENSE file in the project root for more information. Imports System.Runtime.CompilerServices -Imports System.Threading Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Friend Module InvocationExpressionExtensions - Public Function CanRemoveEmptyArgumentList(invocationExpression As InvocationExpressionSyntax, semanticModel As SemanticModel, cancellationToken As CancellationToken) As Boolean + Public Function CanRemoveEmptyArgumentList(invocationExpression As InvocationExpressionSyntax, semanticModel As SemanticModel) As Boolean Return invocationExpression.ArgumentList IsNot Nothing AndAlso invocationExpression.ArgumentList.Arguments.Count = 0 AndAlso - CanHaveOmittedArgumentList(invocationExpression, semanticModel, cancellationToken) + CanHaveOmittedArgumentList(invocationExpression, semanticModel) End Function - Private Function CanHaveOmittedArgumentList(invocationExpression As InvocationExpressionSyntax, semanticModel As SemanticModel, cancellationToken As CancellationToken) As Boolean + Private Function CanHaveOmittedArgumentList(invocationExpression As InvocationExpressionSyntax, semanticModel As SemanticModel) As Boolean Dim nextToken = invocationExpression.GetLastToken().GetNextToken() If nextToken.IsKindOrHasMatchingText(SyntaxKind.OpenParenToken) Then @@ -38,7 +37,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions .SkipWhile(Function(t) t.IsKind(SyntaxKind.WhitespaceTrivia)) _ .FirstOrDefault() - If nextTrivia.IsKind(SyntaxKind.ColonTrivia) AndAlso invocationExpression.GetFirstToken().IsFirstTokenOnLine(cancellationToken) Then + If nextTrivia.IsKind(SyntaxKind.ColonTrivia) AndAlso invocationExpression.GetFirstToken().IsFirstTokenOnLine() Then Return False End If End If diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb index 6f8ff4f6e0def..062eb6c0b5da6 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/ParenthesizedExpressionSyntaxExtensions.vb @@ -18,7 +18,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Dim invocationAtLast = token.Parent.FirstAncestorOrSelf(Of InvocationExpressionSyntax)() Return invocationAtLast IsNot Nothing AndAlso invocationAtLast.GetLastToken() = token AndAlso - invocationAtLast.CanRemoveEmptyArgumentList(semanticModel, cancellationToken) AndAlso + invocationAtLast.CanRemoveEmptyArgumentList(semanticModel) AndAlso EndsQuery(invocationAtLast.Expression.GetLastToken(), semanticModel, cancellationToken) End If diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxTokenExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxTokenExtensions.vb index 4dccb4d91e48b..26226c16fa6f4 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxTokenExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Extensions/SyntaxTokenExtensions.vb @@ -3,7 +3,6 @@ ' See the LICENSE file in the project root for more information. Imports System.Runtime.CompilerServices -Imports System.Threading Imports Microsoft.CodeAnalysis.LanguageServices Imports Microsoft.CodeAnalysis.VisualBasic.LanguageServices Imports Microsoft.CodeAnalysis.VisualBasic.Syntax @@ -194,7 +193,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions ''' Determines whether the given SyntaxToken is the first token on a line ''' - Public Function IsFirstTokenOnLine(token As SyntaxToken, cancellationToken As CancellationToken) As Boolean + Public Function IsFirstTokenOnLine(token As SyntaxToken) As Boolean Dim previousToken = token.GetPreviousToken(includeSkipped:=True, includeDirectives:=True, includeDocumentationComments:=True) If previousToken.Kind = SyntaxKind.None Then Return True diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/CastAnalyzer.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/CastAnalyzer.vb index 04719e090a8a6..4db52fe0635de 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/CastAnalyzer.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/CastAnalyzer.vb @@ -271,7 +271,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions If castToOuterType.IsUserDefined OrElse expressionToCastType.IsUserDefined Then Return (HaveSameUserDefinedConversion(expressionToCastType, expressionToOuterType) OrElse HaveSameUserDefinedConversion(castToOuterType, expressionToOuterType)) AndAlso - (UserDefinedConversionIsAllowed(_castNode, _semanticModel) AndAlso + (UserDefinedConversionIsAllowed(_castNode) AndAlso Not expressionToCastType.IsNarrowing) ElseIf expressionToOuterType.IsUserDefined Then Return False @@ -346,7 +346,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Return conversion1.IsUserDefined AndAlso conversion2.IsUserDefined AndAlso conversion1.MethodSymbol.Equals(conversion2.MethodSymbol) End Function - Private Shared Function UserDefinedConversionIsAllowed(expression As ExpressionSyntax, semanticModel As SemanticModel) As Boolean + Private Shared Function UserDefinedConversionIsAllowed(expression As ExpressionSyntax) As Boolean expression = expression.WalkUpParentheses() Dim parentNode = expression.Parent diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/ImportsOrganizer.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/ImportsOrganizer.vb index bd9390fedbc37..74a43e7a3b199 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/ImportsOrganizer.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/ImportsOrganizer.vb @@ -134,8 +134,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Utilities Return Nothing End Function - Public Shared Function Organize(clauses As SeparatedSyntaxList(Of ImportsClauseSyntax), - placeSystemNamespaceFirst As Boolean) As SeparatedSyntaxList(Of ImportsClauseSyntax) + Public Shared Function Organize(clauses As SeparatedSyntaxList(Of ImportsClauseSyntax)) As SeparatedSyntaxList(Of ImportsClauseSyntax) If clauses.Count > 0 Then Dim result = clauses.OrderBy(ImportsClauseComparer.NormalInstance).ToList() diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/SpeculationAnalyzer.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/SpeculationAnalyzer.vb index 20b897c4e0cc3..fd29aad0101d7 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/SpeculationAnalyzer.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Utilities/SpeculationAnalyzer.vb @@ -296,7 +296,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Utilities .DescendantNodes() _ .OfType(Of IdentifierNameSyntax)() _ .Where(Function(node) paramNames.Contains(node.Identifier.ValueText)) - Return ReplacementChangesSemanticsForNodes(originalIdentifierNodes, replacedIdentifierNodes, originalLambdaBody, replacedLambdaBody) + Return ReplacementChangesSemanticsForNodes(originalIdentifierNodes, replacedIdentifierNodes, originalLambdaBody) End Function Private Function HaveSameParameterType(originalParam As ParameterSyntax, replacedParam As ParameterSyntax) As Boolean @@ -308,8 +308,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Utilities Private Function ReplacementChangesSemanticsForNodes( originalIdentifierNodes As IEnumerable(Of IdentifierNameSyntax), replacedIdentifierNodes As IEnumerable(Of IdentifierNameSyntax), - originalRoot As SyntaxNode, - replacedRoot As SyntaxNode) As Boolean + originalRoot As SyntaxNode) As Boolean Debug.Assert(originalIdentifierNodes.Any()) Debug.Assert(originalIdentifierNodes.Count() = replacedIdentifierNodes.Count()) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs index 01d08c6be914a..b985e82672c65 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ContextQuery/SyntaxTreeExtensions.cs @@ -10,6 +10,8 @@ using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; +#pragma warning disable IDE0060 // Remove unused parameter - Majority of extension methods in this file have an unused 'SyntaxTree' this parameter for consistency with other Context related extension methods. + namespace Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery { internal static partial class SyntaxTreeExtensions @@ -962,7 +964,7 @@ public static bool IsGenericTypeArgumentContext( } } - var symbols = semanticModelOpt.LookupName(nameToken, namespacesAndTypesOnly: SyntaxFacts.IsInNamespaceOrTypeContext(name), cancellationToken: cancellationToken); + var symbols = semanticModelOpt.LookupName(nameToken, cancellationToken); return symbols.Any(s => { switch (s) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs index 333ecda367e05..900b94ea7ac79 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/SemanticModelExtensions.cs @@ -24,7 +24,7 @@ public static IEnumerable LookupTypeRegardlessOfArity( { if (name.Parent is ExpressionSyntax expression) { - var results = semanticModel.LookupName(expression, namespacesAndTypesOnly: true, cancellationToken: cancellationToken); + var results = semanticModel.LookupName(expression, cancellationToken: cancellationToken); if (results.Length > 0) { return results.OfType(); @@ -37,12 +37,11 @@ public static IEnumerable LookupTypeRegardlessOfArity( public static ImmutableArray LookupName( this SemanticModel semanticModel, SyntaxToken name, - bool namespacesAndTypesOnly, CancellationToken cancellationToken) { if (name.Parent is ExpressionSyntax expression) { - return semanticModel.LookupName(expression, namespacesAndTypesOnly, cancellationToken); + return semanticModel.LookupName(expression, cancellationToken); } return ImmutableArray.Create(); @@ -101,7 +100,6 @@ private static void DecomposeName(ExpressionSyntax expression, out ExpressionSyn public static ImmutableArray LookupName( this SemanticModel semanticModel, ExpressionSyntax expression, - bool namespacesAndTypesOnly, CancellationToken cancellationToken) { var expr = SyntaxFactory.GetStandaloneExpression(expression); diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeSyntaxExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeSyntaxExtensions.cs index e1852b684411d..8472b3078c933 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeSyntaxExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/TypeSyntaxExtensions.cs @@ -40,7 +40,7 @@ typeSyntax is PointerTypeSyntax || var nameToken = nameSyntax.GetNameToken(); - var symbols = semanticModelOpt.LookupName(nameToken, namespacesAndTypesOnly: true, cancellationToken); + var symbols = semanticModelOpt.LookupName(nameToken, cancellationToken); var firstSymbol = symbols.FirstOrDefault(); var typeSymbol = firstSymbol != null && firstSymbol.Kind == SymbolKind.Alias diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index 52cab148a1e74..059fafbd3fa3e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -156,7 +156,7 @@ protected override IEnumerable InferTypesWorker_DoNotCallDire ConstantPatternSyntax constantPattern => InferTypeInConstantPattern(constantPattern), DoStatementSyntax doStatement => InferTypeInDoStatement(doStatement), EqualsValueClauseSyntax equalsValue => InferTypeInEqualsValueClause(equalsValue), - ExpressionStatementSyntax expressionStatement => InferTypeInExpressionStatement(expressionStatement), + ExpressionStatementSyntax _ => InferTypeInExpressionStatement(), ForEachStatementSyntax forEachStatement => InferTypeInForEachStatement(forEachStatement, expression), ForStatementSyntax forStatement => InferTypeInForStatement(forStatement, expression), IfStatementSyntax ifStatement => InferTypeInIfStatement(ifStatement), @@ -170,7 +170,7 @@ protected override IEnumerable InferTypesWorker_DoNotCallDire PostfixUnaryExpressionSyntax postfixUnary => InferTypeInPostfixUnaryExpression(postfixUnary), PrefixUnaryExpressionSyntax prefixUnary => InferTypeInPrefixUnaryExpression(prefixUnary), RecursivePatternSyntax propertyPattern => InferTypeInRecursivePattern(propertyPattern), - PropertyPatternClauseSyntax propertySubpattern => InferTypeInPropertyPatternClause(propertySubpattern, node), + PropertyPatternClauseSyntax propertySubpattern => InferTypeInPropertyPatternClause(propertySubpattern), RefExpressionSyntax refExpression => InferTypeInRefExpression(refExpression), ReturnStatementSyntax returnStatement => InferTypeForReturnStatement(returnStatement), SubpatternSyntax subpattern => InferTypeInSubpattern(subpattern, node), @@ -220,11 +220,11 @@ protected override IEnumerable InferTypesWorker_DoNotCallDire DefaultExpressionSyntax defaultExpression => InferTypeInDefaultExpression(defaultExpression), DoStatementSyntax doStatement => InferTypeInDoStatement(doStatement, token), EqualsValueClauseSyntax equalsValue => InferTypeInEqualsValueClause(equalsValue, token), - ExpressionStatementSyntax expressionStatement => InferTypeInExpressionStatement(expressionStatement, token), + ExpressionStatementSyntax _ => InferTypeInExpressionStatement(token), ForEachStatementSyntax forEachStatement => InferTypeInForEachStatement(forEachStatement, previousToken: token), ForStatementSyntax forStatement => InferTypeInForStatement(forStatement, previousToken: token), IfStatementSyntax ifStatement => InferTypeInIfStatement(ifStatement, token), - ImplicitArrayCreationExpressionSyntax implicitArray => InferTypeInImplicitArrayCreation(implicitArray, token), + ImplicitArrayCreationExpressionSyntax implicitArray => InferTypeInImplicitArrayCreation(implicitArray), InitializerExpressionSyntax initializerExpression => InferTypeInInitializerExpression(initializerExpression, previousToken: token), LockStatementSyntax lockStatement => InferTypeInLockStatement(lockStatement, token), MemberAccessExpressionSyntax memberAccessExpression => InferTypeInMemberAccessExpression(memberAccessExpression, previousToken: token), @@ -1202,7 +1202,7 @@ private IEnumerable InferTypeInPropertyDeclaration(PropertyDe return CreateResult(typeInfo.Type); } - private IEnumerable InferTypeInExpressionStatement(ExpressionStatementSyntax expressionStatement, SyntaxToken? previousToken = null) + private IEnumerable InferTypeInExpressionStatement(SyntaxToken? previousToken = null) { // If we're position based, then that means we're after the semicolon. In this case // we don't have any sort of type to infer. @@ -1268,7 +1268,7 @@ private IEnumerable InferTypeInIfStatement(IfStatementSyntax return CreateResult(SpecialType.System_Boolean); } - private IEnumerable InferTypeInImplicitArrayCreation(ImplicitArrayCreationExpressionSyntax implicitArray, SyntaxToken previousToken) + private IEnumerable InferTypeInImplicitArrayCreation(ImplicitArrayCreationExpressionSyntax implicitArray) => InferTypes(implicitArray.SpanStart); private IEnumerable InferTypeInInitializerExpression( @@ -1432,8 +1432,7 @@ private IEnumerable InferTypeInConstantPattern( } private IEnumerable InferTypeInPropertyPatternClause( - PropertyPatternClauseSyntax propertySubpattern, - SyntaxNode child) + PropertyPatternClauseSyntax propertySubpattern) { return InferTypes(propertySubpattern); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions_Negate.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions_Negate.cs index 9a6fce58923b7..aea229d1780b0 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions_Negate.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Extensions/SyntaxGeneratorExtensions_Negate.cs @@ -173,7 +173,7 @@ private static SyntaxNode GetNegationOfBinaryExpression( newRightOperand = generator.Negate(generatorInternal, rightOperand, semanticModel, cancellationToken); } - var newBinaryExpressionSyntax = NewBinaryOperation(binaryOperation, newLeftOperand, negatedKind, newRightOperand, generator, cancellationToken) + var newBinaryExpressionSyntax = NewBinaryOperation(binaryOperation, newLeftOperand, negatedKind, newRightOperand, generator) .WithTriviaFrom(expressionNode); var newToken = syntaxFacts.GetOperatorTokenOfBinaryExpression(newBinaryExpressionSyntax); @@ -292,8 +292,7 @@ private static SyntaxNode NewBinaryOperation( SyntaxNode leftOperand, BinaryOperatorKind operationKind, SyntaxNode rightOperand, - SyntaxGenerator generator, - CancellationToken cancellationToken) + SyntaxGenerator generator) { switch (operationKind) { @@ -306,11 +305,11 @@ private static SyntaxNode NewBinaryOperation( ? generator.ValueNotEqualsExpression(leftOperand, rightOperand) : generator.ReferenceNotEqualsExpression(leftOperand, rightOperand); case BinaryOperatorKind.LessThanOrEqual: - return IsSpecialCaseBinaryExpression(binaryOperation, operationKind, cancellationToken) + return IsSpecialCaseBinaryExpression(binaryOperation, operationKind) ? generator.ValueEqualsExpression(leftOperand, rightOperand) : generator.LessThanOrEqualExpression(leftOperand, rightOperand); case BinaryOperatorKind.GreaterThanOrEqual: - return IsSpecialCaseBinaryExpression(binaryOperation, operationKind, cancellationToken) + return IsSpecialCaseBinaryExpression(binaryOperation, operationKind) ? generator.ValueEqualsExpression(leftOperand, rightOperand) : generator.GreaterThanOrEqualExpression(leftOperand, rightOperand); case BinaryOperatorKind.LessThan: @@ -337,8 +336,7 @@ private static SyntaxNode NewBinaryOperation( /// public static bool IsSpecialCaseBinaryExpression( IBinaryOperation binaryOperation, - BinaryOperatorKind operationKind, - CancellationToken cancellationToken) + BinaryOperatorKind operationKind) { if (binaryOperation == null) { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/CallStatementSyntaxExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/CallStatementSyntaxExtensions.vb index b523933e9620e..93828c17f120c 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/CallStatementSyntaxExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/CallStatementSyntaxExtensions.vb @@ -9,7 +9,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Friend Module CallStatementSyntaxExtensions - Public Function CanRemoveCallKeyword(callStatement As CallStatementSyntax, semanticModel As SemanticModel) As Boolean + Public Function CanRemoveCallKeyword(callStatement As CallStatementSyntax) As Boolean Dim nextToken = callStatement.CallKeyword.GetNextToken() If (nextToken.IsKindOrHasMatchingText(SyntaxKind.IdentifierToken) OrElse nextToken.Parent.IsKind(SyntaxKind.PredefinedType)) AndAlso diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTokenExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTokenExtensions.vb index dadd066c4bb11..68e9f25f5f9c0 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTokenExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTokenExtensions.vb @@ -53,7 +53,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery ''' Friend Function HasNonContinuableEndOfLineBeforePosition(token As SyntaxToken, position As Integer, Optional checkForSecondEol As Boolean = False) As Boolean - If token.FollowsBadEndDirective(position) Then + If token.FollowsBadEndDirective() Then Return False End If @@ -93,7 +93,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery End Function - Friend Function FollowsBadEndDirective(targetToken As SyntaxToken, position As Integer) As Boolean + Friend Function FollowsBadEndDirective(targetToken As SyntaxToken) As Boolean If targetToken.IsKind(SyntaxKind.HashToken) AndAlso targetToken.TrailingTrivia.Any(Function(t) If t.HasStructure Then Dim childTokens = t.GetStructure().ChildTokens() diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTreeExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTreeExtensions.vb index 9fca6fdf8c18d..a5796534d81c3 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTreeExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/SyntaxTreeExtensions.vb @@ -42,8 +42,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery cancellationToken) End Function +#Disable Warning IDE0060 ' Remove unused parameter - Unused 'SyntaxTree' parameter for consistency with other Context extension methods Public Function IsPreProcessorKeywordContext(syntaxTree As SyntaxTree, position As Integer, preProcessorTokenOnLeftOfPosition As SyntaxToken, cancellationToken As CancellationToken) As Boolean +#Enable Warning IDE0060 ' Remove unused parameter ' cases: ' #| ' #d| @@ -294,8 +296,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery Return False End Function +#Disable Warning IDE0060 ' Remove unused parameter - Unused 'SyntaxTree' parameter for consistency with other Context extension methods Friend Function IsEnumMemberNameContext(syntaxTree As SyntaxTree, context As VisualBasicSyntaxContext) As Boolean +#Enable Warning IDE0060 ' Remove unused parameter Dim token = context.TargetToken ' Check to see if we're inside an enum block @@ -1057,10 +1061,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery ' Tuple literals aren't recognized by the parser until there is a comma ' So a parenthesized expression is a possible tuple context too +#Disable Warning IDE0060 ' Remove unused parameter - Unused 'SyntaxTree' parameter for consistency with other Context extension methods Friend Function IsPossibleTupleContext(syntaxTree As SyntaxTree, tokenOnLeftOfPosition As SyntaxToken, position As Integer) As Boolean +#Enable Warning IDE0060 ' Remove unused parameter tokenOnLeftOfPosition = tokenOnLeftOfPosition.GetPreviousTokenIfTouchingWord(position) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb index bd46cc433aace..65ad91ba66915 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ContextQuery/VisualBasicSyntaxContext.vb @@ -98,7 +98,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery isNameOfContext:=isNameOfContext, isInQuery:=isInQuery, isInImportsDirective:=isInImportsDirective, - isWithinAsyncMethod:=IsWithinAsyncMethod(targetToken, cancellationToken), + isWithinAsyncMethod:=IsWithinAsyncMethod(targetToken), isPossibleTupleContext:=isPossibleTupleContext, isAtStartOfPattern:=False, isAtEndOfPattern:=False, @@ -130,10 +130,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery Me.EnclosingNamedType = CancellableLazy.Create(AddressOf ComputeEnclosingNamedType) Me.IsCustomEventContext = isCustomEventContext - Me.IsPreprocessorEndDirectiveKeywordContext = targetToken.FollowsBadEndDirective(position) + Me.IsPreprocessorEndDirectiveKeywordContext = targetToken.FollowsBadEndDirective() End Sub - Private Shared Shadows Function IsWithinAsyncMethod(targetToken As SyntaxToken, cancellationToken As CancellationToken) As Boolean + Private Shared Shadows Function IsWithinAsyncMethod(targetToken As SyntaxToken) As Boolean Dim enclosingMethod = targetToken.GetAncestor(Of MethodBlockBaseSyntax)() Return enclosingMethod IsNot Nothing AndAlso enclosingMethod.BlockStatement.Modifiers.Any(SyntaxKind.AsyncKeyword) End Function @@ -192,7 +192,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery Return targetToken.Kind = SyntaxKind.None OrElse targetToken.Kind = SyntaxKind.EndOfFileToken OrElse - (targetToken.HasNonContinuableEndOfLineBeforePosition(position) AndAlso Not targetToken.FollowsBadEndDirective(position)) + (targetToken.HasNonContinuableEndOfLineBeforePosition(position) AndAlso Not targetToken.FollowsBadEndDirective()) End Function Private Shared Function ComputeIsPreprocessorStartContext(position As Integer, targetToken As SyntaxToken) As Boolean @@ -203,7 +203,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery Return targetToken.Kind = SyntaxKind.None OrElse targetToken.Kind = SyntaxKind.EndOfFileToken OrElse - (targetToken.HasNonContinuableEndOfLineBeforePosition(position) AndAlso Not targetToken.FollowsBadEndDirective(position)) + (targetToken.HasNonContinuableEndOfLineBeforePosition(position) AndAlso Not targetToken.FollowsBadEndDirective()) End Function Public Function IsFollowingParameterListOrAsClauseOfMethodDeclaration() As Boolean diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ObjectCreationExpressionExtensions.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ObjectCreationExpressionExtensions.vb index c930c4d8633ef..cfa61e90879bd 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ObjectCreationExpressionExtensions.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/Extensions/ObjectCreationExpressionExtensions.vb @@ -9,7 +9,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions Friend Module ObjectCreationExpressionExtensions - Public Function CanRemoveEmptyArgumentList(objectCreationExpression As ObjectCreationExpressionSyntax, semanticModel As SemanticModel) As Boolean + Public Function CanRemoveEmptyArgumentList(objectCreationExpression As ObjectCreationExpressionSyntax) As Boolean If objectCreationExpression.ArgumentList Is Nothing Then Return False End If diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb index baabafed90c3b..b348c3e935131 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/VisualBasic/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb @@ -65,7 +65,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Function(arrayType As ArrayTypeSyntax) InferTypeInArrayType(arrayType), Function(asClause As AsClauseSyntax) InferTypeInAsClause(asClause, expression), Function(assignmentStatement As AssignmentStatementSyntax) InferTypeInAssignmentStatement(assignmentStatement, expression), - Function(attribute As AttributeSyntax) InferTypeInAttribute(attribute), + Function(attribute As AttributeSyntax) InferTypeInAttribute(), Function(awaitExpression As AwaitExpressionSyntax) InferTypeInAwaitExpression(awaitExpression), Function(binaryExpression As BinaryExpressionSyntax) InferTypeInBinaryExpression(binaryExpression, expression), Function(callStatement As CallStatementSyntax) InferTypeInCallStatement(), @@ -92,7 +92,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Function(switchStatement As SelectStatementSyntax) InferTypeInSelectStatement(switchStatement), Function(throwStatement As ThrowStatementSyntax) InferTypeInThrowStatement(), Function(typeOfExpression As TypeOfExpressionSyntax) InferTypeInTypeOfExpressionSyntax(typeOfExpression), - Function(usingStatement As UsingStatementSyntax) InferTypeInUsingStatement(usingStatement), + Function(usingStatement As UsingStatementSyntax) InferTypeInUsingStatement(), Function(whileStatement As WhileOrUntilClauseSyntax) InferTypeInWhileOrUntilClause(), Function(whileStatement As WhileStatementSyntax) InferTypeInWhileStatement(), Function(yieldStatement As YieldStatementSyntax) InferTypeInYieldStatement(yieldStatement), @@ -137,7 +137,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Function(arrayType As ArrayTypeSyntax) InferTypeInArrayType(arrayType), Function(asClause As AsClauseSyntax) InferTypeInAsClause(asClause, previousToken:=token), Function(assignmentStatement As AssignmentStatementSyntax) InferTypeInAssignmentStatement(assignmentStatement, previousToken:=token), - Function(attribute As AttributeSyntax) InferTypeInAttribute(attribute), + Function(attribute As AttributeSyntax) InferTypeInAttribute(), Function(awaitExpression As AwaitExpressionSyntax) InferTypeInAwaitExpression(awaitExpression), Function(binaryExpression As BinaryExpressionSyntax) InferTypeInBinaryExpression(binaryExpression, previousToken:=token), Function(callStatement As CallStatementSyntax) InferTypeInCallStatement(), @@ -147,25 +147,25 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Function(collectionInitializer As CollectionInitializerSyntax) InferTypeInCollectionInitializerExpression(collectionInitializer, previousToken:=token), Function(conditionalExpression As BinaryConditionalExpressionSyntax) InferTypeInBinaryConditionalExpression(conditionalExpression, previousToken:=token), Function(conditionalExpression As TernaryConditionalExpressionSyntax) InferTypeInTernaryConditionalExpression(conditionalExpression, previousToken:=token), - Function(doStatement As DoStatementSyntax) InferTypeInDoStatement(token), - Function(equalsValue As EqualsValueSyntax) InferTypeInEqualsValue(equalsValue, token), + Function(doStatement As DoStatementSyntax) InferTypeInDoStatement(), + Function(equalsValue As EqualsValueSyntax) InferTypeInEqualsValue(equalsValue), Function(expressionStatement As ExpressionStatementSyntax) InferTypeInExpressionStatement(expressionStatement), Function(forEachStatement As ForEachStatementSyntax) InferTypeInForEachStatement(forEachStatement, previousToken:=token), Function(forStatement As ForStatementSyntax) InferTypeInForStatement(forStatement, previousToken:=token), Function(forStepClause As ForStepClauseSyntax) InferTypeInForStepClause(forStepClause, token), - Function(ifStatement As IfStatementSyntax) InferTypeInIfOrElseIfStatement(token), + Function(ifStatement As IfStatementSyntax) InferTypeInIfOrElseIfStatement(), Function(memberAccessExpression As MemberAccessExpressionSyntax) InferTypeInMemberAccessExpression(memberAccessExpression, previousToken:=token), Function(nameColonEquals As NameColonEqualsSyntax) InferTypeInArgumentList(TryCast(nameColonEquals.Parent.Parent, ArgumentListSyntax), DirectCast(nameColonEquals.Parent, ArgumentSyntax)), - Function(namedFieldInitializer As NamedFieldInitializerSyntax) InferTypeInNamedFieldInitializer(namedFieldInitializer, token), + Function(namedFieldInitializer As NamedFieldInitializerSyntax) InferTypeInNamedFieldInitializer(namedFieldInitializer), Function(objectCreation As ObjectCreationExpressionSyntax) InferTypes(objectCreation), Function(parameterListSyntax As ParameterListSyntax) InferTypeInParameterList(parameterListSyntax), - Function(parenthesizedLambda As MultiLineLambdaExpressionSyntax) InferTypeInLambda(parenthesizedLambda, token), - Function(prefixUnary As UnaryExpressionSyntax) InferTypeInUnaryExpression(prefixUnary, token), + Function(parenthesizedLambda As MultiLineLambdaExpressionSyntax) InferTypeInLambda(parenthesizedLambda), + Function(prefixUnary As UnaryExpressionSyntax) InferTypeInUnaryExpression(prefixUnary), Function(returnStatement As ReturnStatementSyntax) InferTypeForReturnStatement(returnStatement, token), - Function(singleLineLambdaExpression As SingleLineLambdaExpressionSyntax) InferTypeInLambda(singleLineLambdaExpression, token), - Function(switchStatement As SelectStatementSyntax) InferTypeInSelectStatement(switchStatement, token), + Function(singleLineLambdaExpression As SingleLineLambdaExpressionSyntax) InferTypeInLambda(singleLineLambdaExpression), + Function(switchStatement As SelectStatementSyntax) InferTypeInSelectStatement(switchStatement), Function(throwStatement As ThrowStatementSyntax) InferTypeInThrowStatement(), - Function(usingStatement As UsingStatementSyntax) InferTypeInUsingStatement(usingStatement), + Function(usingStatement As UsingStatementSyntax) InferTypeInUsingStatement(), Function(whileStatement As WhileOrUntilClauseSyntax) InferTypeInWhileOrUntilClause(), Function(whileStatement As WhileStatementSyntax) InferTypeInWhileStatement(), Function(yieldStatement As YieldStatementSyntax) InferTypeInYieldStatement(yieldStatement, token), @@ -446,7 +446,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)() End Function - Private Function InferTypeInAttribute(attribute As AttributeSyntax) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInAttribute() As IEnumerable(Of TypeInferenceInfo) Return CreateResult(Me.Compilation.AttributeType) End Function @@ -577,11 +577,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return CreateResult(SpecialType.System_Boolean) End Function - Private Function InferTypeInDoStatement(Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInDoStatement() As IEnumerable(Of TypeInferenceInfo) Return CreateResult(SpecialType.System_Boolean) End Function - Private Function InferTypeInEqualsValue(equalsValue As EqualsValueSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInEqualsValue(equalsValue As EqualsValueSyntax) As IEnumerable(Of TypeInferenceInfo) If equalsValue.IsParentKind(SyntaxKind.VariableDeclarator) Then Dim variableDeclarator = DirectCast(equalsValue.Parent, VariableDeclaratorSyntax) If variableDeclarator.AsClause Is Nothing AndAlso variableDeclarator.IsParentKind(SyntaxKind.UsingStatement) Then @@ -668,17 +668,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)() End Function +#Disable Warning IDE0060 ' Remove unused parameter + ' TODO(cyrusn): Potentially infer a different type based on the type of the variable + ' being foreach-ed over. Private Function InferTypeInForStepClause(forStepClause As ForStepClauseSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) - ' TODO(cyrusn): Potentially infer a different type based on the type of the variable - ' being foreach-ed over. +#Enable Warning IDE0060 ' Remove unused parameter Return CreateResult(Me.Compilation.GetSpecialType(SpecialType.System_Int32)) End Function - Private Function InferTypeInIfOrElseIfStatement(Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInIfOrElseIfStatement() As IEnumerable(Of TypeInferenceInfo) Return CreateResult(SpecialType.System_Boolean) End Function - Private Function InferTypeInLambda(lambda As ExpressionSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInLambda(lambda As ExpressionSyntax) As IEnumerable(Of TypeInferenceInfo) If lambda Is Nothing Then Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)() End If @@ -774,7 +776,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return originalSemanticModel.GetDeclaredSymbol(declaration, CancellationToken) End Function - Private Function InferTypeInSelectStatement(switchStatementSyntax As SelectStatementSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInSelectStatement(switchStatementSyntax As SelectStatementSyntax) As IEnumerable(Of TypeInferenceInfo) ' Use the first case label to determine the return type. If TypeOf switchStatementSyntax.Parent Is SelectBlockSyntax Then Dim firstCase = DirectCast(switchStatementSyntax.Parent, SelectBlockSyntax).CaseBlocks.SelectMany(Function(c) c.CaseStatement.Cases).OfType(Of SimpleCaseClauseSyntax).FirstOrDefault() @@ -815,7 +817,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return CreateResult(Me.Compilation.ExceptionType) End Function - Private Function InferTypeInUnaryExpression(unaryExpressionSyntax As UnaryExpressionSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInUnaryExpression(unaryExpressionSyntax As UnaryExpressionSyntax) As IEnumerable(Of TypeInferenceInfo) Select Case unaryExpressionSyntax.Kind Case SyntaxKind.UnaryPlusExpression, SyntaxKind.UnaryMinusExpression Return CreateResult(Me.Compilation.GetSpecialType(SpecialType.System_Int32)) @@ -833,13 +835,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)() End Function - Private Function InferTypeInUsingStatement(usingStatement As UsingStatementSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInUsingStatement() As IEnumerable(Of TypeInferenceInfo) Return CreateResult(SpecialType.System_IDisposable) End Function - Private Function InferTypeInVariableDeclarator(expression As ExpressionSyntax, - variableDeclarator As VariableDeclaratorSyntax, - Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInVariableDeclarator(variableDeclarator As VariableDeclaratorSyntax) As IEnumerable(Of TypeInferenceInfo) If variableDeclarator.AsClause IsNot Nothing Then Return SpecializedCollections.EmptyEnumerable(Of TypeInferenceInfo)() End If @@ -847,11 +847,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return GetTypes(variableDeclarator.AsClause.Type) End Function - Private Function InferTypeInWhileStatement(Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInWhileStatement() As IEnumerable(Of TypeInferenceInfo) Return CreateResult(SpecialType.System_Boolean) End Function - Private Function InferTypeInWhileOrUntilClause(Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInWhileOrUntilClause() As IEnumerable(Of TypeInferenceInfo) Return CreateResult(SpecialType.System_Boolean) End Function @@ -982,7 +982,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return Nothing End Function - Private Function InferTypeInNamedFieldInitializer(initializer As NamedFieldInitializerSyntax, Optional previousToken As SyntaxToken = Nothing) As IEnumerable(Of TypeInferenceInfo) + Private Function InferTypeInNamedFieldInitializer(initializer As NamedFieldInitializerSyntax) As IEnumerable(Of TypeInferenceInfo) Dim right = SemanticModel.GetTypeInfo(initializer.Name).Type If right IsNot Nothing AndAlso TypeOf right IsNot IErrorTypeSymbol Then Return CreateResult(right) diff --git a/src/Workspaces/VisualBasic/Portable/Classification/ClassificationHelpers.vb b/src/Workspaces/VisualBasic/Portable/Classification/ClassificationHelpers.vb index 7414c06c43f1e..7823ff9904c48 100644 --- a/src/Workspaces/VisualBasic/Portable/Classification/ClassificationHelpers.vb +++ b/src/Workspaces/VisualBasic/Portable/Classification/ClassificationHelpers.vb @@ -323,8 +323,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification Worker.CollectClassifiedSpans(tokens, textSpan, result, cancellationToken) End Sub +#Disable Warning IDE0060 ' Remove unused parameter - TODO: Do we need to do the same work here that we do in C#? Friend Function AdjustStaleClassification(text As SourceText, classifiedSpan As ClassifiedSpan) As ClassifiedSpan - ' TODO: Do we need to do the same work here that we do in C#? +#Enable Warning IDE0060 ' Remove unused parameter Return classifiedSpan End Function End Module diff --git a/src/Workspaces/VisualBasic/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.vb b/src/Workspaces/VisualBasic/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.vb index 3c0ce327fb89f..b045238472e4e 100644 --- a/src/Workspaces/VisualBasic/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.vb +++ b/src/Workspaces/VisualBasic/Portable/Classification/SyntaxClassification/NameSyntaxClassifier.vb @@ -35,19 +35,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers Dim modifiedIdentifier = TryCast(syntax, ModifiedIdentifierSyntax) If modifiedIdentifier IsNot Nothing Then - ClassifyModifiedIdentifier(modifiedIdentifier, semanticModel, result, cancellationToken) + ClassifyModifiedIdentifier(modifiedIdentifier, result) Return End If Dim methodStatement = TryCast(syntax, MethodStatementSyntax) If methodStatement IsNot Nothing Then - ClassifyMethodStatement(methodStatement, semanticModel, result, cancellationToken) + ClassifyMethodStatement(methodStatement, semanticModel, result) Return End If Dim labelSyntax = TryCast(syntax, LabelSyntax) If labelSyntax IsNot Nothing Then - ClassifyLabelSyntax(labelSyntax, semanticModel, result, cancellationToken) + ClassifyLabelSyntax(labelSyntax, result) Return End If End Sub @@ -76,15 +76,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers Dim symbol = TryGetSymbol(node, symbolInfo, semanticModel) If symbol Is Nothing Then - If TryClassifyIdentifier(node, symbol, semanticModel, cancellationToken, classifiedSpan) Then + If TryClassifyIdentifier(node, semanticModel, cancellationToken, classifiedSpan) Then result.Add(classifiedSpan) End If Return End If - If TryClassifyMyNamespace(node, symbol, semanticModel, cancellationToken, classifiedSpan) Then + If TryClassifyMyNamespace(node, symbol, semanticModel, classifiedSpan) Then result.Add(classifiedSpan) - ElseIf TryClassifySymbol(node, symbol, semanticModel, cancellationToken, classifiedSpan) Then + ElseIf TryClassifySymbol(node, symbol, classifiedSpan) Then result.Add(classifiedSpan) ' Additionally classify static symbols @@ -95,8 +95,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers Private Function TryClassifySymbol( node As NameSyntax, symbol As ISymbol, - semanticModel As SemanticModel, - cancellationToken As CancellationToken, ByRef classifiedSpan As ClassifiedSpan) As Boolean Select Case symbol.Kind @@ -153,7 +151,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers node As NameSyntax, symbol As ISymbol, semanticModel As SemanticModel, - cancellationToken As CancellationToken, ByRef classifiedSpan As ClassifiedSpan) As Boolean If symbol.IsMyNamespace(semanticModel.Compilation) Then @@ -166,7 +163,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers Private Function TryClassifyIdentifier( node As NameSyntax, - symbol As ISymbol, semanticModel As SemanticModel, cancellationToken As CancellationToken, ByRef classifiedSpan As ClassifiedSpan) As Boolean @@ -237,9 +233,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers Private Sub ClassifyModifiedIdentifier( modifiedIdentifier As ModifiedIdentifierSyntax, - semanticModel As SemanticModel, - result As ArrayBuilder(Of ClassifiedSpan), - cancellationToken As CancellationToken) + result As ArrayBuilder(Of ClassifiedSpan)) If modifiedIdentifier.ArrayBounds IsNot Nothing OrElse modifiedIdentifier.ArrayRankSpecifiers.Count > 0 OrElse @@ -279,7 +273,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers End Select End Function - Private Sub ClassifyMethodStatement(methodStatement As MethodStatementSyntax, semanticModel As SemanticModel, result As ArrayBuilder(Of ClassifiedSpan), cancellationToken As CancellationToken) + Private Sub ClassifyMethodStatement(methodStatement As MethodStatementSyntax, semanticModel As SemanticModel, result As ArrayBuilder(Of ClassifiedSpan)) ' Ensure that extension method declarations are classified properly. ' Note that the method statement name is likely already classified as a method name ' by the syntactic classifier. However, there isn't away to determine whether a VB @@ -292,9 +286,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers Private Sub ClassifyLabelSyntax( node As LabelSyntax, - semanticModel As SemanticModel, - result As ArrayBuilder(Of ClassifiedSpan), - cancellationToken As CancellationToken) + result As ArrayBuilder(Of ClassifiedSpan)) result.Add(New ClassifiedSpan(node.LabelToken.Span, ClassificationTypeNames.LabelName)) End Sub diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/ConversionGenerator.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/ConversionGenerator.vb index 2cfe1345d19d6..0236320082af4 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/ConversionGenerator.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/ConversionGenerator.vb @@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration method As IMethodSymbol, options As CodeGenerationOptions, availableIndices As IList(Of Boolean)) As TypeBlockSyntax - Dim methodDeclaration = GenerateConversionDeclaration(method, GetDestination(destination), options) + Dim methodDeclaration = GenerateConversionDeclaration(method, options) Dim members = Insert(destination.Members, methodDeclaration, options, availableIndices, after:=AddressOf LastOperator) @@ -22,14 +22,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Function GenerateConversionDeclaration(method As IMethodSymbol, - destination As CodeGenerationDestination, - options As CodeGenerationOptions) As StatementSyntax + options As CodeGenerationOptions) As StatementSyntax Dim reusableSyntax = GetReuseableSyntaxNodeForSymbol(Of StatementSyntax)(method, options) If reusableSyntax IsNot Nothing Then Return reusableSyntax End If - Dim declaration = GenerateConversionDeclarationWorker(method, destination, options) + Dim declaration = GenerateConversionDeclarationWorker(method, options) Return AddAnnotationsTo(method, AddFormatterAndCodeGeneratorAnnotationsTo( @@ -37,8 +36,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function GenerateConversionDeclarationWorker(method As IMethodSymbol, - destination As CodeGenerationDestination, - options As CodeGenerationOptions) As StatementSyntax + options As CodeGenerationOptions) As StatementSyntax Dim modifiers = New List(Of SyntaxToken) From { SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.SharedKeyword) diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/OperatorGenerator.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/OperatorGenerator.vb index cd4aa595cd457..6f09cb73b163c 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/OperatorGenerator.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/OperatorGenerator.vb @@ -13,7 +13,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration method As IMethodSymbol, options As CodeGenerationOptions, availableIndices As IList(Of Boolean)) As TypeBlockSyntax - Dim methodDeclaration = GenerateOperatorDeclaration(method, GetDestination(destination), options) + Dim methodDeclaration = GenerateOperatorDeclaration(method, options) Dim members = Insert(destination.Members, methodDeclaration, options, availableIndices, after:=AddressOf LastOperator) @@ -22,14 +22,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Function GenerateOperatorDeclaration(method As IMethodSymbol, - destination As CodeGenerationDestination, - options As CodeGenerationOptions) As StatementSyntax + options As CodeGenerationOptions) As StatementSyntax Dim reusableSyntax = GetReuseableSyntaxNodeForSymbol(Of StatementSyntax)(method, options) If reusableSyntax IsNot Nothing Then Return reusableSyntax End If - Dim declaration = GenerateOperatorDeclarationWorker(method, destination, options) + Dim declaration = GenerateOperatorDeclarationWorker(method, options) Return AddAnnotationsTo(method, AddFormatterAndCodeGeneratorAnnotationsTo( @@ -37,8 +36,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function GenerateOperatorDeclarationWorker(method As IMethodSymbol, - destination As CodeGenerationDestination, - options As CodeGenerationOptions) As StatementSyntax + options As CodeGenerationOptions) As StatementSyntax Dim operatorSyntaxKind = SyntaxFacts.GetOperatorKind(method.MetadataName) If operatorSyntaxKind = SyntaxKind.None Then Throw New ArgumentException(String.Format(WorkspacesResources.Cannot_generate_code_for_unsupported_operator_0, method.Name), NameOf(method)) diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb index 6c917f181e714..5c42cc7515e09 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationHelpers.vb @@ -114,7 +114,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function AfterDeclaration(Of TDeclaration As SyntaxNode)( - declarationList As SyntaxList(Of TDeclaration), options As CodeGenerationOptions, [next] As Func(Of SyntaxList(Of TDeclaration), TDeclaration)) As Func(Of SyntaxList(Of TDeclaration), TDeclaration) @@ -130,9 +129,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function BeforeDeclaration(Of TDeclaration As SyntaxNode)( - declarationList As SyntaxList(Of TDeclaration), options As CodeGenerationOptions, - [next] As Func(Of SyntaxList(Of TDeclaration), TDeclaration)) As Func(Of SyntaxList(Of TDeclaration), TDeclaration) + [next] As Func(Of SyntaxList(Of TDeclaration), TDeclaration)) As Func(Of SyntaxList(Of TDeclaration), TDeclaration) options = If(options, CodeGenerationOptions.Default) @@ -153,8 +151,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional after As Func(Of SyntaxList(Of TDeclaration), TDeclaration) = Nothing, Optional before As Func(Of SyntaxList(Of TDeclaration), TDeclaration) = Nothing) As SyntaxList(Of TDeclaration) - after = AfterDeclaration(declarationList, options, after) - before = BeforeDeclaration(declarationList, options, before) + after = AfterDeclaration(options, after) + before = BeforeDeclaration(options, before) Dim index = GetInsertionIndex( declarationList, declaration, options, availableIndices, diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb index 02e4908a49f61..6165d20ebaa81 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicCodeGenerationService.vb @@ -353,7 +353,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ' Handle most cases Dim member = TryCast(destination, StatementSyntax) If member IsNot Nothing Then - Dim newAttributeLists = RemoveAttributeFromAttributeLists(member.GetAttributes(), attributeToRemove, options, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) + Dim newAttributeLists = RemoveAttributeFromAttributeLists(member.GetAttributes(), attributeToRemove, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) VerifyAttributeRemoved(attributeRemoved) Dim newMember = member.WithAttributeLists(newAttributeLists) Return Cast(Of TDeclarationNode)(AppendTriviaAtPosition(newMember, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)) @@ -363,7 +363,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Dim compilationUnit = TryCast(destination, CompilationUnitSyntax) If compilationUnit IsNot Nothing Then Dim attributeStatements = compilationUnit.Attributes - Dim newAttributeStatements = RemoveAttributeFromAttributeStatements(attributeStatements, attributeToRemove, options, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) + Dim newAttributeStatements = RemoveAttributeFromAttributeStatements(attributeStatements, attributeToRemove, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) VerifyAttributeRemoved(attributeRemoved) Dim newCompilationUnit = compilationUnit.WithAttributes(newAttributeStatements) Return Cast(Of TDeclarationNode)(AppendTriviaAtPosition(newCompilationUnit, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)) @@ -372,7 +372,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration ' Handle parameters Dim parameter = TryCast(destination, ParameterSyntax) If parameter IsNot Nothing Then - Dim newAttributeLists = RemoveAttributeFromAttributeLists(parameter.AttributeLists, attributeToRemove, options, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) + Dim newAttributeLists = RemoveAttributeFromAttributeLists(parameter.AttributeLists, attributeToRemove, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) VerifyAttributeRemoved(attributeRemoved) Dim newParameter = parameter.WithAttributeLists(newAttributeLists) Return Cast(Of TDeclarationNode)(AppendTriviaAtPosition(newParameter, positionOfRemovedNode - destination.FullSpan.Start, triviaOfRemovedNode)) @@ -381,7 +381,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Return destination End Function - Private Shared Function RemoveAttributeFromAttributeLists(attributeLists As SyntaxList(Of AttributeListSyntax), attributeToRemove As SyntaxNode, options As CodeGenerationOptions, + Private Shared Function RemoveAttributeFromAttributeLists(attributeLists As SyntaxList(Of AttributeListSyntax), attributeToRemove As SyntaxNode, ByRef attributeRemoved As Boolean, ByRef positionOfRemovedNode As Integer, ByRef triviaOfRemovedNode As SyntaxTriviaList) As SyntaxList(Of AttributeListSyntax) For Each attributeList In attributeLists Dim attributes = attributeList.Attributes @@ -410,11 +410,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Return attributeLists End Function - Private Shared Function RemoveAttributeFromAttributeStatements(attributeStatements As SyntaxList(Of AttributesStatementSyntax), attributeToRemove As SyntaxNode, options As CodeGenerationOptions, + Private Shared Function RemoveAttributeFromAttributeStatements(attributeStatements As SyntaxList(Of AttributesStatementSyntax), attributeToRemove As SyntaxNode, ByRef attributeRemoved As Boolean, ByRef positionOfRemovedNode As Integer, ByRef triviaOfRemovedNode As SyntaxTriviaList) As SyntaxList(Of AttributesStatementSyntax) For Each attributeStatement In attributeStatements Dim attributeLists = attributeStatement.AttributeLists - Dim newAttributeLists = RemoveAttributeFromAttributeLists(attributeLists, attributeToRemove, options, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) + Dim newAttributeLists = RemoveAttributeFromAttributeLists(attributeLists, attributeToRemove, attributeRemoved, positionOfRemovedNode, triviaOfRemovedNode) If attributeRemoved Then Dim newAttributeStatement = attributeStatement.WithAttributeLists(newAttributeLists) Return SyntaxFactory.List(attributeStatements.Select(Function(attrStatement) If(attrStatement Is attributeStatement, newAttributeStatement, attrStatement))) @@ -510,9 +510,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration If method.IsConstructor() Then Return ConstructorGenerator.GenerateConstructorDeclaration(method, destination, options) ElseIf method.IsUserDefinedOperator() Then - Return OperatorGenerator.GenerateOperatorDeclaration(method, destination, options) + Return OperatorGenerator.GenerateOperatorDeclaration(method, options) ElseIf method.IsConversion() Then - Return ConversionGenerator.GenerateConversionDeclaration(method, destination, options) + Return ConversionGenerator.GenerateConversionDeclaration(method, options) Else Return MethodGenerator.GenerateMethodDeclaration(method, destination, options) End If @@ -554,7 +554,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Return NamespaceGenerator.GenerateNamespaceDeclaration(Me, [namespace], options, cancellationToken) End Function - Private Overloads Shared Function UpdateDeclarationModifiers(Of TDeclarationNode As SyntaxNode)(declaration As TDeclarationNode, computeNewModifiersList As Func(Of SyntaxTokenList, SyntaxTokenList), options As CodeGenerationOptions, cancellationToken As CancellationToken) As TDeclarationNode + Private Overloads Shared Function UpdateDeclarationModifiers(Of TDeclarationNode As SyntaxNode)(declaration As TDeclarationNode, computeNewModifiersList As Func(Of SyntaxTokenList, SyntaxTokenList)) As TDeclarationNode ' Handle type declarations Dim typeStatementSyntax = TryCast(declaration, TypeStatementSyntax) If typeStatementSyntax IsNot Nothing Then @@ -604,14 +604,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Dim computeNewModifiersList As Func(Of SyntaxTokenList, SyntaxTokenList) = Function(modifiersList As SyntaxTokenList) Return SyntaxFactory.TokenList(newModifiers) End Function - Return UpdateDeclarationModifiers(declaration, computeNewModifiersList, options, cancellationToken) + Return UpdateDeclarationModifiers(declaration, computeNewModifiersList) End Function Public Overrides Function UpdateDeclarationAccessibility(Of TDeclarationNode As SyntaxNode)(declaration As TDeclarationNode, newAccessibility As Accessibility, options As CodeGenerationOptions, cancellationToken As CancellationToken) As TDeclarationNode Dim computeNewModifiersList As Func(Of SyntaxTokenList, SyntaxTokenList) = Function(modifiersList As SyntaxTokenList) Return UpdateDeclarationAccessibility(modifiersList, newAccessibility, options) End Function - Return UpdateDeclarationModifiers(declaration, computeNewModifiersList, options, cancellationToken) + Return UpdateDeclarationModifiers(declaration, computeNewModifiersList) End Function Private Overloads Shared Function UpdateDeclarationAccessibility(modifiersList As SyntaxTokenList, newAccessibility As Accessibility, options As CodeGenerationOptions) As SyntaxTokenList diff --git a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb index 8ac1d1115e28a..c03cafded1ff8 100644 --- a/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb +++ b/src/Workspaces/VisualBasic/Portable/FindSymbols/VisualBasicReferenceFinder.vb @@ -56,13 +56,12 @@ Namespace Microsoft.CodeAnalysis.FindSymbols ' If this is a WinForms project, then the VB 'my' feature may have synthesized ' a property that would return an instance of the main Form type for the project. ' Search for such properties and cascade to them as well. - Return GetMatchingMyPropertySymbols(namedType, project.Id, compilation, cancellationToken). + Return GetMatchingMyPropertySymbols(namedType, compilation, cancellationToken). Distinct().ToImmutableArray() End Function Private Function GetMatchingMyPropertySymbols( namedType As INamedTypeSymbol, - projectId As ProjectId, compilation As Compilation, cancellationToken As CancellationToken) As IEnumerable(Of ISymbol) Return From childNamespace In compilation.RootNamespace.GetNamespaceMembers() diff --git a/src/Workspaces/VisualBasic/Portable/Formatting/Engine/Trivia/TriviaDataFactory.CodeShapeAnalyzer.vb b/src/Workspaces/VisualBasic/Portable/Formatting/Engine/Trivia/TriviaDataFactory.CodeShapeAnalyzer.vb index 6ec74ca08ad34..57f85617c8f33 100644 --- a/src/Workspaces/VisualBasic/Portable/Formatting/Engine/Trivia/TriviaDataFactory.CodeShapeAnalyzer.vb +++ b/src/Workspaces/VisualBasic/Portable/Formatting/Engine/Trivia/TriviaDataFactory.CodeShapeAnalyzer.vb @@ -252,7 +252,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting Return False End Function - Private Function OnPreprocessor(trivia As SyntaxTrivia, currentIndex As Integer) As Boolean + Private Function OnPreprocessor(trivia As SyntaxTrivia) As Boolean If Not SyntaxFacts.IsPreprocessorDirective(trivia.Kind) Then Return False End If @@ -273,7 +273,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting OnComment(trivia, index) OrElse OnSkippedTokensOrText(trivia) OrElse OnRegion(trivia, index) OrElse - OnPreprocessor(trivia, index) Then + OnPreprocessor(trivia) Then Return True End If Next diff --git a/src/Workspaces/VisualBasic/Portable/Formatting/Rules/BaseFormattingRule.vb b/src/Workspaces/VisualBasic/Portable/Formatting/Rules/BaseFormattingRule.vb index f5202822df828..25b5f16a7d3fd 100644 --- a/src/Workspaces/VisualBasic/Portable/Formatting/Rules/BaseFormattingRule.vb +++ b/src/Workspaces/VisualBasic/Portable/Formatting/Rules/BaseFormattingRule.vb @@ -68,15 +68,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Formatting Return TextSpan.FromBounds(spanStart, nextToken.SpanStart) End Function +#Disable Warning IDE0060 ' Remove unused parameter Protected Sub AddSuppressWrappingIfOnSingleLineOperation(operations As List(Of SuppressOperation), startToken As SyntaxToken, endToken As SyntaxToken) ' VB doesn't need to use this operation - throw ExceptionUtilities.Unreachable + Throw ExceptionUtilities.Unreachable End Sub Protected Sub AddSuppressAllOperationIfOnMultipleLine(operations As List(Of SuppressOperation), startToken As SyntaxToken, endToken As SyntaxToken) ' VB doesn't need to use this operation - throw ExceptionUtilities.Unreachable + Throw ExceptionUtilities.Unreachable End Sub +#Enable Warning IDE0060 ' Remove unused parameter Protected Sub AddAnchorIndentationOperation(operations As List(Of AnchorIndentationOperation), startToken As SyntaxToken, endToken As SyntaxToken) If startToken.Kind = SyntaxKind.None OrElse endToken.Kind = SyntaxKind.None Then diff --git a/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb b/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb index b774dc108bb4e..4f257bd834677 100644 --- a/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb +++ b/src/Workspaces/VisualBasic/Portable/Indentation/VisualBasicIndentationService.Indenter.vb @@ -116,7 +116,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Indentation End If ' implicit line continuation case - If IsLineContinuable(token, trivia, position) Then + If IsLineContinuable(token, trivia) Then Return GetIndentationFromTokenLineAfterLineContinuation(indenter, token, trivia) End If @@ -142,7 +142,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Indentation Return indenter.IndentFromStartOfLine(indenter.Finder.GetIndentationOfCurrentPosition(indenter.Tree, token, position, extraSpaces, indenter.CancellationToken)) End Function - Private Function IsLineContinuable(lastVisibleTokenOnPreviousLine As SyntaxToken, trivia As SyntaxTrivia, position As Integer) As Boolean + Private Function IsLineContinuable(lastVisibleTokenOnPreviousLine As SyntaxToken, trivia As SyntaxTrivia) As Boolean If trivia.Kind = SyntaxKind.LineContinuationTrivia OrElse trivia.Kind = SyntaxKind.SkippedTokensTrivia Then Return True diff --git a/src/Workspaces/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.Rewriter.vb b/src/Workspaces/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.Rewriter.vb index 1015b351e78e3..1301469902585 100644 --- a/src/Workspaces/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.Rewriter.vb +++ b/src/Workspaces/VisualBasic/Portable/OrganizeImports/VisualBasicOrganizeImportsService.Rewriter.vb @@ -35,7 +35,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.OrganizeImports End Function Public Overrides Function VisitImportsStatement(node As ImportsStatementSyntax) As SyntaxNode - Dim organizedImportsClauses = ImportsOrganizer.Organize(node.ImportsClauses, _placeSystemNamespaceFirst) + Dim organizedImportsClauses = ImportsOrganizer.Organize(node.ImportsClauses) Dim result = node.WithImportsClauses(organizedImportsClauses) If result IsNot node Then diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicCallReducer.vb b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicCallReducer.vb index 347f8b6c5524a..37a1b5f6a67f1 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicCallReducer.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicCallReducer.vb @@ -28,7 +28,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification cancellationToken As CancellationToken ) As ExecutableStatementSyntax - If callStatement.CanRemoveCallKeyword(semanticModel) Then + If callStatement.CanRemoveCallKeyword() Then Dim leading = callStatement.GetLeadingTrivia() Dim resultNode = SyntaxFactory.ExpressionStatement(callStatement.Invocation) _ diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb index ba198f88ba339..ea8ced9b30453 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb @@ -19,7 +19,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification MyBase.New(s_pool) End Sub +#Disable Warning IDE0060 ' Remove unused parameter - False positive, used as a delegate in a nested type. + ' TODO: File a bug for this 'IDE0060' false positive. Private Shared Function TryUnescapeToken(identifier As SyntaxToken, semanticModel As SemanticModel, optionSet As OptionSet, cancellationToken As CancellationToken) As SyntaxToken +#Enable Warning IDE0060 ' Remove unused parameter If Not identifier.IsBracketed Then Return identifier End If diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicMiscellaneousReducer.vb b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicMiscellaneousReducer.vb index 5f2c97eb9f280..4f132ecafa80e 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicMiscellaneousReducer.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicMiscellaneousReducer.vb @@ -45,7 +45,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification cancellationToken As CancellationToken ) As InvocationExpressionSyntax - If invocationExpression.CanRemoveEmptyArgumentList(semanticModel, cancellationToken) Then + If invocationExpression.CanRemoveEmptyArgumentList(semanticModel) Then Dim resultNode = invocationExpression _ .WithArgumentList(Nothing) _ .WithTrailingTrivia(invocationExpression.GetTrailingTrivia()) @@ -68,7 +68,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification cancellationToken As CancellationToken ) As ObjectCreationExpressionSyntax - If objectCreationExpression.CanRemoveEmptyArgumentList(semanticModel) Then + If objectCreationExpression.CanRemoveEmptyArgumentList() Then Dim resultNode = objectCreationExpression _ .WithArgumentList(Nothing) _ .WithTrailingTrivia(objectCreationExpression.GetTrailingTrivia()) From d256ecd0d4a162bbc78166c3d9a012482d17e7fc Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 16:17:49 -0700 Subject: [PATCH 158/222] Address pending feedback from https://github.com/dotnet/roslyn/pull/44164#discussion_r424012929 --- .../CSharpInlineDeclarationDiagnosticAnalyzer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Analyzers/CSharp/Analyzers/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs b/src/Analyzers/CSharp/Analyzers/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs index d579d4702d827..481008cb14037 100644 --- a/src/Analyzers/CSharp/Analyzers/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs +++ b/src/Analyzers/CSharp/Analyzers/InlineDeclaration/CSharpInlineDeclarationDiagnosticAnalyzer.cs @@ -221,8 +221,7 @@ private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context, INamedTypeSymb var allLocations = ImmutableArray.Create( localDeclarator.GetLocation(), identifierName.GetLocation(), - invocationOrCreation.GetLocation(), - containingStatement.GetLocation()); + invocationOrCreation.GetLocation()); // If the local variable only has one declarator, then report the suggestion on the whole // declaration. Otherwise, return the suggestion only on the single declarator. From 7878df970abb67156d33ef007a19ea67f171b847 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 17:52:50 -0700 Subject: [PATCH 159/222] Remove workaround added for https://github.com/dotnet/roslyn/issues/42166 That feature has been implemented and Roslyn repo is currently using a toolset which has the compiler with this feature. Additionally, we no longer run analyzers on local builds, so there is no performance impact with this change. --- eng/targets/Imports.targets | 6 ------ 1 file changed, 6 deletions(-) diff --git a/eng/targets/Imports.targets b/eng/targets/Imports.targets index 43364a7f6afd8..59c9c35caf8c2 100644 --- a/eng/targets/Imports.targets +++ b/eng/targets/Imports.targets @@ -50,12 +50,6 @@ $(NoWarn);Nullable - - - - $(NoWarn);IDE0004;IDE0004WithoutSuggestion;IDE0005;IDE0007;IDE0007WithoutSuggestion;IDE0008;IDE0008WithoutSuggestion;IDE0009;IDE0009WithoutSuggestion;IDE0010;IDE0010WithoutSuggestion;IDE0011;IDE0011WithoutSuggestion;IDE0016;IDE0016WithoutSuggestion;IDE0017;IDE0017WithoutSuggestion;IDE0018;IDE0018WithoutSuggestion;IDE0019;IDE0019WithoutSuggestion;IDE0020;IDE0020WithoutSuggestion;IDE0021;IDE0022;IDE0023;IDE0024;IDE0025;IDE0026;IDE0027;IDE0028;IDE0028WithoutSuggestion;IDE0029;IDE0029WithoutSuggestion;IDE0030;IDE0030WithoutSuggestion;IDE0031;IDE0031WithoutSuggestion;IDE0032;IDE0032WithoutSuggestion;IDE0033;IDE0033WithoutSuggestion;IDE0034;IDE0034WithoutSuggestion;IDE0035;IDE0035WithoutSuggestion;IDE0036;IDE0036WithoutSuggestion;IDE0037;IDE0037WithoutSuggestion;IDE0040;IDE0040WithoutSuggestion;IDE0041;IDE0041WithoutSuggestion;IDE0042;IDE0042WithoutSuggestion;IDE0043;IDE0044;IDE0044WithoutSuggestion;IDE0045;IDE0045WithoutSuggestion;IDE0046;IDE0046WithoutSuggestion;IDE0047;IDE0048;IDE0048WithoutSuggestion;IDE0050;IDE0050WithoutSuggestion;IDE0051;IDE0052;IDE0054;IDE0054WithoutSuggestion;IDE0055;IDE0056;IDE0056WithoutSuggestion;IDE0057;IDE0057WithoutSuggestion;IDE0058;IDE0059;IDE0060;IDE0061;IDE0062;IDE0062WithoutSuggestion;IDE0063;IDE0063WithoutSuggestion;IDE0064;IDE0065;IDE0066;IDE0066WithoutSuggestion;IDE0070;IDE0070WithoutSuggestion;IDE0071;IDE0071WithoutSuggestion;IDE0072;IDE0072WithoutSuggestion;IDE0073;IDE0073WithoutSuggestion;IDE0074;IDE0074WithoutSuggestion;IDE0075;IDE0075WithoutSuggestion;IDE1005;IDE1005WithoutSuggestion;IDE1006;IDE1006WithoutSuggestion - - <_ExplicitReference Include="$(FrameworkPathOverride)\mscorlib.dll" /> From b75f8f0791f3b36bd78de1364fbf08e762967055 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 18:03:37 -0700 Subject: [PATCH 160/222] Removing the workaround for https://github.com/dotnet/roslyn/issues/42166 identified that IDE0051/IDE0052 were not getting enforced on the build. I will file a follow-up issue to investigate it, but this commit fixes the existing IDE0051/IDE0052 violations in IDE projects where they are set to warning. --- ...emoveUnnecessaryPatternParenthesesTests.cs | 8 ------- .../UseIsNullCheckForReferenceEqualsTests.cs | 7 +++++- .../Portable/Diagnostics/AnalyzerHelper.cs | 2 ++ ...crementalAnalyzer_GetDiagnosticsForSpan.cs | 22 +++++++++---------- .../AbstractGenerateTypeService.Editor.cs | 8 ------- .../SQLite/v1/Interop/SqlConnection.cs | 2 ++ .../SQLite/v2/Interop/SqlConnection.cs | 2 ++ ...ynamicFileInfoProviderThatProducesFiles.cs | 5 +---- ...amicFileInfoProviderThatProducesNoFiles.cs | 5 +---- 9 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs index 9bdb399e2e090..e8c1530677e72 100644 --- a/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs +++ b/src/Analyzers/CSharp/Tests/RemoveUnnecessaryParentheses/RemoveUnnecessaryPatternParenthesesTests.cs @@ -12,8 +12,6 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; using Microsoft.CodeAnalysis.Test.Utilities; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.RemoveUnnecessaryParentheses @@ -40,12 +38,6 @@ private async Task TestAsync(string initial, string expected, bool offeredWhenRe internal override bool ShouldSkipMessageDescriptionVerification(DiagnosticDescriptor descriptor) => descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Unnecessary) && descriptor.DefaultSeverity == DiagnosticSeverity.Hidden; - private DiagnosticDescription GetRemoveUnnecessaryParenthesesDiagnostic(string text, int line, int column) - => TestHelpers.Diagnostic(IDEDiagnosticIds.RemoveUnnecessaryParenthesesDiagnosticId, text, startLocation: new LinePosition(line, column)); - - private DiagnosticDescription GetRemoveUnnecessaryParenthesesDiagnostic(string text, int line, int column, DiagnosticSeverity severity) - => GetRemoveUnnecessaryParenthesesDiagnostic(text, line, column).WithEffectiveSeverity(severity); - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryParentheses)] public async Task TestArithmeticRequiredForClarity2() { diff --git a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs index c32dc8fb025cf..0dc59d6fef4ee 100644 --- a/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs +++ b/src/Analyzers/CSharp/Tests/UseIsNullCheck/UseIsNullCheckForReferenceEqualsTests.cs @@ -5,7 +5,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Shared.Extensions; using Microsoft.CodeAnalysis.CSharp.UseIsNullCheck; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics; @@ -13,12 +12,18 @@ using Roslyn.Test.Utilities; using Xunit; +#if !CODE_STYLE +using Microsoft.CodeAnalysis.CSharp.Shared.Extensions; +#endif + namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseIsNullCheck { public partial class UseIsNullCheckForReferenceEqualsTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest { private static readonly ParseOptions CSharp7 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7); +#if !CODE_STYLE private static readonly ParseOptions CSharp9 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersionExtensions.CSharp9); +#endif internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace) => (new CSharpUseIsNullCheckForReferenceEqualsDiagnosticAnalyzer(), new CSharpUseIsNullCheckForReferenceEqualsCodeFixProvider()); diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs index fff8f02338a9c..c7237894f9ede 100644 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs +++ b/src/Features/Core/Portable/Diagnostics/AnalyzerHelper.cs @@ -484,6 +484,7 @@ public static async Task> ComputeProjectDiagnosticAna private static bool IsCanceled(Exception ex, CancellationToken cancellationToken) => (ex as OperationCanceledException)?.CancellationToken == cancellationToken; +#if DEBUG private static async Task VerifyDiagnosticLocationsAsync(ImmutableArray diagnostics, Project project, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) @@ -564,6 +565,7 @@ async Task VerifyDiagnosticLocationAsync(string id, Location location) return null; } } +#endif public static IEnumerable ConvertToLocalDiagnostics(this IEnumerable diagnostics, Document targetDocument, TextSpan? span = null) { diff --git a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs index 1c5feafbc57c6..2b474f937be9c 100644 --- a/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs +++ b/src/Features/Core/Portable/Diagnostics/EngineV2/DiagnosticIncrementalAnalyzer_GetDiagnosticsForSpan.cs @@ -271,20 +271,20 @@ private void VerifyDiagnostics(SemanticModel model) GC.KeepAlive(wholeMethodBodyDiagnostics); GC.KeepAlive(wholeDiagnostics); } -#endif - } - private static bool IsUnusedImportDiagnostic(Diagnostic d) - { - switch (d.Id) + static bool IsUnusedImportDiagnostic(Diagnostic d) { - case "CS8019": - case "BC50000": - case "BC50001": - return true; - default: - return false; + switch (d.Id) + { + case "CS8019": + case "BC50000": + case "BC50001": + return true; + default: + return false; + } } +#endif } private static TextSpan AdjustSpan(Document document, SyntaxNode root, TextSpan span) diff --git a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs index 54812da289f96..27ddc14d7aeb6 100644 --- a/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs +++ b/src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.Editor.cs @@ -562,14 +562,6 @@ private ITypeSymbol FixType( return typeSymbol.RemoveUnnamedErrorTypes(compilation); } - private ICodeGenerationService GetCodeGenerationService() - { - var language = _state.TypeToGenerateInOpt == null - ? _state.SimpleName.Language - : _state.TypeToGenerateInOpt.Language; - return _semanticDocument.Project.Solution.Workspace.Services.GetLanguageServices(language).GetService(); - } - private bool TryFindMatchingField( ParameterName parameterName, ITypeSymbol parameterType, diff --git a/src/Workspaces/Core/Portable/Storage/SQLite/v1/Interop/SqlConnection.cs b/src/Workspaces/Core/Portable/Storage/SQLite/v1/Interop/SqlConnection.cs index e82055a10641b..14d3c38dbb59a 100644 --- a/src/Workspaces/Core/Portable/Storage/SQLite/v1/Interop/SqlConnection.cs +++ b/src/Workspaces/Core/Portable/Storage/SQLite/v1/Interop/SqlConnection.cs @@ -31,10 +31,12 @@ internal class SqlConnection /// private readonly SafeSqliteHandle _handle; +#pragma warning disable IDE0052 // Remove unread private members - TODO: Can this field be removed? /// /// For testing purposes to simulate failures during testing. /// private readonly IPersistentStorageFaultInjector _faultInjector; +#pragma warning restore IDE0052 // Remove unread private members /// /// Our cache of prepared statements for given sql strings. diff --git a/src/Workspaces/Core/Portable/Storage/SQLite/v2/Interop/SqlConnection.cs b/src/Workspaces/Core/Portable/Storage/SQLite/v2/Interop/SqlConnection.cs index ac7b5b541b95d..2cc33a220bde9 100644 --- a/src/Workspaces/Core/Portable/Storage/SQLite/v2/Interop/SqlConnection.cs +++ b/src/Workspaces/Core/Portable/Storage/SQLite/v2/Interop/SqlConnection.cs @@ -31,10 +31,12 @@ internal class SqlConnection /// private readonly SafeSqliteHandle _handle; +#pragma warning disable IDE0052 // Remove unread private members - TODO: Can this field be removed? /// /// For testing purposes to simulate failures during testing. /// private readonly IPersistentStorageFaultInjector _faultInjector; +#pragma warning restore IDE0052 // Remove unread private members /// /// Our cache of prepared statements for given sql strings. diff --git a/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesFiles.cs b/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesFiles.cs index c9aa4851af285..a206c00b3a57c 100644 --- a/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesFiles.cs +++ b/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesFiles.cs @@ -23,7 +23,7 @@ public TestDynamicFileInfoProviderThatProducesFiles() { } - public event EventHandler Updated; + event EventHandler IDynamicFileInfoProvider.Updated { add { } remove { } } public Task GetDynamicFileInfoAsync(ProjectId projectId, string projectFilePath, string filePath, CancellationToken cancellationToken) { @@ -48,8 +48,5 @@ public static string GetDynamicFileText(string filePath) public Task RemoveDynamicFileInfoAsync(ProjectId projectId, string projectFilePath, string filePath, CancellationToken cancellationToken) => Task.CompletedTask; - - private void OnUpdate() - => Updated?.Invoke(this, "test"); } } diff --git a/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesNoFiles.cs b/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesNoFiles.cs index 3f2797c8fff79..72599dd2b35a2 100644 --- a/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesNoFiles.cs +++ b/src/Workspaces/CoreTestUtilities/TestDynamicFileInfoProviderThatProducesNoFiles.cs @@ -22,15 +22,12 @@ public TestDynamicFileInfoProviderThatProducesNoFiles() { } - public event EventHandler Updated; + event EventHandler IDynamicFileInfoProvider.Updated { add { } remove { } } public Task GetDynamicFileInfoAsync(ProjectId projectId, string projectFilePath, string filePath, CancellationToken cancellationToken) => Task.FromResult(null); public Task RemoveDynamicFileInfoAsync(ProjectId projectId, string projectFilePath, string filePath, CancellationToken cancellationToken) => Task.CompletedTask; - - private void OnUpdate() - => Updated?.Invoke(this, "test"); } } From f1f3b9c4b855da1e551a4a4584180c9b4f2dee02 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Tue, 12 May 2020 18:20:32 -0700 Subject: [PATCH 161/222] Fix crash in ref-returning property (#44186) --- .../Portable/FlowAnalysis/DefiniteAssignment.cs | 13 ++++++++----- .../Semantic/Semantics/RefLocalsAndReturnsTests.cs | 13 +++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs index 9777e930a58cf..8a016b98fbfe4 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/DefiniteAssignment.cs @@ -1879,6 +1879,7 @@ public override BoundNode VisitAddressOfOperator(BoundAddressOfOperator node) return null; } +#nullable enable protected override void WriteArgument(BoundExpression arg, RefKind refKind, MethodSymbol method) { if (refKind == RefKind.Ref) @@ -1895,11 +1896,12 @@ protected override void WriteArgument(BoundExpression arg, RefKind refKind, Meth // we assume that external method may write and/or read all of its fields (recursively). // Strangely, the native compiler requires the "ref", even for reference types, to exhibit // this behavior. - if (refKind != RefKind.None && ((object)method == null || method.IsExtern)) + if (refKind != RefKind.None && ((object)method == null || method.IsExtern) && arg.Type is TypeSymbol type) { - MarkFieldsUsed(arg.Type); + MarkFieldsUsed(type); } } +#nullable restore protected void CheckAssigned(BoundExpression expr, SyntaxNode node) { @@ -1936,6 +1938,7 @@ protected void CheckAssigned(BoundExpression expr, SyntaxNode node) } } +#nullable enable private void MarkFieldsUsed(TypeSymbol type) { switch (type.TypeKind) @@ -1951,9 +1954,7 @@ private void MarkFieldsUsed(TypeSymbol type) return; } - var namedType = (NamedTypeSymbol)type; - var assembly = type.ContainingAssembly as SourceAssemblySymbol; - if ((object)assembly == null) + if (!(type.ContainingAssembly is SourceAssemblySymbol assembly)) { return; // could be retargeting assembly } @@ -1961,6 +1962,7 @@ private void MarkFieldsUsed(TypeSymbol type) var seen = assembly.TypesReferencedInExternalMethods; if (seen.Add(type)) { + var namedType = (NamedTypeSymbol)type; foreach (var symbol in namedType.GetMembersUnordered()) { if (symbol.Kind != SymbolKind.Field) @@ -1976,6 +1978,7 @@ private void MarkFieldsUsed(TypeSymbol type) return; } } +#nullable restore public override BoundNode VisitBaseReference(BoundBaseReference node) { diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index 3f013fea47d80..6afe8b1dc881b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -990,6 +990,19 @@ ref int P Diagnostic(ErrorCode.ERR_RefLocalOrParamExpected, "P").WithLocation(8, 9)); } + [Fact, WorkItem(44153, "https://github.com/dotnet/roslyn/issues/44153")] + public void RefErrorProperty() + { + CreateCompilation(@" +public class C { + public ref ERROR Prop => throw null!; +} +").VerifyEmitDiagnostics( + // (3,16): error CS0246: The type or namespace name 'ERROR' could not be found (are you missing a using directive or an assembly reference?) + // public ref ERROR Prop => throw null!; + Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "ERROR").WithArguments("ERROR").WithLocation(3, 16)); + } + [Fact] public void RefReadonlyOnlyIn72() { From b8585be8e9ff9e30dbe64980e2c9156ae8b6c2bf Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Tue, 12 May 2020 18:34:44 -0700 Subject: [PATCH 162/222] No longer add dumps by default (#44094) NFE should no longer collect dumps by default. Instead, we want them to be controlled remotely if possible, or sampled via watson. --- .../Def/Implementation/Watson/WatsonReporter.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Watson/WatsonReporter.cs b/src/VisualStudio/Core/Def/Implementation/Watson/WatsonReporter.cs index 3d598821b4101..7f328328180ef 100644 --- a/src/VisualStudio/Core/Def/Implementation/Watson/WatsonReporter.cs +++ b/src/VisualStudio/Core/Def/Implementation/Watson/WatsonReporter.cs @@ -93,16 +93,19 @@ public static void ReportNonFatal(Exception exception) exceptionObject: exception, gatherEventDetails: faultUtility => { - // add current process dump - faultUtility.AddProcessDump(currentProcess.Id); - - // add ServiceHub log files: - foreach (var path in CollectServiceHubLogFilePaths()) + if (faultUtility is FaultEvent { IsIncludedInWatsonSample: true }) { - faultUtility.AddFile(path); + // add ServiceHub log files: + foreach (var path in CollectServiceHubLogFilePaths()) + { + faultUtility.AddFile(path); + } } - // Returning "0" signals that we should send data to Watson; any other value will cancel the Watson report. + // Returning "0" signals that, if sampled, we should send data to Watson. + // Any other value will cancel the Watson report. We never want to trigger a process dump manually, + // we'll let TargetedNotifications determine if a dump should be collected. + // See https://aka.ms/roslynnfwdocs for more details return 0; }); From ee660b5e1bb95c608179bacc41aa106a8ac59b0a Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 18:46:27 -0700 Subject: [PATCH 163/222] [Dogfooding[ Enforce IDE0011 (Add braces) as a build warning for some IDE projects My prior attempt to enable this as a build warning in https://github.com/dotnet/roslyn/pull/44164 did not work due to #44201. This PR actually adds the build enforcement and fixes the violations. --- .editorconfig | 2 ++ .../CSharpDeclarationComputer.cs | 33 +++++++++++++++---- ...CSharpConvertLinqQueryToForEachProvider.cs | 4 ++- ...DisambiguateSameVariableCodeFixProvider.cs | 2 ++ ...IntroduceVariableService_IntroduceLocal.cs | 2 ++ ...erseForStatementCodeRefactoringProvider.cs | 2 ++ .../AbstractConflictMarkerCodeFixProvider.cs | 2 ++ .../RegularExpressions/RegexCharClass.cs | 6 ++++ .../ConflictEngine/RenamedSpansTracker.cs | 2 ++ .../AbstractSelectedMembers.cs | 2 ++ 10 files changed, 50 insertions(+), 7 deletions(-) diff --git a/.editorconfig b/.editorconfig index 699fb17642c9f..c21dd878f51cc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -231,6 +231,8 @@ dotnet_diagnostic.IDE0005.severity = warning # IDE0011: Add braces csharp_prefer_braces = when_multiline:warning +# NOTE: We need the below severity entry for Add Braces due to https://github.com/dotnet/roslyn/issues/44201 +dotnet_diagnostic.IDE0011.severity = warning # IDE0035: Remove unreachable code dotnet_diagnostic.IDE0035.severity = warning diff --git a/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs b/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs index b930a860512b7..369a958180fc9 100644 --- a/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs +++ b/src/Compilers/CSharp/CSharpAnalyzerDriver/CSharpDeclarationComputer.cs @@ -72,7 +72,11 @@ private static void ComputeDeclarations( case SyntaxKind.NamespaceDeclaration: { var ns = (NamespaceDeclarationSyntax)node; - foreach (var decl in ns.Members) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + foreach (var decl in ns.Members) + { + ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } + var declInfo = GetDeclarationInfo(model, node, getSymbol, cancellationToken); builder.Add(declInfo); @@ -94,7 +98,11 @@ private static void ComputeDeclarations( case SyntaxKind.InterfaceDeclaration: { var t = (TypeDeclarationSyntax)node; - foreach (var decl in t.Members) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + foreach (var decl in t.Members) + { + ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } + var attributes = GetAttributes(t.AttributeLists).Concat(GetTypeParameterListAttributes(t.TypeParameterList)); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; @@ -103,7 +111,11 @@ private static void ComputeDeclarations( case SyntaxKind.EnumDeclaration: { var t = (EnumDeclarationSyntax)node; - foreach (var decl in t.Members) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + foreach (var decl in t.Members) + { + ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } + var attributes = GetAttributes(t.AttributeLists); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); return; @@ -133,7 +145,10 @@ private static void ComputeDeclarations( var t = (EventDeclarationSyntax)node; if (t.AccessorList != null) { - foreach (var decl in t.AccessorList.Accessors) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + foreach (var decl in t.AccessorList.Accessors) + { + ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } } var attributes = GetAttributes(t.AttributeLists); builder.Add(GetDeclarationInfo(model, node, getSymbol, attributes, cancellationToken)); @@ -170,7 +185,10 @@ private static void ComputeDeclarations( var t = (PropertyDeclarationSyntax)node; if (t.AccessorList != null) { - foreach (var decl in t.AccessorList.Accessors) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + foreach (var decl in t.AccessorList.Accessors) + { + ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } } if (t.ExpressionBody != null) @@ -259,7 +277,10 @@ private static void ComputeDeclarations( case SyntaxKind.CompilationUnit: { var t = (CompilationUnitSyntax)node; - foreach (var decl in t.Members) ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + foreach (var decl in t.Members) + { + ComputeDeclarations(model, decl, shouldSkip, getSymbol, builder, newLevel, cancellationToken); + } if (t.AttributeLists.Any()) { diff --git a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs index 70843bcef9336..c2c5c7e55dfd3 100644 --- a/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs +++ b/src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs @@ -98,8 +98,10 @@ public bool TryConvert(out DocumentUpdateInfo documentUpdateInfo) { if (!documentUpdateInfo.Source.IsParentKind(SyntaxKind.Block) && documentUpdateInfo.Destinations.Length > 1) - + { documentUpdateInfo = new DocumentUpdateInfo(documentUpdateInfo.Source, SyntaxFactory.Block(documentUpdateInfo.Destinations)); + } + return true; } diff --git a/src/Features/CSharp/Portable/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs b/src/Features/CSharp/Portable/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs index 374a18fb62e53..a26952fcbfaf0 100644 --- a/src/Features/CSharp/Portable/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/DisambiguateSameVariable/CSharpDisambiguateSameVariableCodeFixProvider.cs @@ -155,7 +155,9 @@ protected override async Task FixAllAsync( { if (!CanFix(semanticModel, diagnostic, cancellationToken, out var nameNode, out var matchingMember, out _)) + { continue; + } var newNameNode = matchingMember.Name.ToIdentifierName(); var newExpr = (ExpressionSyntax)newNameNode; diff --git a/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService_IntroduceLocal.cs b/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService_IntroduceLocal.cs index 5d24c1e094fdf..6ce0acb981c16 100644 --- a/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService_IntroduceLocal.cs +++ b/src/Features/CSharp/Portable/IntroduceVariable/CSharpIntroduceVariableService_IntroduceLocal.cs @@ -419,8 +419,10 @@ private static SyntaxList InsertWithinTriviaOfNext( var nextStatementLeading = nextStatement.GetLeadingTrivia(); var precedingEndOfLine = nextStatementLeading.LastOrDefault(t => t.Kind() == SyntaxKind.EndOfLineTrivia); if (precedingEndOfLine == default) + { return oldStatements.ReplaceRange( nextStatement, new[] { newStatement, nextStatement }); + } var endOfLineIndex = nextStatementLeading.IndexOf(precedingEndOfLine) + 1; diff --git a/src/Features/CSharp/Portable/ReverseForStatement/CSharpReverseForStatementCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ReverseForStatement/CSharpReverseForStatementCodeRefactoringProvider.cs index 20390a88919c5..dd06b42fb65b9 100644 --- a/src/Features/CSharp/Portable/ReverseForStatement/CSharpReverseForStatementCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ReverseForStatement/CSharpReverseForStatementCodeRefactoringProvider.cs @@ -53,7 +53,9 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte if (declaration == null || declaration.Variables.Count != 1 || forStatement.Incrementors.Count != 1) + { return; + } var variable = declaration.Variables[0]; var after = forStatement.Incrementors[0]; diff --git a/src/Features/Core/Portable/ConflictMarkerResolution/AbstractConflictMarkerCodeFixProvider.cs b/src/Features/Core/Portable/ConflictMarkerResolution/AbstractConflictMarkerCodeFixProvider.cs index eebe4a0a83f1f..920e1f741ca6d 100644 --- a/src/Features/Core/Portable/ConflictMarkerResolution/AbstractConflictMarkerCodeFixProvider.cs +++ b/src/Features/Core/Portable/ConflictMarkerResolution/AbstractConflictMarkerCodeFixProvider.cs @@ -93,7 +93,9 @@ private bool ShouldFix( // issue there. if (startTrivia.RawKind == _syntaxKinds.ConflictMarkerTrivia || middleTrivia.RawKind == _syntaxKinds.ConflictMarkerTrivia) + { return false; + } } return true; diff --git a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs index 9b967b47b48e8..68532e2e93f62 100644 --- a/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs +++ b/src/Features/Core/Portable/EmbeddedLanguages/RegularExpressions/RegexCharClass.cs @@ -269,7 +269,9 @@ private static bool CharInClassInternal(char ch, string set, int start, int mySe // reverse this check. Debug.Assert((SETSTART & 0x1) == 1, "If SETSTART is not odd, the calculation below this will be reversed"); if ((min & 0x1) == (start & 0x1)) + { return true; + } else { if (myCategoryLength == 0) @@ -302,7 +304,9 @@ private static bool CharInCategory(char ch, string set, int start, int mySetLeng if (curcat == SpaceConst) { if (char.IsWhiteSpace(ch)) + { return true; + } else { i++; @@ -320,7 +324,9 @@ private static bool CharInCategory(char ch, string set, int start, int mySetLeng if (curcat == NotSpaceConst) { if (!char.IsWhiteSpace(ch)) + { return true; + } else { i++; diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs index 5ab06e6c9a00f..77fb7dc4592cd 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/RenamedSpansTracker.cs @@ -237,8 +237,10 @@ public ImmutableDictionary> GetDocu var builder = ImmutableDictionary.CreateBuilder>(); foreach (var (docId, spans) in _documentToComplexifiedSpansMap) + { builder.Add(docId, spans.SelectAsArray( s => new ComplexifiedSpan(s.OriginalSpan, s.NewSpan, s.ModifiedSubSpans.ToImmutableArray()))); + } return builder.ToImmutable(); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SelectedMembers/AbstractSelectedMembers.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SelectedMembers/AbstractSelectedMembers.cs index ccd3678475cfc..c9a91e86f6ca2 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SelectedMembers/AbstractSelectedMembers.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SelectedMembers/AbstractSelectedMembers.cs @@ -102,7 +102,9 @@ void AddSelectedFieldOrPropertyDeclarations(TMemberDeclarationSyntax member) { if (!(member is TFieldDeclarationSyntax) && !(member is TPropertyDeclarationSyntax)) + { return; + } // first, check if entire member is selected. If so, we definitely include this member. if (textSpan.Contains(member.Span)) From 41e306d610f74985b7fd030a22346ccad301f7ad Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Tue, 12 May 2020 18:58:57 -0700 Subject: [PATCH 164/222] Restore the 'isWriteOnly' parameter removed in previous commit, and actually set Modifiers.IsWriteOnly flag based on this parameter value. This was caught by a unit test failure. --- src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs b/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs index e8dc573119dc5..3f9d000f7fe16 100644 --- a/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs +++ b/src/Workspaces/Core/Portable/Editing/DeclarationModifiers.cs @@ -32,6 +32,7 @@ internal DeclarationModifiers( bool isWithEvents = false, bool isPartial = false, bool isAsync = false, + bool isWriteOnly = false, bool isRef = false, bool isVolatile = false, bool isExtern = false) @@ -48,6 +49,7 @@ internal DeclarationModifiers( (isWithEvents ? Modifiers.WithEvents : Modifiers.None) | (isPartial ? Modifiers.Partial : Modifiers.None) | (isAsync ? Modifiers.Async : Modifiers.None) | + (isWriteOnly ? Modifiers.WriteOnly : Modifiers.None) | (isRef ? Modifiers.Ref : Modifiers.None) | (isVolatile ? Modifiers.Volatile : Modifiers.None) | (isExtern ? Modifiers.Extern : Modifiers.None)) From 3dd419ef5e394f42b61933abc331ae925bc08073 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Wed, 13 May 2020 07:12:54 -0700 Subject: [PATCH 165/222] Fix serialization/deserialization of SymbolUsageInfo in SerializableSourceReferenceItem Fixes #44184 Find References "Kind" column uses `SymbolUsageInfo` for its data. `SymbolUsageInfo` is correctly serialized/deserialized when Find References is invoked via [SymbolFinder.FindReferencesServerCallback](https://github.com/dotnet/roslyn/blob/b8585be8e9ff9e30dbe64980e2c9156ae8b6c2bf/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.FindReferencesServerCallback.cs#L72-L84), as it uses [SerializableReferenceLocation](https://github.com/dotnet/roslyn/blob/a65653a77b2862329052d84816b5fb324f8bc8bd/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs#L156) which uses `SerializableSymbolUsageInfo`. With https://github.com/dotnet/roslyn/pull/43914/, we added a new [FindUsagesServerCallback](https://github.com/dotnet/roslyn/blob/0852232f315e952fee1dc63a0b374614b55c1c69/src/EditorFeatures/Core/FindUsages/IRemoteFindUsagesService.cs#L32) and switched to it for Find references serialization/deserialization. This callback does not use `SerializableSymbolUsageInfo`, hence loses the SymbolUsageInfo for "Kind" column. This change fixes this part. --- .../Core/FindUsages/IRemoteFindUsagesService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EditorFeatures/Core/FindUsages/IRemoteFindUsagesService.cs b/src/EditorFeatures/Core/FindUsages/IRemoteFindUsagesService.cs index 58dbfc471bcf7..01fb1dcb8c309 100644 --- a/src/EditorFeatures/Core/FindUsages/IRemoteFindUsagesService.cs +++ b/src/EditorFeatures/Core/FindUsages/IRemoteFindUsagesService.cs @@ -163,7 +163,7 @@ internal class SerializableSourceReferenceItem { public int DefinitionId; public SerializableDocumentSpan SourceSpan; - public SymbolUsageInfo SymbolUsageInfo; + public SerializableSymbolUsageInfo SymbolUsageInfo; public (string Key, string Value)[] AdditionalProperties; public static SerializableSourceReferenceItem Dehydrate( @@ -173,7 +173,7 @@ public static SerializableSourceReferenceItem Dehydrate( { DefinitionId = definitionId, SourceSpan = SerializableDocumentSpan.Dehydrate(item.SourceSpan), - SymbolUsageInfo = item.SymbolUsageInfo, + SymbolUsageInfo = SerializableSymbolUsageInfo.Dehydrate(item.SymbolUsageInfo), AdditionalProperties = item.AdditionalProperties.Select(kvp => (kvp.Key, kvp.Value)).ToArray(), }; } @@ -183,7 +183,7 @@ public SourceReferenceItem Rehydrate(Solution solution, DefinitionItem definitio return new SourceReferenceItem( definition, SourceSpan.Rehydrate(solution), - SymbolUsageInfo, + SymbolUsageInfo.Rehydrate(), AdditionalProperties.ToImmutableDictionary(t => t.Key, t => t.Value)); } } From bc0b404fbeed7a62a7052c57a07b3e4082a5d5e5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 13 May 2020 12:21:19 -0700 Subject: [PATCH 166/222] initial --- .../MetadataAsSource/MetadataAsSourceTests.cs | 5 +- .../AbstractMetadataAsSourceService.cs | 23 ------- .../CodeGeneration/AttributeGenerator.cs | 63 +++++++++++++++---- .../CSharpCodeGenerationHelpers.cs | 9 +++ .../CodeGeneration/TypeParameterGenerator.cs | 3 +- .../NullableSyntaxAnnotation.cs | 15 +++++ 6 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index 559aa0ad569bd..93e805883971b 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -591,10 +591,7 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.CSh // {CodeAnalysisResources.InMemoryAssembly} #endregion -using System.Runtime.CompilerServices; - -[NullableContextAttribute(1)] -public interface [|C|]<[NullableAttribute(2)] T> +public interface [|C|] {{ bool Equals([AllowNullAttribute] T other); }}"); diff --git a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs index b1e5be14d07b8..89f3d1183793d 100644 --- a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs @@ -41,8 +41,6 @@ public async Task AddSourceToAsync(Document document, Compilation symb CreateCodeGenerationOptions(newSemanticModel.SyntaxTree.GetLocation(new TextSpan()), symbol), cancellationToken).ConfigureAwait(false); - document = await RemoveSimplifierAnnotationsFromImportsAsync(document, cancellationToken).ConfigureAwait(false); - var docCommentFormattingService = document.GetLanguageService(); var docWithDocComments = await ConvertDocCommentsToRegularCommentsAsync(document, docCommentFormattingService, cancellationToken).ConfigureAwait(false); @@ -55,27 +53,6 @@ public async Task AddSourceToAsync(Document document, Compilation symb return await Simplifier.ReduceAsync(formattedDoc, reducers, null, cancellationToken).ConfigureAwait(false); } - /// - /// adds to Import Directives it adds, - /// which causes the to remove import directives when thety are only used by attributes. - /// Presumably this is because MetadataAsSource isn't actually semantically valid code. - /// - /// To fix this we remove these annotations. - /// - private static async Task RemoveSimplifierAnnotationsFromImportsAsync(Document document, CancellationToken cancellationToken) - { - var syntaxFacts = document.GetLanguageService(); - - var importDirectives = (await document.GetSyntaxRootAsync().ConfigureAwait(false)) - .DescendantNodesAndSelf() - .Where(syntaxFacts.IsUsingOrExternOrImport); - - return await document.ReplaceNodesAsync( - importDirectives, - (o, c) => c.WithoutAnnotations(Simplifier.Annotation), - cancellationToken).ConfigureAwait(false); - } - /// /// provide formatting rules to be used when formatting MAS file /// diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs index a1d87442510a1..d6a6600726123 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -16,53 +17,89 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeGeneration { internal static class AttributeGenerator { - public static SyntaxList GenerateAttributeLists( + public static (SyntaxList, bool isNullable) GenerateAttributeLists( ImmutableArray attributes, CodeGenerationOptions options, SyntaxToken? target = null) { if (options.MergeAttributes) { - var attributeNodes = attributes.OrderBy(a => a.AttributeClass.Name).Select(a => GenerateAttribute(a, options)).WhereNotNull().ToList(); - return attributeNodes.Count == 0 + var pairs = attributes.OrderBy(a => a.AttributeClass.Name).Select(a => GenerateAttribute(a, options)).ToList(); + var isNullable = pairs.Any(t => t.isNullable); + var attributeNodes = pairs.Select(p => p.syntax).WhereNotNull().ToList(); + + var list = attributeNodes.Count == 0 ? default : SyntaxFactory.SingletonList(SyntaxFactory.AttributeList( target.HasValue ? SyntaxFactory.AttributeTargetSpecifier(target.Value) : null, SyntaxFactory.SeparatedList(attributeNodes))); + return (list, isNullable); } else { - var attributeDeclarations = attributes.OrderBy(a => a.AttributeClass.Name).Select(a => GenerateAttributeDeclaration(a, target, options)).WhereNotNull().ToList(); - return attributeDeclarations.Count == 0 - ? default - : SyntaxFactory.List(attributeDeclarations); + var pairs = attributes.OrderBy(a => a.AttributeClass.Name).Select(a => GenerateAttributeDeclaration(a, target, options)).ToList(); + var isNullable = pairs.Any(t => t.isNullable); + + var list = SyntaxFactory.List(pairs.Select(t => t.syntax).WhereNotNull()); + return (list, isNullable); } } - private static AttributeListSyntax GenerateAttributeDeclaration( + private static (AttributeListSyntax syntax, bool isNullable) GenerateAttributeDeclaration( AttributeData attribute, SyntaxToken? target, CodeGenerationOptions options) { - var attributeSyntax = GenerateAttribute(attribute, options); - return attributeSyntax == null + var (attributeSyntax, isNullable) = GenerateAttribute(attribute, options); + var resultSyntax = attributeSyntax == null ? null : SyntaxFactory.AttributeList( target.HasValue ? SyntaxFactory.AttributeTargetSpecifier(target.Value) : null, SyntaxFactory.SingletonSeparatedList(attributeSyntax)); + + return (resultSyntax, isNullable); } - private static AttributeSyntax GenerateAttribute(AttributeData attribute, CodeGenerationOptions options) + private static (AttributeSyntax syntax, bool isNullable) GenerateAttribute(AttributeData attribute, CodeGenerationOptions options) { + NullableAnnotation + // Never add the internal nullable attributes the compiler generates. + if (IsCompilerInternalNulllableAttribute(attribute)) + return (null, isNullable: true); + if (!options.MergeAttributes) { var reusableSyntax = GetReuseableSyntaxNodeForAttribute(attribute, options); if (reusableSyntax != null) { - return reusableSyntax; + return (reusableSyntax, isNullable: false); } } var attributeArguments = GenerateAttributeArgumentList(attribute); - return !(attribute.AttributeClass.GenerateTypeSyntax() is NameSyntax nameSyntax) ? null : SyntaxFactory.Attribute(nameSyntax, attributeArguments); + var syntax = !(attribute.AttributeClass.GenerateTypeSyntax() is NameSyntax nameSyntax) ? null : SyntaxFactory.Attribute(nameSyntax, attributeArguments); + + return (syntax, isNullable: false); + } + + private static bool IsCompilerInternalNulllableAttribute(AttributeData attribute) + { + // from https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-metadata.md + var attrClass = attribute.AttributeClass; + var name = attrClass.Name; + + if (name != "NullableAttribute" && name != "NullableContextAttribute") + return false; + + + var ns = attrClass.ContainingNamespace; + return ns?.Name == nameof(System.Runtime.CompilerServices) && + ns.ContainingNamespace?.Name == nameof(System.Runtime) && + ns.ContainingNamespace.ContainingNamespace?.Name == nameof(System) && + ns.ContainingNamespace.ContainingNamespace.ContainingNamespace?.IsGlobalNamespace == true; + } + + private static bool IsSystemRuntimeCompilerServicesNamespace(INamespaceSymbol containingNamespace) + { + throw new NotImplementedException(); } private static AttributeArgumentListSyntax GenerateAttributeArgumentList(AttributeData attribute) diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs index b0adf9fcfdb7c..62049bf48cb79 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs @@ -30,6 +30,15 @@ public static TDeclarationSyntax ConditionallyAddFormattingAnnotationTo( + TDeclarationSyntax result, + bool isNullable) where TDeclarationSyntax : SyntaxNode + { + return isNullable + ? result.WithAdditionalAnnotations(NullableAnnotation.Instance) + : result; + } + internal static void AddAccessibilityModifiers( Accessibility accessibility, ArrayBuilder tokens, diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs index f996df0594046..8c0dd1d29deb7 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs @@ -27,8 +27,9 @@ private static TypeParameterSyntax GenerateTypeParameter(ITypeParameterSymbol sy symbol.Variance == VarianceKind.In ? SyntaxFactory.Token(SyntaxKind.InKeyword) : symbol.Variance == VarianceKind.Out ? SyntaxFactory.Token(SyntaxKind.OutKeyword) : default; + var (attributes, isNullable) = AttributeGenerator.GenerateAttributeLists(symbol.GetAttributes(), options) return SyntaxFactory.TypeParameter( - AttributeGenerator.GenerateAttributeLists(symbol.GetAttributes(), options), + attributes, varianceKeyword, symbol.Name.ToIdentifierToken()); } diff --git a/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs b/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs new file mode 100644 index 0000000000000..4d53de64e6cc7 --- /dev/null +++ b/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Microsoft.CodeAnalysis.CodeGeneration +{ + /// + /// Annotation placed if the code generator encounters a NullableAttribute or NullableContextAttribute while + /// generating the code. + /// + internal sealed class NullableSyntaxAnnotation + { + public static readonly SyntaxAnnotation Instance = new SyntaxAnnotation(nameof(NullableAnnotation)); + } +} From a2e5f8733bd61180f908d64f27cc3d00804e76b3 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Wed, 13 May 2020 12:11:11 -0700 Subject: [PATCH 167/222] Update to roslyn-analyzers 3.3.0-beta1.20262.5 --- eng/Versions.props | 2 +- eng/config/rulesets/Shipping.ruleset | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 183852665ebdc..367f513e24633 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -27,7 +27,7 @@ - 3.3.0-beta1.20257.5 + 3.3.0-beta1.20262.5 3.6.0-2.final 1.0.1-beta1.20210.2 3.7.0-1.20210.7 diff --git a/eng/config/rulesets/Shipping.ruleset b/eng/config/rulesets/Shipping.ruleset index 161ff6f8744d9..f400d3411ae49 100644 --- a/eng/config/rulesets/Shipping.ruleset +++ b/eng/config/rulesets/Shipping.ruleset @@ -60,7 +60,7 @@ - + From 7d0d320aa3d0c884e5090914401832e7ab4d3573 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Wed, 13 May 2020 12:48:00 -0700 Subject: [PATCH 168/222] Replace TODOs in comments with github issue links --- src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb | 2 +- .../CoreTestUtilities/Formatting/FormattingTestBase.cs | 2 +- .../Simplification/Reducers/VisualBasicEscapingReducer.vb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb index ec4a4f6c5b54a..63e5f40c84718 100644 --- a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb +++ b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb @@ -59,7 +59,7 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Assert.Equal(referencePath, DirectCast(metadataReference, PortableExecutableReference).FilePath) End Sub -#Disable Warning IDE0060 ' Remove unused parameter - TODO: File a test issue +#Disable Warning IDE0060 ' Remove unused parameter - https://github.com/dotnet/roslyn/issues/44224 Public Async Sub TestSourceFilePathMappingWithDriveLetters( from As String, [to] As String) diff --git a/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs b/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs index 83c116da11068..e2b9a4c3e7d93 100644 --- a/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs +++ b/src/Workspaces/CoreTestUtilities/Formatting/FormattingTestBase.cs @@ -37,7 +37,7 @@ private protected async Task AssertFormatAsync( string code, IEnumerable spans, string language, -#pragma warning disable IDE0060 // Remove unused parameter - TODO: File a test bug as quite a few formatting tests pass in 'debugMode: true', but the value is ignored. +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/44225 bool debugMode = false, #pragma warning restore IDE0060 // Remove unused parameter OptionsCollection? changedOptionSet = null, diff --git a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb index ea8ced9b30453..bb16ef4da24e1 100644 --- a/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb +++ b/src/Workspaces/VisualBasic/Portable/Simplification/Reducers/VisualBasicEscapingReducer.vb @@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification End Sub #Disable Warning IDE0060 ' Remove unused parameter - False positive, used as a delegate in a nested type. - ' TODO: File a bug for this 'IDE0060' false positive. + ' https://github.com/dotnet/roslyn/issues/44226 Private Shared Function TryUnescapeToken(identifier As SyntaxToken, semanticModel As SemanticModel, optionSet As OptionSet, cancellationToken As CancellationToken) As SyntaxToken #Enable Warning IDE0060 ' Remove unused parameter If Not identifier.IsBracketed Then From 982ed5353dd0d137fcd4600b2daf8ff0803d70e6 Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Wed, 13 May 2020 23:12:28 +0200 Subject: [PATCH 169/222] Remove unused parameter --- .../Diagnostics/UpgradeProject/UpgradeProjectTests.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs index 9422d68904fae..dc843c5c1a770 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs @@ -49,12 +49,7 @@ private async Task TestLanguageVersionUpgradedAsync( await TestAsync(initialMarkup, initialMarkup, parseOptions); // no change to markup } - private async Task TestLanguageVersionNotUpgradedAsync(string initialMarkup, -#pragma warning disable IDE0060 // Remove unused parameter - LanguageVersion expected, -#pragma warning restore IDE0060 // Remove unused parameter - ParseOptions parseOptions, - int index = 0) + private async Task TestLanguageVersionNotUpgradedAsync(string initialMarkup, ParseOptions parseOptions, int index = 0) { var parameters = new TestParameters(parseOptions: parseOptions, index: index); using var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters); @@ -789,7 +784,6 @@ void M1() ", - expected: LanguageVersion.Preview, new CSharpParseOptions(LanguageVersion.CSharp7_3)); } From 3164a4f251a9bbf1ca13812c54a8590e9afcbcad Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 13 May 2020 14:48:30 -0700 Subject: [PATCH 170/222] Generate #nullable --- .../MetadataAsSourceTests.CSharp.cs | 6 - .../MetadataAsSourceTests.VisualBasic.cs | 3 - .../MetadataAsSource/MetadataAsSourceTests.cs | 71 +++++-- .../CSharpMetadataAsSourceService.cs | 195 ++++++++++++++---- .../MetadataAsSource/FormattingRule.cs | 67 ++++++ .../AbstractMetadataAsSourceService.cs | 6 +- .../VisualBasicMetadataAsSourceService.vb | 6 + .../CodeGeneration/AttributeGenerator.cs | 77 ++++--- .../CSharpCodeGenerationHelpers.cs | 9 - .../CodeGeneration/TypeParameterGenerator.cs | 3 +- .../CSharpSimplificationService.cs | 1 - .../NullableSyntaxAnnotation.cs | 4 +- .../ITypeParameterSymbolExtensions.cs | 9 +- .../Extensions/ITypeSymbolExtensions.cs | 20 +- 14 files changed, 357 insertions(+), 120 deletions(-) create mode 100644 src/Features/CSharp/Portable/MetadataAsSource/FormattingRule.cs diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.CSharp.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.CSharp.cs index c4bba9a44689b..d0571c8d0e34e 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.CSharp.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.CSharp.cs @@ -43,14 +43,10 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.CSh // {CodeAnalysisResources.InMemoryAssembly} #endregion -using System; -using System.Runtime.CompilerServices; public class [|C|] {{ - [NativeIntegerAttribute] public nint i; - [NativeIntegerAttribute] public nuint i2; public C(); @@ -88,8 +84,6 @@ await context.GenerateAndVerifySourceAsync("System.ValueTuple", // System.ValueTuple.dll #endregion -using System; -using System; using System.Collections; namespace System diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.VisualBasic.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.VisualBasic.cs index 0287feff0e964..1843c64efa49f 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.VisualBasic.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.VisualBasic.cs @@ -44,7 +44,6 @@ public async Task BracketedIdentifierSimplificationTest() ' mscorlib.v4_6_1038_0.dll #End Region -Imports System Imports System.Runtime.InteropServices Namespace System @@ -95,8 +94,6 @@ await context.GenerateAndVerifySourceAsync("System.ValueTuple", ' System.ValueTuple.dll #End Region -Imports System -Imports System Imports System.Collections Namespace System diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index 93e805883971b..ff422cf709b08 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -599,7 +599,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis ' {CodeAnalysisResources.InMemoryAssembly} #End Region -Imports System.Runtime.CompilerServices Public Interface [|C|](Of T) @@ -1701,7 +1700,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis ' {CodeAnalysisResources.InMemoryAssembly} #End Region -Imports System.Runtime.CompilerServices Public Structure [|S|] @@ -1763,7 +1761,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis #End Region Imports System -Imports System.Runtime.CompilerServices Public Structure [|S|] @@ -1794,7 +1791,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis #End Region Imports System -Imports System.Runtime.CompilerServices Public Structure [|S|] @@ -1829,7 +1825,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis ' {CodeAnalysisResources.InMemoryAssembly} #End Region -Imports System.Runtime.CompilerServices Public Structure S Public Sub [|M|]() @@ -1864,7 +1859,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis ' {CodeAnalysisResources.InMemoryAssembly} #End Region -Imports System.Runtime.CompilerServices Public Structure S @@ -1995,7 +1989,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis ' {CodeAnalysisResources.InMemoryAssembly} #End Region -Imports System.Runtime.CompilerServices Public Structure S @@ -2241,7 +2234,6 @@ await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.Vis #End Region Imports System -Imports System.Runtime.CompilerServices Public Structure S @@ -2268,6 +2260,8 @@ void M() // {CodeAnalysisResources.InMemoryAssembly} #endregion +#nullable enable + using System.Runtime.CompilerServices; public class [|TestType|]<[NullableAttribute(1)] T> where T : notnull @@ -2310,13 +2304,12 @@ void M() // {CodeAnalysisResources.InMemoryAssembly} #endregion -using System.Runtime.CompilerServices; +#nullable enable public class TestType {{ public TestType(); - [NullableContextAttribute(1)] public void [|M|]() where T : notnull; }}"; @@ -2349,9 +2342,63 @@ class C // {CodeAnalysisResources.InMemoryAssembly} #endregion -using System.Runtime.CompilerServices; +#nullable enable + +public delegate void [|D|]() where T : notnull;"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable1() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(string) + { + } + +#nullable disable + + public void M(string) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|]<int>(); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion -public delegate void [|D|]<[NullableAttribute(1)] T>() where T : notnull;"; +#nullable enable + +public class TestType +{{ + public TestType(); + + public void [|M|]() where T : notnull; +}}"; using var context = TestContext.Create( LanguageNames.CSharp, diff --git a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs index 2133e2705b58e..803f84f18f0be 100644 --- a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs +++ b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs @@ -7,19 +7,23 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.DocumentationComments; using Microsoft.CodeAnalysis.CSharp.Simplification; -using Microsoft.CodeAnalysis.CSharp.Utilities; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.MetadataAsSource; +using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.MetadataAsSource { - internal class CSharpMetadataAsSourceService : AbstractMetadataAsSourceService + internal partial class CSharpMetadataAsSourceService : AbstractMetadataAsSourceService { private static readonly AbstractFormattingRule s_memberSeparationRule = new FormattingRule(); public static readonly CSharpMetadataAsSourceService Instance = new CSharpMetadataAsSourceService(); @@ -37,16 +41,14 @@ protected override async Task AddAssemblyInfoRegionAsync(Document docu .WithTrailingTrivia(new[] { SyntaxFactory.Space, SyntaxFactory.PreprocessingMessage(assemblyInfo) }); var oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var newRoot = oldRoot.WithLeadingTrivia(new[] - { - SyntaxFactory.Trivia(regionTrivia), - SyntaxFactory.CarriageReturnLineFeed, - SyntaxFactory.Comment("// " + assemblyPath), - SyntaxFactory.CarriageReturnLineFeed, - SyntaxFactory.Trivia(SyntaxFactory.EndRegionDirectiveTrivia(true)), - SyntaxFactory.CarriageReturnLineFeed, - SyntaxFactory.CarriageReturnLineFeed - }); + var newRoot = oldRoot.WithPrependedLeadingTrivia( + SyntaxFactory.Trivia(regionTrivia), + SyntaxFactory.CarriageReturnLineFeed, + SyntaxFactory.Comment("// " + assemblyPath), + SyntaxFactory.CarriageReturnLineFeed, + SyntaxFactory.Trivia(SyntaxFactory.EndRegionDirectiveTrivia(true)), + SyntaxFactory.CarriageReturnLineFeed, + SyntaxFactory.CarriageReturnLineFeed); return document.WithSyntaxRoot(newRoot); } @@ -71,55 +73,162 @@ protected override ImmutableArray GetReducers() new CSharpParenthesizedPatternReducer(), new CSharpDefaultExpressionReducer()); - private class FormattingRule : AbstractMetadataFormattingRule + /// + /// Adds #nullable enable and #nullable disable annotations to the file as necessary. Note that + /// this does not try to be 100% accurate, but rather it handles the most common cases out there. Specifically, + /// if a file contains any nullable annotated/not-annotated types, then we prefix the file with #nullable + /// enable. Then if we hit any members that explicitly have *oblivious* types, not no annotated or + /// non-annotated types, then we switch to #nullable disable for those specific members. + /// + /// This is technically innacurate for possible, but very uncommon cases. For example, if the user's code + /// explicitly did something like this: + /// + /// + /// public void Goo(string goo, + /// #nullable disable + /// string bar + /// #nullable enable + /// string baz); + /// + /// + /// Then we would be unable to handle that. However, this is highly unlikely to happen, and so we accept the + /// inaccuracy for the purpose of simplicity and for handling the much more common cases of either the entire + /// file being annotated, or the user individually disabling annotations at the member level. + /// + protected override async Task AddNullableRegionsAsync(Document document, CancellationToken cancellationToken) + { + var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + var options = (CSharpParseOptions)tree.Options; + + // Only valid for C# 8 and above. + if (options.LanguageVersion < LanguageVersion.CSharp8) + return document; + + var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); + + var (_, annotated, notAnnotated) = GetNullableAnnotations(root); + + // If there are no annotated or not-annotated types, then no need to add `#nullable enable`. + if (!annotated && !notAnnotated) + return document; + + var newRoot = AddNullableRegions(root, cancellationToken); + newRoot = newRoot.WithPrependedLeadingTrivia(CreateNullableTrivia(enable: true)); + + return document.WithSyntaxRoot(newRoot); + } + + private (bool oblivious, bool annotated, bool notAnnotated) GetNullableAnnotations(SyntaxNode node) { - protected override AdjustNewLinesOperation GetAdjustNewLinesOperationBetweenMembersAndUsings(SyntaxToken token1, SyntaxToken token2) + return (HasAnnotation(node, NullableSyntaxAnnotation.None), + HasAnnotation(node, NullableSyntaxAnnotation.Annotated), + HasAnnotation(node, NullableSyntaxAnnotation.NotAnnotated)); + } + + private bool HasAnnotation(SyntaxNode node, SyntaxAnnotation annotation) + { + // see if any child nodes have this annotation. Ignore anything in attributes (like `[Obsolete]void Goo()` + // as these are not impacted by `#nullable` regions. Instead, we only care about signature types. + var annotatedChildren = node.GetAnnotatedNodes(annotation); + return annotatedChildren.Any(n => n.GetAncestorOrThis() == null); + } + + private static SyntaxTrivia[] CreateNullableTrivia(bool enable) + { + var keyword = enable ? SyntaxKind.EnableKeyword : SyntaxKind.DisableKeyword; + return new[] { - var previousToken = token1; - var currentToken = token2; + SyntaxFactory.Trivia(SyntaxFactory.NullableDirectiveTrivia(SyntaxFactory.Token(keyword), isActive: enable)), + SyntaxFactory.ElasticCarriageReturnLineFeed, + SyntaxFactory.ElasticCarriageReturnLineFeed, + }; + } - // We are not between members or usings if the last token wasn't the end of a statement or if the current token - // is the end of a scope. - if ((previousToken.Kind() != SyntaxKind.SemicolonToken && previousToken.Kind() != SyntaxKind.CloseBraceToken) || - currentToken.Kind() == SyntaxKind.CloseBraceToken) + private SyntaxNode AddNullableRegions(SyntaxNode node, CancellationToken cancellationToken) + { + return node switch + { + CompilationUnitSyntax compilationUnit => compilationUnit.WithMembers(AddNullableRegions(compilationUnit.Members, cancellationToken)), + NamespaceDeclarationSyntax ns => ns.WithMembers(AddNullableRegions(ns.Members, cancellationToken)), + TypeDeclarationSyntax type => AddNullableRegionsAroundTypeMembers(type, cancellationToken), + _ => node, + }; + } + + private SyntaxList AddNullableRegions( + SyntaxList members, + CancellationToken cancellationToken) + { + using var _ = ArrayBuilder.GetInstance(out var builder); + + foreach (var member in members) + builder.Add((MemberDeclarationSyntax)AddNullableRegions(member, cancellationToken)); + + return SyntaxFactory.List(builder); + } + + private TypeDeclarationSyntax AddNullableRegionsAroundTypeMembers( + TypeDeclarationSyntax type, CancellationToken cancellationToken) + { + using var _ = ArrayBuilder.GetInstance(out var builder); + + var currentlyEnabled = true; + + foreach (var member in type.Members) + { + if (member is BaseTypeDeclarationSyntax) { - return null; + // if we hit a type, and we're currently disabled, then switch us back to enabled for that type. + // This ensures whenever we walk into a type-decl, we're always in the enabled-state. + builder.Add(TransitionTo(member, enabled: true, ref currentlyEnabled)); + continue; } - SyntaxNode previousMember = FormattingRangeHelper.GetEnclosingMember(previousToken); - SyntaxNode nextMember = FormattingRangeHelper.GetEnclosingMember(currentToken); + // we hit a member. see what sort of types it contained. + var (oblivious, annotated, notAnnotated) = GetNullableAnnotations(member); - // Is the previous statement an using directive? If so, treat it like a member to add - // the right number of lines. - if (previousToken.Kind() == SyntaxKind.SemicolonToken && previousToken.Parent.Kind() == SyntaxKind.UsingDirective) + // if we have null annotations, transition us back to the enabled state + if (annotated || notAnnotated) { - previousMember = previousToken.Parent; + builder.Add(TransitionTo(member, enabled: true, ref currentlyEnabled)); } - - if (previousMember == null || nextMember == null || previousMember == nextMember) + else if (oblivious) { - return null; + // if we didn't have null annotations, and we had an explicit oblivious type, + // then definitely transition us to the disabled state + builder.Add(TransitionTo(member, enabled: false, ref currentlyEnabled)); } - - // If we have two members of the same kind, we won't insert a blank line - if (previousMember.Kind() == nextMember.Kind()) + else { - return FormattingOperations.CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines); + // had no types at all. no need to change state. + builder.Add(member); } - - // Force a blank line between the two nodes by counting the number of lines of - // trivia and adding one to it. - var triviaList = token1.TrailingTrivia.Concat(token2.LeadingTrivia); - return FormattingOperations.CreateAdjustNewLinesOperation(GetNumberOfLines(triviaList) + 1, AdjustNewLinesOption.ForceLines); } - public override void AddAnchorIndentationOperations(List list, SyntaxNode node, in NextAnchorIndentationOperationAction nextOperation) + var result = type.WithMembers(SyntaxFactory.List(builder)); + if (!currentlyEnabled) { - return; + // switch us back to enabled as we leave the type. + result = result.WithCloseBraceToken( + result.CloseBraceToken.WithPrependedLeadingTrivia(CreateNullableTrivia(enable: true))); } - protected override bool IsNewLine(char c) - => SyntaxFacts.IsNewLine(c); + return result; + } + + private MemberDeclarationSyntax TransitionTo(MemberDeclarationSyntax member, bool enabled, ref bool currentlyEnabled) + { + if (enabled == currentlyEnabled) + { + // already in the right state. don't start a #nullable region + return member; + } + else + { + // switch to the desired state and add the right trivia to the node. + currentlyEnabled = enabled; + return member.WithPrependedLeadingTrivia(CreateNullableTrivia(currentlyEnabled)); + } } } } diff --git a/src/Features/CSharp/Portable/MetadataAsSource/FormattingRule.cs b/src/Features/CSharp/Portable/MetadataAsSource/FormattingRule.cs new file mode 100644 index 0000000000000..0920547925e38 --- /dev/null +++ b/src/Features/CSharp/Portable/MetadataAsSource/FormattingRule.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis.CSharp.Utilities; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Formatting.Rules; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.CSharp.MetadataAsSource +{ + internal partial class CSharpMetadataAsSourceService + { + private class FormattingRule : AbstractMetadataFormattingRule + { + protected override AdjustNewLinesOperation GetAdjustNewLinesOperationBetweenMembersAndUsings(SyntaxToken token1, SyntaxToken token2) + { + var previousToken = token1; + var currentToken = token2; + + // We are not between members or usings if the last token wasn't the end of a statement or if the current token + // is the end of a scope. + if ((previousToken.Kind() != SyntaxKind.SemicolonToken && previousToken.Kind() != SyntaxKind.CloseBraceToken) || + currentToken.Kind() == SyntaxKind.CloseBraceToken) + { + return null; + } + + SyntaxNode previousMember = FormattingRangeHelper.GetEnclosingMember(previousToken); + SyntaxNode nextMember = FormattingRangeHelper.GetEnclosingMember(currentToken); + + // Is the previous statement an using directive? If so, treat it like a member to add + // the right number of lines. + if (previousToken.Kind() == SyntaxKind.SemicolonToken && previousToken.Parent.Kind() == SyntaxKind.UsingDirective) + { + previousMember = previousToken.Parent; + } + + if (previousMember == null || nextMember == null || previousMember == nextMember) + { + return null; + } + + // If we have two members of the same kind, we won't insert a blank line + if (previousMember.Kind() == nextMember.Kind()) + { + return FormattingOperations.CreateAdjustNewLinesOperation(1, AdjustNewLinesOption.ForceLines); + } + + // Force a blank line between the two nodes by counting the number of lines of + // trivia and adding one to it. + var triviaList = token1.TrailingTrivia.Concat(token2.LeadingTrivia); + return FormattingOperations.CreateAdjustNewLinesOperation(GetNumberOfLines(triviaList) + 1, AdjustNewLinesOption.ForceLines); + } + + public override void AddAnchorIndentationOperations(List list, SyntaxNode node, in NextAnchorIndentationOperationAction nextOperation) + { + return; + } + + protected override bool IsNewLine(char c) + => SyntaxFacts.IsNewLine(c); + } + } +} diff --git a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs index 89f3d1183793d..4ff18c0060eb2 100644 --- a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs @@ -5,12 +5,10 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.DocumentationComments; -using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Formatting.Rules; using Microsoft.CodeAnalysis.LanguageServices; @@ -41,6 +39,8 @@ public async Task AddSourceToAsync(Document document, Compilation symb CreateCodeGenerationOptions(newSemanticModel.SyntaxTree.GetLocation(new TextSpan()), symbol), cancellationToken).ConfigureAwait(false); + document = await AddNullableRegionsAsync(document, cancellationToken).ConfigureAwait(false); + var docCommentFormattingService = document.GetLanguageService(); var docWithDocComments = await ConvertDocCommentsToRegularCommentsAsync(document, docCommentFormattingService, cancellationToken).ConfigureAwait(false); @@ -53,6 +53,8 @@ public async Task AddSourceToAsync(Document document, Compilation symb return await Simplifier.ReduceAsync(formattedDoc, reducers, null, cancellationToken).ConfigureAwait(false); } + protected abstract Task AddNullableRegionsAsync(Document document, CancellationToken cancellationToken); + /// /// provide formatting rules to be used when formatting MAS file /// diff --git a/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb b/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb index 0d4f35ec180ec..03593e0166d19 100644 --- a/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb +++ b/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports System.Threading +Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.DocumentationComments Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Formatting.Rules @@ -49,6 +50,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MetadataAsSource Return document.WithSyntaxRoot(newRoot) End Function + Protected Overrides Function AddNullableRegionsAsync(document As Document, cancellationToken As CancellationToken) As Task(Of Document) + ' VB has no equivalent to #nullable enable + Return Task.FromResult(document) + End Function + Protected Overrides Async Function ConvertDocCommentsToRegularCommentsAsync(document As Document, docCommentFormattingService As IDocumentationCommentFormattingService, cancellationToken As CancellationToken) As Task(Of Document) Dim syntaxRoot = Await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(False) diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs index d6a6600726123..0c864e30159b7 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; +#nullable enable + using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -17,79 +18,84 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeGeneration { internal static class AttributeGenerator { - public static (SyntaxList, bool isNullable) GenerateAttributeLists( + public static SyntaxList GenerateAttributeLists( ImmutableArray attributes, CodeGenerationOptions options, SyntaxToken? target = null) { if (options.MergeAttributes) { - var pairs = attributes.OrderBy(a => a.AttributeClass.Name).Select(a => GenerateAttribute(a, options)).ToList(); - var isNullable = pairs.Any(t => t.isNullable); - var attributeNodes = pairs.Select(p => p.syntax).WhereNotNull().ToList(); - - var list = attributeNodes.Count == 0 + var attributeNodes = + attributes.OrderBy(a => a.AttributeClass?.Name) + .Select(a => TryGenerateAttribute(a, options)) + .WhereNotNull().ToList(); + return attributeNodes.Count == 0 ? default : SyntaxFactory.SingletonList(SyntaxFactory.AttributeList( target.HasValue ? SyntaxFactory.AttributeTargetSpecifier(target.Value) : null, SyntaxFactory.SeparatedList(attributeNodes))); - return (list, isNullable); } else { - var pairs = attributes.OrderBy(a => a.AttributeClass.Name).Select(a => GenerateAttributeDeclaration(a, target, options)).ToList(); - var isNullable = pairs.Any(t => t.isNullable); - - var list = SyntaxFactory.List(pairs.Select(t => t.syntax).WhereNotNull()); - return (list, isNullable); + var attributeDeclarations = + attributes.OrderBy(a => a.AttributeClass?.Name) + .Select(a => TryGenerateAttributeDeclaration(a, target, options)) + .WhereNotNull().ToList(); + return attributeDeclarations.Count == 0 + ? default + : SyntaxFactory.List(attributeDeclarations); } } - private static (AttributeListSyntax syntax, bool isNullable) GenerateAttributeDeclaration( + private static AttributeListSyntax? TryGenerateAttributeDeclaration( AttributeData attribute, SyntaxToken? target, CodeGenerationOptions options) { - var (attributeSyntax, isNullable) = GenerateAttribute(attribute, options); - var resultSyntax = attributeSyntax == null + var attributeSyntax = TryGenerateAttribute(attribute, options); + return attributeSyntax == null ? null : SyntaxFactory.AttributeList( - target.HasValue ? SyntaxFactory.AttributeTargetSpecifier(target.Value) : null, + target.HasValue + ? SyntaxFactory.AttributeTargetSpecifier(target.Value) + : null, SyntaxFactory.SingletonSeparatedList(attributeSyntax)); - - return (resultSyntax, isNullable); } - private static (AttributeSyntax syntax, bool isNullable) GenerateAttribute(AttributeData attribute, CodeGenerationOptions options) + private static AttributeSyntax? TryGenerateAttribute(AttributeData attribute, CodeGenerationOptions options) { - NullableAnnotation - // Never add the internal nullable attributes the compiler generates. - if (IsCompilerInternalNulllableAttribute(attribute)) - return (null, isNullable: true); + if (IsCompilerInternalAttribute(attribute)) + return null; if (!options.MergeAttributes) { var reusableSyntax = GetReuseableSyntaxNodeForAttribute(attribute, options); if (reusableSyntax != null) { - return (reusableSyntax, isNullable: false); + return reusableSyntax; } } - var attributeArguments = GenerateAttributeArgumentList(attribute); - var syntax = !(attribute.AttributeClass.GenerateTypeSyntax() is NameSyntax nameSyntax) ? null : SyntaxFactory.Attribute(nameSyntax, attributeArguments); + if (attribute.AttributeClass == null) + return null; - return (syntax, isNullable: false); + var attributeArguments = GenerateAttributeArgumentList(attribute); + return attribute.AttributeClass.GenerateTypeSyntax() is NameSyntax nameSyntax + ? SyntaxFactory.Attribute(nameSyntax, attributeArguments) + : null; } - private static bool IsCompilerInternalNulllableAttribute(AttributeData attribute) + + private static bool IsCompilerInternalAttribute(AttributeData attribute) { // from https://github.com/dotnet/roslyn/blob/master/docs/features/nullable-metadata.md var attrClass = attribute.AttributeClass; + if (attrClass == null) + return false; + var name = attrClass.Name; - if (name != "NullableAttribute" && name != "NullableContextAttribute") + if (name != "NullableAttribute" && name != "NullableContextAttribute" && name != "NativeIntegerAttribute") return false; - var ns = attrClass.ContainingNamespace; return ns?.Name == nameof(System.Runtime.CompilerServices) && ns.ContainingNamespace?.Name == nameof(System.Runtime) && @@ -97,17 +103,10 @@ private static bool IsCompilerInternalNulllableAttribute(AttributeData attribute ns.ContainingNamespace.ContainingNamespace.ContainingNamespace?.IsGlobalNamespace == true; } - private static bool IsSystemRuntimeCompilerServicesNamespace(INamespaceSymbol containingNamespace) - { - throw new NotImplementedException(); - } - - private static AttributeArgumentListSyntax GenerateAttributeArgumentList(AttributeData attribute) + private static AttributeArgumentListSyntax? GenerateAttributeArgumentList(AttributeData attribute) { if (attribute.ConstructorArguments.Length == 0 && attribute.NamedArguments.Length == 0) - { return null; - } var arguments = new List(); arguments.AddRange(attribute.ConstructorArguments.Select(c => diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs index 62049bf48cb79..b0adf9fcfdb7c 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpCodeGenerationHelpers.cs @@ -30,15 +30,6 @@ public static TDeclarationSyntax ConditionallyAddFormattingAnnotationTo( - TDeclarationSyntax result, - bool isNullable) where TDeclarationSyntax : SyntaxNode - { - return isNullable - ? result.WithAdditionalAnnotations(NullableAnnotation.Instance) - : result; - } - internal static void AddAccessibilityModifiers( Accessibility accessibility, ArrayBuilder tokens, diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs index 8c0dd1d29deb7..f996df0594046 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/TypeParameterGenerator.cs @@ -27,9 +27,8 @@ private static TypeParameterSyntax GenerateTypeParameter(ITypeParameterSymbol sy symbol.Variance == VarianceKind.In ? SyntaxFactory.Token(SyntaxKind.InKeyword) : symbol.Variance == VarianceKind.Out ? SyntaxFactory.Token(SyntaxKind.OutKeyword) : default; - var (attributes, isNullable) = AttributeGenerator.GenerateAttributeLists(symbol.GetAttributes(), options) return SyntaxFactory.TypeParameter( - attributes, + AttributeGenerator.GenerateAttributeLists(symbol.GetAttributes(), options), varianceKeyword, symbol.Name.ToIdentifierToken()); } diff --git a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs index c9a2f04d2a377..f39761e71c76a 100644 --- a/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs +++ b/src/Workspaces/CSharp/Portable/Simplification/CSharpSimplificationService.cs @@ -183,7 +183,6 @@ protected override void GetUnusedNamespaceImports(SemanticModel model, HashSet internal sealed class NullableSyntaxAnnotation { - public static readonly SyntaxAnnotation Instance = new SyntaxAnnotation(nameof(NullableAnnotation)); + public static readonly SyntaxAnnotation None = new SyntaxAnnotation($"{nameof(NullableAnnotation)}.{NullableAnnotation.None}"); + public static readonly SyntaxAnnotation Annotated = new SyntaxAnnotation($"{nameof(NullableAnnotation)}.{NullableAnnotation.Annotated}"); + public static readonly SyntaxAnnotation NotAnnotated = new SyntaxAnnotation($"{nameof(NullableAnnotation)}.{NullableAnnotation.NotAnnotated}"); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs index 868abea333905..b94750b09bae0 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs @@ -8,6 +8,7 @@ using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Extensions @@ -53,7 +54,13 @@ private static void AddConstraintClauses( } else if (typeParameter.HasNotNullConstraint) { - constraints.Add(SyntaxFactory.TypeConstraint(SyntaxFactory.IdentifierName("notnull"))); + var constraint = SyntaxFactory.TypeConstraint(SyntaxFactory.IdentifierName("notnull")); + +#if !CODE_STYLE + constraint = constraint.WithAdditionalAnnotations(NullableSyntaxAnnotation.Annotated); +#endif + + constraints.Add(constraint); } var constraintTypes = diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs index 6331688f373c0..f1e43cd00e060 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -41,7 +42,8 @@ public static TypeSyntax GenerateTypeSyntax( private static TypeSyntax GenerateTypeSyntax( INamespaceOrTypeSymbol symbol, bool nameSyntax, bool allowVar = true) { - if (symbol is ITypeSymbol type && type.ContainsAnonymousType()) + var type = symbol as ITypeSymbol; + if (type != null && type.ContainsAnonymousType()) { // something with an anonymous type can only be represented with 'var', regardless // of what the user's preferences might be. @@ -56,6 +58,22 @@ private static TypeSyntax GenerateTypeSyntax( syntax = syntax.WithAdditionalAnnotations(DoNotAllowVarAnnotation.Annotation); } +#if !CODE_STYLE + + if (type != null && type.IsReferenceType) + { + syntax = syntax.WithAdditionalAnnotations( + type.NullableAnnotation switch + { + NullableAnnotation.None => NullableSyntaxAnnotation.None, + NullableAnnotation.Annotated => NullableSyntaxAnnotation.Annotated, + NullableAnnotation.NotAnnotated => NullableSyntaxAnnotation.NotAnnotated, + _ => throw ExceptionUtilities.UnexpectedValue(type.NullableAnnotation), + }); + } + +#endif + return syntax; } From 7cd72269e943f82e81ee723d20c6f130bf4a7fb8 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 13 May 2020 15:02:08 -0700 Subject: [PATCH 171/222] Add tests --- .../MetadataAsSource/MetadataAsSourceTests.cs | 243 +++++++++++++++++- .../ITypeParameterSymbolExtensions.cs | 8 +- 2 files changed, 230 insertions(+), 21 deletions(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index ff422cf709b08..c4422114f3494 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -2260,11 +2260,7 @@ void M() // {CodeAnalysisResources.InMemoryAssembly} #endregion -#nullable enable - -using System.Runtime.CompilerServices; - -public class [|TestType|]<[NullableAttribute(1)] T> where T : notnull +public class [|TestType|] where T : notnull {{ public TestType(); }}"; @@ -2304,8 +2300,6 @@ void M() // {CodeAnalysisResources.InMemoryAssembly} #endregion -#nullable enable - public class TestType {{ public TestType(); @@ -2342,8 +2336,6 @@ class C // {CodeAnalysisResources.InMemoryAssembly} #endregion -#nullable enable - public delegate void [|D|]() where T : notnull;"; using var context = TestContext.Create( @@ -2369,13 +2361,13 @@ public async Task TestNullableEnableDisable1() public class TestType { - public void M1(string) + public void M1(string s) { } #nullable disable - public void M(string) + public void M2(string s) { } }"; @@ -2384,20 +2376,243 @@ class C { void M() { - var obj = new TestType().[|M1|]<int>(); + var obj = new TestType().[|M1|](null); } }"; var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // {CodeAnalysisResources.InMemoryAssembly} #endregion -#nullable enable +#nullable enable public class TestType {{ public TestType(); - public void [|M|]() where T : notnull; + public void [|M1|](string s); +#nullable disable + public void M2(string s); + +#nullable enable +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable2() + { + var metadata = @" +using System; + +public class TestType +{ + public void M1(string s) + { + } + +#nullable enable + + public void M2(string s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +public class TestType +{{ + public TestType(); + +#nullable disable + public void [|M1|](string s); +#nullable enable + public void M2(string s); +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable3() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(string s) + { + } + +#nullable disable + + public void M2(string s) + { + } + + public void M3(string s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +public class TestType +{{ + public TestType(); + + public void [|M1|](string s); +#nullable disable + public void M2(string s); + public void M3(string s); + +#nullable enable +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable4() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(ICloneable s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +using System; + +public class TestType +{{ + public TestType(); + + public void [|M1|](ICloneable s); +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable5() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(ICloneable s) + { +#nullable disable + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +using System; + +public class TestType +{{ + public TestType(); + + public void [|M1|](ICloneable s); }}"; using var context = TestContext.Create( diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs index b94750b09bae0..3194ba4c1296b 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs @@ -54,13 +54,7 @@ private static void AddConstraintClauses( } else if (typeParameter.HasNotNullConstraint) { - var constraint = SyntaxFactory.TypeConstraint(SyntaxFactory.IdentifierName("notnull")); - -#if !CODE_STYLE - constraint = constraint.WithAdditionalAnnotations(NullableSyntaxAnnotation.Annotated); -#endif - - constraints.Add(constraint); + constraints.Add(SyntaxFactory.TypeConstraint(SyntaxFactory.IdentifierName("notnull"))); } var constraintTypes = From c2fbd0a12c300411d2e7bf3f390f82b62e7d2ffa Mon Sep 17 00:00:00 2001 From: Alexander Gayko Date: Thu, 14 May 2020 01:58:01 +0200 Subject: [PATCH 172/222] Refactoring "Move tool tip assertions to shared ToolTipAssert class" (commit 04968d4b08d6e213b4058edf7253af3604bcd343) had to be applied to the new methods --- .../Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb b/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb index 51c4ebc9db5a2..0bd1f1bfb5335 100644 --- a/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb +++ b/src/EditorFeatures/Test2/IntelliSense/IntellisenseQuickInfoBuilderTests.vb @@ -1001,7 +1001,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense New ClassifiedTextRun(ClassificationTypeNames.TypeParameterName, "T", navigationAction:=Sub() Return, "T"), New ClassifiedTextRun(ClassificationTypeNames.Text, ".")))) - AssertEqualAdornments(expected, container) + ToolTipAssert.EqualContent(expected, container) End Sub @@ -1053,7 +1053,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.IntelliSense New ClassifiedTextRun(ClassificationTypeNames.Keyword, "int", navigationAction:=Sub() Return, "int"), New ClassifiedTextRun(ClassificationTypeNames.Text, ".")))) - AssertEqualAdornments(expected, container) + ToolTipAssert.EqualContent(expected, container) End Sub From 2e8525920f7f8ea5105cb466fdabcbcc2e8752c0 Mon Sep 17 00:00:00 2001 From: Alexander Gayko Date: Thu, 14 May 2020 02:11:08 +0200 Subject: [PATCH 173/222] deleted three unused methods that were a remnant from copy-pasting. --- ...ctDocumentationCommentFormattingService.cs | 53 ------------------- 1 file changed, 53 deletions(-) diff --git a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs index 81ef18a3f7e9c..cbe82c60881fe 100644 --- a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs @@ -260,59 +260,6 @@ private void EmitPendingChars() } } - private static string GetDocumentation(ISymbol symbol, Compilation compilation, CancellationToken cancellationToken) - => symbol switch - { - IParameterSymbol parameter => GetParameterDocumentation(parameter, compilation, cancellationToken), - ITypeParameterSymbol typeParam => typeParam.ContainingSymbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).GetTypeParameterText(symbol.Name), - IMethodSymbol method => GetMethodDocumentation(method, compilation, cancellationToken), - IAliasSymbol alias => alias.Target.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText, - _ => symbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText, - }; - - private static string GetParameterDocumentation(IParameterSymbol parameter, Compilation compilation, CancellationToken cancellationToken) - { - var containingSymbol = parameter.ContainingSymbol; - if (containingSymbol.ContainingSymbol.IsDelegateType() && containingSymbol is IMethodSymbol methodSymbol) - { - // There are two ways to invoke a delegate that we care about here: the Invoke()/BeginInvoke() methods. (Direct invocation is equivalent to an Invoke() call.) - // DynamicInvoke() takes an object array, and EndInvoke() takes a System.IAsyncResult, so we can (and should) ignore those here. - - var symbolName = methodSymbol.Name; - if (symbolName == WellKnownMemberNames.DelegateBeginInvokeName && parameter.Ordinal >= (methodSymbol.Parameters.Length - 2)) - { - // Return null (similar to DocumentationComment.GetParameterText()) for the last two implicit parameters (usually called "callback" and "@object"). - // We can't rely on those names because they might be renamed to avoid collision with a user-defined delegate parameter of the same name, - // and we have to treat them separately, because a user might add e.g. a '' tag to the delegate, which would be displayed in Signature Help for that implicit parameter. - return null; - } - - if (symbolName == WellKnownMemberNames.DelegateInvokeName || symbolName == WellKnownMemberNames.DelegateBeginInvokeName) - { - // We know that containingSymbol is the [Begin]Invoke() method of a delegate type, so we need to go up a level and take the method's containing symbol (i.e. the delegate), which contains the documentation. - containingSymbol = containingSymbol.ContainingSymbol; - } - } - - // Get the comments from the original definition of the containing symbol. - return containingSymbol.OriginalDefinition.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).GetParameterText(parameter.Name); - } - - private static string GetMethodDocumentation(IMethodSymbol method, Compilation compilation, CancellationToken cancellationToken) - { - switch (method.MethodKind) - { - case MethodKind.EventAdd: - case MethodKind.EventRaise: - case MethodKind.EventRemove: - case MethodKind.PropertyGet: - case MethodKind.PropertySet: - return method.AssociatedSymbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText; - default: - return method.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: cancellationToken).SummaryText; - } - } - public string Format(string rawXmlText, Compilation compilation = null) { if (rawXmlText == null) From 21316855abe8ac2fd70c737ea1d38e6d84077c1c Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Wed, 13 May 2020 19:49:09 -0700 Subject: [PATCH 174/222] Add FindReferences tests for Kind column/SymbolUsageInfo for references --- .../FindReferencesTests.FieldSymbols.vb | 35 ++++++ .../FindReferencesTests.LocalSymbols.vb | 33 ++++++ .../FindReferencesTests.NamedTypeSymbols.vb | 43 ++++++++ .../FindReferencesTests.NamespaceSymbols.vb | 30 ++++++ .../FindReferencesTests.ParameterSymbol.vb | 33 ++++++ .../FindReferencesTests.PropertySymbols.vb | 36 +++++++ .../FindReferences/FindReferencesTests.vb | 101 ++++++++++++++++-- 7 files changed, 301 insertions(+), 10 deletions(-) diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb index f80052cf14c77..bf782721c94e4 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb @@ -411,6 +411,41 @@ class Definition:Program ]]> + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestField_ValueUsageInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class C + { + int {|Definition:$$i|}; + + void Goo() + { + Console.WriteLine({|ValueUsageInfo.Read:[|i|]|}); + {|ValueUsageInfo.Write:[|i|]|} = 0; + {|ValueUsageInfo.ReadWrite:[|i|]|}++; + Goo2(in {|ValueUsageInfo.ReadableReference:[|i|]|}, ref {|ValueUsageInfo.ReadableWritableReference:[|i|]|}); + Goo3(out {|ValueUsageInfo.WritableReference:[|i|]|}); + Console.WriteLine(nameof({|ValueUsageInfo.Name:[|i|]|})); + } + + void Goo2(in int j, ref int k) + { + } + + void Goo3(out int i) + { + i = 0; + } + } + + Await TestAPIAndFeature(input, kind, host) End Function diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.LocalSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.LocalSymbols.vb index cab80c2385090..23e88a1541035 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.LocalSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.LocalSymbols.vb @@ -541,5 +541,38 @@ End Module Await TestAPIAndFeature(input, kind, host) End Function + + Public Async Function TestLocal_ValueUsageInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class C + { + void Goo() + { + int {|Definition:$$i|} = 0; + Console.WriteLine({|ValueUsageInfo.Read:[|i|]|}); + {|ValueUsageInfo.Write:[|i|]|} = 0; + {|ValueUsageInfo.ReadWrite:[|i|]|}++; + Goo2(in {|ValueUsageInfo.ReadableReference:[|i|]|}, ref {|ValueUsageInfo.ReadableWritableReference:[|i|]|}); + Goo3(out {|ValueUsageInfo.WritableReference:[|i|]|}); + Console.WriteLine(nameof({|ValueUsageInfo.Name:[|i|]|})); + } + + void Goo2(in int j, ref int k) + { + } + + void Goo3(out int i) + { + i = 0; + } + } + + + + Await TestAPIAndFeature(input, kind, host) + End Function End Class End Namespace diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb index c8f33244ab7ae..904212a4dcbd5 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb @@ -2189,5 +2189,48 @@ public class D { } End Function + + + + Public Async Function TestNamedType_TypeOrNamespaceUsageInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + { } + + public class {|Definition:$$Class1|} + { + public static int Field; + public class Nested { } + } + + public class Class2 : {|TypeOrNamespaceUsageInfo.Base:[|Class1|]|}, I<{|TypeOrNamespaceUsageInfo.TypeArgument:[|Class1|]|}> + { + public static int M() => {|TypeOrNamespaceUsageInfo.Qualified:[|Class1|]|}.Field; + } + } + + namespace N2.N3 + { + using Alias2 = N2.{|TypeOrNamespaceUsageInfo.Qualified,Import:[|Class1|]|}.Nested; + + public class Class3: {|TypeOrNamespaceUsageInfo.Qualified,Base:[|Class1|]|}.Nested, I<{|TypeOrNamespaceUsageInfo.Qualified,TypeArgument:[|Class1|]|}.Nested> + { + public static [|Class1|] M2() => new {|TypeOrNamespaceUsageInfo.ObjectCreation:[|Class1|]|}(); + } + }]]> + + + + Await TestAPIAndFeature(input, kind, host) + End Function End Class End Namespace diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamespaceSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamespaceSymbols.vb index 5ef025dfd4f2a..429976af4b872 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamespaceSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamespaceSymbols.vb @@ -372,5 +372,35 @@ namespace var { } Await TestAPIAndFeature(input, kind, host) End Function + + + Public Async Function TestNamespace_TypeOrNamespaceUsageInfo(host As TestHost) As Task + Dim input = + + + + using {|TypeOrNamespaceUsageInfo.Import:[|N1|]|}; + using {|TypeOrNamespaceUsageInfo.Qualified,Import:[|N1|]|}.N2; + + namespace {|Definition:{|TypeOrNamespaceUsageInfo.NamespaceDeclaration:[|$$N1|]|}|} + { + public class Class1 + { + public static int Field; + } + } + + namespace {|TypeOrNamespaceUsageInfo.Qualified,NamespaceDeclaration:[|N1|]|}.N2 + { + public class Class2 + { + public static int M() => {|TypeOrNamespaceUsageInfo.Qualified:[|N1|]|}.Class1.Field; + } + } + + + + Await TestAPI(input, host) + End Function End Class End Namespace diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ParameterSymbol.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ParameterSymbol.vb index 07df3ba4e6923..6cf0778b80dd9 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ParameterSymbol.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ParameterSymbol.vb @@ -635,6 +635,39 @@ end class } + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestParameter_ValueUsageInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class C + { + void Goo(int {|Definition:$$i|}) + { + Console.WriteLine({|ValueUsageInfo.Read:[|i|]|}); + {|ValueUsageInfo.Write:[|i|]|} = 0; + {|ValueUsageInfo.ReadWrite:[|i|]|}++; + Goo2(in {|ValueUsageInfo.ReadableReference:[|i|]|}, ref {|ValueUsageInfo.ReadableWritableReference:[|i|]|}); + Goo3(out {|ValueUsageInfo.WritableReference:[|i|]|}); + Console.WriteLine(nameof({|ValueUsageInfo.Name:[|i|]|})); + } + + void Goo2(in int j, ref int k) + { + } + + void Goo3(out int i) + { + i = 0; + } + } + + Await TestAPIAndFeature(input, kind, host) End Function diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.PropertySymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.PropertySymbols.vb index 2e5a2e4ab3fa1..456173ab2826b 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.PropertySymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.PropertySymbols.vb @@ -912,5 +912,41 @@ interface IC Await TestStreamingFeature(input, host) End Function + + + + Public Async Function TestProperty_ValueUsageInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + +using System; +namespace ConsoleApplication22 +{ + class Program + { + static public int {|Definition:G$$oo|} + { + get + { + return 1; + } + set + { + } + } + static void Main(string[] args) + { + Console.WriteLine(Program.{|ValueUsageInfo.Read:[|Goo|]|}); + Program.{|ValueUsageInfo.Write:[|Goo|]|} = 0; + Program.{|ValueUsageInfo.ReadWrite:[|Goo|]|} += 1; + } + } +} + + + + Await TestAPIAndFeature(input, kind, host) + End Function End Class End Namespace diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb index d653e02af8182..2f3ba45357655 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb @@ -19,6 +19,8 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences <[UseExportProvider]> Partial Public Class FindReferencesTests Private Const DefinitionKey As String = "Definition" + Private Const ValueUsageInfoKey As String = "ValueUsageInfo." + Private Const TypeOrNamespaceUsageInfoKey As String = "TypeOrNamespaceUsageInfo." Private ReadOnly _outputHelper As ITestOutputHelper @@ -96,6 +98,37 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences context.References.Select(Function(r) r.SourceSpan)) Assert.Equal(expectedReferences, actualReferences) + + Dim valueUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(ValueUsageInfoKey))) + For Each key In valueUsageInfoKeys + Dim expected = + workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(key) AndAlso d.AnnotatedSpans(key).Any()). + OrderBy(Function(d) d.Name). + Select(Function(d) New FileNameAndSpans( + d.Name, d.AnnotatedSpans(key).ToList())).ToList() + Dim valueUsageInfoField = key.Substring(ValueUsageInfoKey.Length) + Dim actual = GetFileNamesAndSpans( + context.References.Where(Function(r) r.SymbolUsageInfo.ValueUsageInfoOpt?.ToString() = valueUsageInfoField).Select(Function(r) r.SourceSpan)) + + Assert.Equal(expected, actual) + Next + + Dim typeOrNamespaceUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(TypeOrNamespaceUsageInfoKey))) + For Each key In typeOrNamespaceUsageInfoKeys + Dim expected = + workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(key) AndAlso d.AnnotatedSpans(key).Any()). + OrderBy(Function(d) d.Name). + Select(Function(d) New FileNameAndSpans( + d.Name, d.AnnotatedSpans(key).ToList())).ToList() + Dim typeOrNamespaceUsageInfoFieldNames = key.Substring(TypeOrNamespaceUsageInfoKey.Length).Split(","c).Select(Function(s) s.Trim) + Dim actual = GetFileNamesAndSpans( + context.References.Where(Function(r) + Return r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt IsNot Nothing AndAlso + r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt.ToString().Split(","c).Select(Function(s) s.Trim).SetEquals(typeOrNamespaceUsageInfoFieldNames) + End Function).Select(Function(r) r.SourceSpan)) + + Assert.Equal(expected, actual) + Next Next End Using End Function @@ -226,7 +259,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences Assert.Equal(Of String)(documentsWithAnnotatedSpans.Select(Function(d) GetFilePathAndProjectLabel(workspace, d)).Order(), actualDefinitions.Keys.Order()) For Each doc In documentsWithAnnotatedSpans - Dim expected = doc.AnnotatedSpans(DefinitionKey).Order() + Dim expected = If(doc.AnnotatedSpans.ContainsKey(DefinitionKey), doc.AnnotatedSpans(DefinitionKey), ImmutableArray(Of TextSpan).Empty).Order() Dim actual = actualDefinitions(GetFilePathAndProjectLabel(workspace, doc)).Order() If Not TextSpansMatch(expected, actual) Then @@ -234,15 +267,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences End If Next - Dim actualReferences = - result.FilterToItemsToShow(options). - SelectMany(Function(r) r.Locations.Select(Function(loc) loc.Location)). - Where(Function(loc) IsInSource(workspace, loc, uiVisibleOnly)). - Distinct(). - GroupBy(Function(loc) loc.SourceTree). - ToDictionary( - Function(g) GetFilePathAndProjectLabel(document.Project.Solution, g.Key), - Function(g) g.Select(Function(loc) loc.SourceSpan).Distinct().ToList()) + Dim actualReferences = GetActualReferences(result, uiVisibleOnly, options, document, workspace) Dim expectedDocuments = workspace.Documents.Where(Function(d) d.SelectedSpans.Any()) Assert.Equal(expectedDocuments.Select(Function(d) GetFilePathAndProjectLabel(workspace, d)).Order(), actualReferences.Keys.Order()) @@ -254,10 +279,66 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences AssertEx.Equal(expectedSpans, actualSpans, message:=PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), "[|", "|]", messageOnly:=True)) Next + + Dim valueUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(ValueUsageInfoKey))) + For Each key In valueUsageInfoKeys + For Each doc In documentsWithAnnotatedSpans.Where(Function(d) d.AnnotatedSpans.ContainsKey(key)) + + Dim expectedSpans = doc.AnnotatedSpans(key).Order() + + Dim valueUsageInfoField = key.Substring(ValueUsageInfoKey.Length) + actualReferences = GetActualReferences(result, uiVisibleOnly, options, document, workspace, Function(r) r.SymbolUsageInfo.ValueUsageInfoOpt?.ToString() = valueUsageInfoField) + Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(workspace, doc)).Order() + + If Not TextSpansMatch(expectedSpans, actualSpans) Then + Assert.True(False, PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), $"{{|{key}:", "|}")) + End If + Next + Next + + Dim typeOrNamespaceUsageInfoKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(TypeOrNamespaceUsageInfoKey))) + For Each key In typeOrNamespaceUsageInfoKeys + For Each doc In documentsWithAnnotatedSpans.Where(Function(d) d.AnnotatedSpans.ContainsKey(key)) + + Dim expectedSpans = doc.AnnotatedSpans(key).Order() + + Dim typeOrNamespaceUsageInfoFieldNames = key.Substring(TypeOrNamespaceUsageInfoKey.Length).Split(","c).Select(Function(s) s.Trim) + actualReferences = GetActualReferences(result, uiVisibleOnly, options, document, workspace, Function(r) + Return r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt IsNot Nothing AndAlso + r.SymbolUsageInfo.TypeOrNamespaceUsageInfoOpt.ToString().Split(","c).Select(Function(s) s.Trim).SetEquals(typeOrNamespaceUsageInfoFieldNames) + End Function) + Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(workspace, doc)).Order() + + If Not TextSpansMatch(expectedSpans, actualSpans) Then + Assert.True(False, PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), $"{{|{key}:", "|}")) + End If + Next + Next Next End Using End Function + Private Shared Function GetActualReferences(result As IEnumerable(Of ReferencedSymbol), + uiVisibleOnly As Boolean, + options As FindReferencesSearchOptions, + document As Document, + workspace As TestWorkspace, + Optional locationFilterOpt As Func(Of ReferenceLocation, Boolean) = Nothing) As Dictionary(Of String, List(Of TextSpan)) + Dim referenceLocations = result.FilterToItemsToShow(options).SelectMany(Function(r) r.Locations) + If locationFilterOpt IsNot Nothing Then + referenceLocations = referenceLocations.Where(locationFilterOpt) + End If + + Return referenceLocations. + Select(Function(loc) loc.Location). + Where(Function(loc) IsInSource(workspace, loc, uiVisibleOnly)). + Distinct(). + GroupBy(Function(loc) loc.SourceTree). + ToDictionary( + Function(g) GetFilePathAndProjectLabel(document.Project.Solution, g.Key), + Function(g) g.Select(Function(loc) loc.SourceSpan).Distinct().ToList()) + End Function + Private Shared Function PrintSpans(expected As IOrderedEnumerable(Of TextSpan), actual As IOrderedEnumerable(Of TextSpan), doc As Document, prefix As String, suffix As String, Optional messageOnly As Boolean = False) As String Debug.Assert(expected IsNot Nothing) Debug.Assert(actual IsNot Nothing) From 5674b62ac84b9a15147a5e09731aed5a758f2b6b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Wed, 13 May 2020 21:08:21 -0700 Subject: [PATCH 175/222] remove using --- .../CSharp/Extensions/ITypeParameterSymbolExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs index 3194ba4c1296b..868abea333905 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeParameterSymbolExtensions.cs @@ -8,7 +8,6 @@ using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Microsoft.CodeAnalysis.CSharp.Extensions From 90d8756a35a5e650208daec74ee1a021e271081f Mon Sep 17 00:00:00 2001 From: Youssef Victor <31348972+Youssef1313@users.noreply.github.com> Date: Thu, 14 May 2020 09:17:52 +0200 Subject: [PATCH 176/222] Fix LowVMMoreInfoLink --- .../Def/Implementation/VirtualMemoryNotificationListener.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/Implementation/VirtualMemoryNotificationListener.cs b/src/VisualStudio/Core/Def/Implementation/VirtualMemoryNotificationListener.cs index 6bdd479d14e9d..5cbfc39acef96 100644 --- a/src/VisualStudio/Core/Def/Implementation/VirtualMemoryNotificationListener.cs +++ b/src/VisualStudio/Core/Def/Implementation/VirtualMemoryNotificationListener.cs @@ -35,7 +35,7 @@ internal sealed class VirtualMemoryNotificationListener : ForegroundThreadAffini private const long MemoryThreshold = 200 * 1024 * 1024; // low vm more info page link - private const string LowVMMoreInfoLink = "http://go.microsoft.com/fwlink/?LinkID=799402&clcid=0x409"; + private const string LowVMMoreInfoLink = "https://docs.microsoft.com/visualstudio/code-quality/automatic-feature-suspension"; private readonly VisualStudioWorkspace _workspace; private readonly WorkspaceCacheService _workspaceCacheService; From 6928f664e467e26e9b46e0670f64b727046e0ae1 Mon Sep 17 00:00:00 2001 From: Alexander Gayko Date: Thu, 14 May 2020 10:34:31 +0200 Subject: [PATCH 177/222] removed unneccessary using. --- .../AbstractDocumentationCommentFormattingService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs index cbe82c60881fe..0b2b4d3848c2e 100644 --- a/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs +++ b/src/Features/Core/Portable/DocumentationComments/AbstractDocumentationCommentFormattingService.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; -using System.Linq; using System.Text; using System.Threading; using System.Xml; From 3d14d95088989789a9d2aa3ee973bb1c81587256 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Thu, 14 May 2020 06:44:04 -0700 Subject: [PATCH 178/222] Add Find References unit tests for ContainingTypeInfo and ContainingMemberInfo custom columns Builds on #44240 to add FAR tests for more custom columns --- .../FindReferencesTests.FieldSymbols.vb | 62 +++++++++++++ .../FindReferencesTests.NamedTypeSymbols.vb | 88 ++++++++++++++++++- .../FindReferences/FindReferencesTests.vb | 70 +++++++++++++++ 3 files changed, 217 insertions(+), 3 deletions(-) diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb index bf782721c94e4..a6e1da712e2f8 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.FieldSymbols.vb @@ -446,6 +446,68 @@ class Definition:Program } + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestField_ContainingTypeInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class C + { + int {|Definition:$$i|}; + + int P + { + get + { + return {|AdditionalProperty.ContainingTypeInfo.C:[|i|]|} + } + } + + int P2 => {|AdditionalProperty.ContainingTypeInfo.C:[|i|]|} + + void Goo() + { + Console.WriteLine({|AdditionalProperty.ContainingTypeInfo.C:[|i|]|}); + } + } + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestField_ContainingMemberInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + + class C + { + int {|Definition:$$i|}; + + int P + { + get + { + return {|AdditionalProperty.ContainingMemberInfo.P:[|i|]|} + } + } + + int P2 => {|AdditionalProperty.ContainingMemberInfo.P2:[|i|]|} + + void Goo() + { + Console.WriteLine({|AdditionalProperty.ContainingMemberInfo.Goo:[|i|]|}); + } + } + + Await TestAPIAndFeature(input, kind, host) End Function diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb index 904212a4dcbd5..5ed88aeffb918 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.NamedTypeSymbols.vb @@ -2189,8 +2189,6 @@ public class D { } End Function - - Public Async Function TestNamedType_TypeOrNamespaceUsageInfo(kind As TestKind, host As TestHost) As Task Dim input = @@ -2224,7 +2222,91 @@ public class D { } public class Class3: {|TypeOrNamespaceUsageInfo.Qualified,Base:[|Class1|]|}.Nested, I<{|TypeOrNamespaceUsageInfo.Qualified,TypeArgument:[|Class1|]|}.Nested> { - public static [|Class1|] M2() => new {|TypeOrNamespaceUsageInfo.ObjectCreation:[|Class1|]|}(); + public static {|TypeOrNamespaceUsageInfo.None:[|Class1|]|} M2() => new {|TypeOrNamespaceUsageInfo.ObjectCreation:[|Class1|]|}(); + } + }]]> + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestNamedType_ContainingTypeInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + { } + + public class {|Definition:$$Class1|} + { + public static int Field; + public class Nested { } + } + + public class Class2 : {|AdditionalProperty.ContainingTypeInfo.Class2:[|Class1|]|}, I<{|AdditionalProperty.ContainingTypeInfo.Class2:[|Class1|]|}> + { + public static int M() => {|AdditionalProperty.ContainingTypeInfo.Class2:[|Class1|]|}.Field; + } + } + + namespace N2.N3 + { + using Alias2 = N2.{|AdditionalProperty.ContainingTypeInfo.:[|Class1|]|}.Nested; + + public class Class3: {|AdditionalProperty.ContainingTypeInfo.Class3:[|Class1|]|}.Nested, I<{|AdditionalProperty.ContainingTypeInfo.Class3:[|Class1|]|}.Nested> + { + public static {|AdditionalProperty.ContainingTypeInfo.Class3:[|Class1|]|} M2() => new {|AdditionalProperty.ContainingTypeInfo.Class3:[|Class1|]|}(); + } + }]]> + + + + Await TestAPIAndFeature(input, kind, host) + End Function + + + Public Async Function TestNamedType_ContainingMemberInfo(kind As TestKind, host As TestHost) As Task + Dim input = + + + { } + + public class {|Definition:$$Class1|} + { + public static int Field; + public class Nested { } + } + + public class Class2 : {|AdditionalProperty.ContainingMemberInfo.Class2:[|Class1|]|}, I<{|AdditionalProperty.ContainingMemberInfo.Class2:[|Class1|]|}> + { + public static int M() => {|AdditionalProperty.ContainingMemberInfo.M:[|Class1|]|}.Field; + } + } + + namespace N2.N3 + { + using Alias2 = N2.{|AdditionalProperty.ContainingMemberInfo.N3:[|Class1|]|}.Nested; + + public class Class3: {|AdditionalProperty.ContainingMemberInfo.Class3:[|Class1|]|}.Nested, I<{|AdditionalProperty.ContainingMemberInfo.Class3:[|Class1|]|}.Nested> + { + public static {|AdditionalProperty.ContainingMemberInfo.M2:[|Class1|]|} M2() => new {|AdditionalProperty.ContainingMemberInfo.M2:[|Class1|]|}(); } }]]> diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb index 2f3ba45357655..09617556e27e8 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.vb @@ -21,6 +21,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences Private Const DefinitionKey As String = "Definition" Private Const ValueUsageInfoKey As String = "ValueUsageInfo." Private Const TypeOrNamespaceUsageInfoKey As String = "TypeOrNamespaceUsageInfo." + Private Const AdditionalPropertyKey As String = "AdditionalProperty." Private ReadOnly _outputHelper As ITestOutputHelper @@ -129,10 +130,53 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences Assert.Equal(expected, actual) Next + + Dim additionalPropertiesMap = GetExpectedAdditionalPropertiesMap(workspace) + For Each kvp In additionalPropertiesMap + Dim propertyName = kvp.Key + For Each propertyValue In kvp.Value + Dim annotationKey = AdditionalPropertyKey + propertyName + "." + propertyValue + Dim expected = + workspace.Documents.Where(Function(d) d.AnnotatedSpans.ContainsKey(annotationKey) AndAlso d.AnnotatedSpans(annotationKey).Any()). + OrderBy(Function(d) d.Name). + Select(Function(d) New FileNameAndSpans( + d.Name, d.AnnotatedSpans(annotationKey).ToList())).ToList() + Dim actual = GetFileNamesAndSpans( + context.References.Where(Function(r) + Dim actualValue As String = Nothing + If r.AdditionalProperties.TryGetValue(propertyName, actualValue) Then + Return actualValue = propertyValue + End If + + Return propertyValue.Length = 0 + End Function).Select(Function(r) r.SourceSpan)) + + Assert.Equal(expected, actual) + Next + Next Next End Using End Function + Private Shared Function GetExpectedAdditionalPropertiesMap(workspace As TestWorkspace) As Dictionary(Of String, HashSet(Of String)) + Dim additionalPropertyKeys = workspace.Documents.SelectMany(Function(d) d.AnnotatedSpans.Keys.Where(Function(key) key.StartsWith(AdditionalPropertyKey)).Select(Function(key) key.Substring(AdditionalPropertyKey.Length))) + Dim additionalPropertiesMap As New Dictionary(Of String, HashSet(Of String)) + For Each key In additionalPropertyKeys + Dim index = key.IndexOf(".") + Assert.True(index > 0) + Dim propertyName = key.Substring(0, index) + Dim propertyValue = key.Substring(index + 1) + Dim propertyValues As HashSet(Of String) = Nothing + If Not additionalPropertiesMap.TryGetValue(propertyName, propertyValues) Then + propertyValues = New HashSet(Of String)() + additionalPropertiesMap.Add(propertyName, propertyValues) + End If + propertyValues.Add(propertyValue) + Next + + Return additionalPropertiesMap + End Function + Private Function GetFileNamesAndSpans(items As IEnumerable(Of DocumentSpan)) As List(Of FileNameAndSpans) Return items.Where(Function(i) i.Document IsNot Nothing). GroupBy(Function(i) i.Document). @@ -314,6 +358,32 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.FindReferences End If Next Next + + Dim additionalPropertiesMap = GetExpectedAdditionalPropertiesMap(workspace) + For Each kvp In additionalPropertiesMap + Dim propertyName = kvp.Key + For Each propertyValue In kvp.Value + Dim annotationKey = AdditionalPropertyKey + propertyName + "." + propertyValue + For Each doc In documentsWithAnnotatedSpans.Where(Function(d) d.AnnotatedSpans.ContainsKey(annotationKey)) + + Dim expectedSpans = doc.AnnotatedSpans(annotationKey).Order() + + actualReferences = GetActualReferences(result, uiVisibleOnly, options, document, workspace, Function(r) + Dim actualValue As String = Nothing + If r.AdditionalProperties.TryGetValue(propertyName, actualValue) Then + Return actualValue = propertyValue + End If + + Return propertyValue.Length = 0 + End Function) + Dim actualSpans = actualReferences(GetFilePathAndProjectLabel(workspace, doc)).Order() + + If Not TextSpansMatch(expectedSpans, actualSpans) Then + Assert.True(False, PrintSpans(expectedSpans, actualSpans, workspace.CurrentSolution.GetDocument(doc.Id), $"{{|{annotationKey}:", "|}")) + End If + Next + Next + Next Next End Using End Function From 064c0c842e2e5220394d6b461404f04d4ccacff7 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 14 May 2020 08:34:04 -0700 Subject: [PATCH 179/222] Only acquire IEditorOptionsFactoryService once for a contained document Closes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1124280 --- .../Core/Def/Implementation/Venus/ContainedDocument.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/Venus/ContainedDocument.cs b/src/VisualStudio/Core/Def/Implementation/Venus/ContainedDocument.cs index ac5999adac196..64f878e36cc0e 100644 --- a/src/VisualStudio/Core/Def/Implementation/Venus/ContainedDocument.cs +++ b/src/VisualStudio/Core/Def/Implementation/Venus/ContainedDocument.cs @@ -78,6 +78,7 @@ public static ContainedDocument TryGetContainedDocument(DocumentId id) private readonly IComponentModel _componentModel; private readonly Workspace _workspace; private readonly ITextDifferencingSelectorService _differenceSelectorService; + private readonly IEditorOptionsFactoryService _editorOptionsFactoryService; private readonly HostType _hostType; private readonly ReiteratedVersionSnapshotTracker _snapshotTracker; private readonly AbstractFormattingRule _vbHelperFormattingRule; @@ -113,6 +114,7 @@ public ContainedDocument( BufferCoordinator = bufferCoordinator; _differenceSelectorService = componentModel.GetService(); + _editorOptionsFactoryService = _componentModel.GetService(); _snapshotTracker = new ReiteratedVersionSnapshotTracker(SubjectBuffer); _vbHelperFormattingRule = vbHelperFormattingRule; @@ -870,8 +872,7 @@ private void GetVisibleAndTextSpan(SourceText text, List spans, int sp private int GetBaseIndentation(SyntaxNode root, SourceText text, TextSpan span) { // Is this right? We should probably get this from the IVsContainedLanguageHost instead. - var editorOptionsFactory = _componentModel.GetService(); - var editorOptions = editorOptionsFactory.GetOptions(DataBuffer); + var editorOptions = _editorOptionsFactoryService.GetOptions(DataBuffer); var additionalIndentation = GetAdditionalIndentation(root, text, span); From f7ca4ebf344c3fab714521d7465dc0562d96ccc1 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Thu, 14 May 2020 09:04:28 -0700 Subject: [PATCH 180/222] Diagnose bad 'ref' locals in switch sections (#44194) --- .../Portable/Binder/Binder_Statements.cs | 29 ++-- .../Portable/Binder/ForEachLoopBinder.cs | 10 +- .../Semantics/RefLocalsAndReturnsTests.cs | 144 +++++++++++++++++- 3 files changed, 159 insertions(+), 24 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs index fd1e468bdda11..6dd63e065e78e 100644 --- a/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs +++ b/src/Compilers/CSharp/Portable/Binder/Binder_Statements.cs @@ -969,10 +969,9 @@ protected BoundLocalDeclaration BindVariableDeclaration( bool nameConflict = localSymbol.ScopeBinder.ValidateDeclarationNameConflictsInScope(localSymbol, diagnostics); bool hasErrors = false; - var containingMethod = this.ContainingMemberOrLambda as MethodSymbol; - if (containingMethod != null && containingMethod.IsAsync && localSymbol.RefKind != RefKind.None) + if (localSymbol.RefKind != RefKind.None) { - Error(diagnostics, ErrorCode.ERR_BadAsyncLocalType, declarator); + CheckRefLocalInAsyncOrIteratorMethod(localSymbol.IdentifierToken, diagnostics); } EqualsValueClauseSyntax equalsClauseSyntax = declarator.Initializer; @@ -1150,6 +1149,22 @@ protected BoundLocalDeclaration BindVariableDeclaration( hasErrors: hasErrors | nameConflict); } + protected bool CheckRefLocalInAsyncOrIteratorMethod(SyntaxToken identifierToken, DiagnosticBag diagnostics) + { + if (IsInAsyncMethod()) + { + Error(diagnostics, ErrorCode.ERR_BadAsyncLocalType, identifierToken); + return true; + } + else if (IsDirectlyInIterator) + { + Error(diagnostics, ErrorCode.ERR_BadIteratorLocalType, identifierToken); + return true; + } + + return false; + } + internal ImmutableArray BindDeclaratorArguments(VariableDeclaratorSyntax declarator, DiagnosticBag diagnostics) { // It is possible that we have a bracketed argument list, like "int x[];" or "int x[123];" @@ -1732,14 +1747,6 @@ private BoundBlock BindBlockParts(BlockSyntax node, DiagnosticBag diagnostics) { Debug.Assert(!diagnostics.IsEmptyWithoutResolution); } - - foreach (var local in locals) - { - if (local.RefKind != RefKind.None) - { - diagnostics.Add(ErrorCode.ERR_BadIteratorLocalType, local.Locations[0]); - } - } } return new BoundBlock( diff --git a/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs b/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs index aa8558ba9b1bf..557abe675b2af 100644 --- a/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs +++ b/src/Compilers/CSharp/Portable/Binder/ForEachLoopBinder.cs @@ -269,18 +269,12 @@ private BoundForEachStatement BindForEachPartsWorker(DiagnosticBag diagnostics, if (local.RefKind != RefKind.None) { // The ref-escape of a ref-returning property is decided - // by the value escape of its receiverm, in this case the + // by the value escape of its receiver, in this case the // collection local.SetRefEscape(collectionEscape); - if (IsDirectlyInIterator) + if (CheckRefLocalInAsyncOrIteratorMethod(local.IdentifierToken, diagnostics)) { - diagnostics.Add(ErrorCode.ERR_BadIteratorLocalType, local.IdentifierToken.GetLocation()); - hasErrors = true; - } - else if (IsInAsyncMethod()) - { - diagnostics.Add(ErrorCode.ERR_BadAsyncLocalType, local.IdentifierToken.GetLocation()); hasErrors = true; } } diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs index 6afe8b1dc881b..b490c8e19f223 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/RefLocalsAndReturnsTests.cs @@ -1174,7 +1174,7 @@ async Task M() comp.VerifyDiagnostics( // (7,26): error CS8177: Async methods cannot have by-reference locals // ref readonly int x = ref (new int[1])[0]; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x = ref (new int[1])[0]").WithLocation(7, 26)); + Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x").WithLocation(7, 26)); } [Fact] @@ -1197,6 +1197,140 @@ IEnumerable M() Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(7, 26)); } + [Fact] + public void RefReadonlyInSwitchCaseInIterator_01() + { + var comp = CreateCompilation(@" +using System.Collections.Generic; +class C +{ + IEnumerable M() + { + switch (this) + { + default: + ref readonly int x = ref (new int[1])[0]; // 1 + yield return 1; + yield return x; + + local(); + void local() + { + ref readonly int z = ref (new int[1])[0]; + } + break; + } + } +}"); + comp.VerifyDiagnostics( + // (10,34): error CS8176: Iterators cannot have by-reference locals + // ref readonly int x = ref (new int[1])[0]; // 1 + Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(10, 34)); + } + + [Fact] + public void RefReadonlyInSwitchCaseInIterator_02() + { + var comp = CreateCompilation(@" +using System.Collections.Generic; +class C +{ + IEnumerable M() + { + switch (this) + { + default: + ref readonly int x; // 1, 2 + yield return 1; + yield return x; // 3 + break; + } + } +}"); + comp.VerifyDiagnostics( + // (10,34): error CS8176: Iterators cannot have by-reference locals + // ref readonly int x; // 1, 2 + Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(10, 34), + // (10,34): error CS8174: A declaration of a by-reference variable must have an initializer + // ref readonly int x; // 1, 2 + Diagnostic(ErrorCode.ERR_ByReferenceVariableMustBeInitialized, "x").WithLocation(10, 34), + // (12,30): error CS0165: Use of unassigned local variable 'x' + // yield return x; // 3 + Diagnostic(ErrorCode.ERR_UseDefViolation, "x").WithArguments("x").WithLocation(12, 30)); + } + + [Fact] + public void RefReadonlyInSwitchCaseInIterator_03() + { + var comp = CreateCompilation(@" +using System.Collections.Generic; +class C +{ + IEnumerable M() + { + switch (this) + { + default: + foreach (ref readonly int x in (new int[1])) + yield return 1; + break; + } + } +}"); + comp.VerifyDiagnostics( + // (10,43): error CS8176: Iterators cannot have by-reference locals + // foreach (ref readonly int x in (new int[1])) + Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(10, 43)); + } + + [Fact] + public void RefReadonlyInEmbeddedStatementInIterator() + { + var comp = CreateCompilation(@" +using System.Collections.Generic; +class C +{ + IEnumerable M() + { + if (true) + ref int x = ref (new int[1])[0]; // 1, 2 + + yield return 1; + } +}"); + comp.VerifyDiagnostics( + // (8,13): error CS1023: Embedded statement cannot be a declaration or labeled statement + // ref int x = ref (new int[1])[0]; // 1, 2 + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "ref int x = ref (new int[1])[0];").WithLocation(8, 13), + // (8,21): error CS8176: Iterators cannot have by-reference locals + // ref int x = ref (new int[1])[0]; // 1, 2 + Diagnostic(ErrorCode.ERR_BadIteratorLocalType, "x").WithLocation(8, 21)); + } + + [Fact] + public void RefReadonlyInEmbeddedStatementInAsync() + { + var comp = CreateCompilation(@" +using System.Threading.Tasks; +class C +{ + async Task M() + { + if (true) + ref int x = ref (new int[1])[0]; // 1, 2 + + await Task.Yield(); + } +}"); + comp.VerifyDiagnostics( + // (8,13): error CS1023: Embedded statement cannot be a declaration or labeled statement + // ref int x = ref (new int[1])[0]; // 1, 2 + Diagnostic(ErrorCode.ERR_BadEmbeddedStmt, "ref int x = ref (new int[1])[0];").WithLocation(8, 13), + // (8,21): error CS8177: Async methods cannot have by-reference locals + // ref int x = ref (new int[1])[0]; // 1, 2 + Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "x").WithLocation(8, 21)); + } + [Fact] public void RefReadonlyLocalNotWritable() { @@ -2711,10 +2845,10 @@ await Task.Run(async () => CreateCompilationWithMscorlib45(code).VerifyDiagnostics( // (8,17): error CS8177: Async methods cannot have by-reference locals // ref int y = ref x; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y = ref x").WithLocation(8, 17), + Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "y").WithLocation(8, 17), // (11,21): error CS8177: Async methods cannot have by-reference locals // ref int z = ref x; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "z = ref x").WithLocation(11, 21)); + Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "z").WithLocation(11, 21)); } [Fact, WorkItem(13073, "https://github.com/dotnet/roslyn/issues/13073")] @@ -3029,9 +3163,9 @@ static async void Goo() "; CreateCompilationWithMscorlib46(text).VerifyDiagnostics( - // (8,17): error CS8932: Async methods cannot have by-reference locals + // (8,17): error CS8177: Async methods cannot have by-reference locals // ref int i = ref field; - Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "i = ref field").WithLocation(8, 17), + Diagnostic(ErrorCode.ERR_BadAsyncLocalType, "i").WithLocation(8, 17), // (6,23): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. // static async void Goo() Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "Goo").WithLocation(6, 23)); From f1bd19828d492d3720f0b2b3aca9bf900a0a2e0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Thu, 14 May 2020 10:10:58 -0700 Subject: [PATCH 181/222] Add option page registration attributes back (#44101) * Add option page registration attributes back * DiagnosticWindowPackage --- src/VisualStudio/CSharp/Impl/CSharpPackage.cs | 30 +++++++++++++++++++ .../CSharp/Impl/PackageRegistration.pkgdef | 2 ++ .../LanguageService/VisualBasicPackage.vb | 16 ++++++++++ .../Impl/PackageRegistration.pkgdef | 2 ++ .../PackageRegistration.pkgdef | 2 ++ .../VisualStudioDiagnosticsWindowPackage.cs | 11 +++++++ 6 files changed, 63 insertions(+) diff --git a/src/VisualStudio/CSharp/Impl/CSharpPackage.cs b/src/VisualStudio/CSharp/Impl/CSharpPackage.cs index 849eb9c31f9f7..852dbdda5e43a 100644 --- a/src/VisualStudio/CSharp/Impl/CSharpPackage.cs +++ b/src/VisualStudio/CSharp/Impl/CSharpPackage.cs @@ -22,6 +22,36 @@ namespace Microsoft.VisualStudio.LanguageServices.CSharp.LanguageService { + // The option page configuration is duplicated in PackageRegistration.pkgdef. + // + // C# option pages tree: + // CSharp + // General (from editor) + // Scroll Bars (from editor) + // Tabs (from editor) + // Advanced + // Code Style (category) + // General + // Formatting (category) + // General + // Indentation + // New Lines + // Spacing + // Wrapping + // Naming + // IntelliSense + + [ProvideLanguageEditorOptionPage(typeof(Options.AdvancedOptionPage), "CSharp", null, "Advanced", pageNameResourceId: "#102", keywordListResourceId: 306)] + [ProvideLanguageEditorToolsOptionCategory("CSharp", "Code Style", "#114")] + [ProvideLanguageEditorOptionPage(typeof(Options.Formatting.CodeStylePage), "CSharp", @"Code Style", "General", pageNameResourceId: "#108", keywordListResourceId: 313)] + [ProvideLanguageEditorToolsOptionCategory("CSharp", @"Code Style\Formatting", "#107")] + [ProvideLanguageEditorOptionPage(typeof(Options.Formatting.FormattingOptionPage), "CSharp", @"Code Style\Formatting", "General", pageNameResourceId: "#108", keywordListResourceId: 307)] + [ProvideLanguageEditorOptionPage(typeof(Options.Formatting.FormattingIndentationOptionPage), "CSharp", @"Code Style\Formatting", "Indentation", pageNameResourceId: "#109", keywordListResourceId: 308)] + [ProvideLanguageEditorOptionPage(typeof(Options.Formatting.FormattingWrappingPage), "CSharp", @"Code Style\Formatting", "Wrapping", pageNameResourceId: "#110", keywordListResourceId: 311)] + [ProvideLanguageEditorOptionPage(typeof(Options.Formatting.FormattingNewLinesPage), "CSharp", @"Code Style\Formatting", "NewLines", pageNameResourceId: "#111", keywordListResourceId: 309)] + [ProvideLanguageEditorOptionPage(typeof(Options.Formatting.FormattingSpacingPage), "CSharp", @"Code Style\Formatting", "Spacing", pageNameResourceId: "#112", keywordListResourceId: 310)] + [ProvideLanguageEditorOptionPage(typeof(Options.NamingStylesOptionPage), "CSharp", @"Code Style", "Naming", pageNameResourceId: "#115", keywordListResourceId: 314)] + [ProvideLanguageEditorOptionPage(typeof(Options.IntelliSenseOptionPage), "CSharp", null, "IntelliSense", pageNameResourceId: "#103", keywordListResourceId: 312)] [Guid(Guids.CSharpPackageIdString)] internal sealed class CSharpPackage : AbstractPackage, IVsUserSettingsQuery { diff --git a/src/VisualStudio/CSharp/Impl/PackageRegistration.pkgdef b/src/VisualStudio/CSharp/Impl/PackageRegistration.pkgdef index 599a5c8ac9753..0222ffa3411fd 100644 --- a/src/VisualStudio/CSharp/Impl/PackageRegistration.pkgdef +++ b/src/VisualStudio/CSharp/Impl/PackageRegistration.pkgdef @@ -48,6 +48,8 @@ "ProfileSave"=dword:00000001 "VSSettingsMigration"=dword:00000001 +// The option page configuration is duplicated on CSharpPackage type definition. +// // C# option pages tree: // CSharp // General (from editor) diff --git a/src/VisualStudio/VisualBasic/Impl/LanguageService/VisualBasicPackage.vb b/src/VisualStudio/VisualBasic/Impl/LanguageService/VisualBasicPackage.vb index fb5732b95fe23..e402c067346fa 100644 --- a/src/VisualStudio/VisualBasic/Impl/LanguageService/VisualBasicPackage.vb +++ b/src/VisualStudio/VisualBasic/Impl/LanguageService/VisualBasicPackage.vb @@ -11,6 +11,7 @@ Imports Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService Imports Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.ObjectBrowser Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Options +Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.Options.Formatting Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.ProjectSystemShim Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.ProjectSystemShim.Interop Imports Microsoft.VisualStudio.Shell @@ -19,6 +20,21 @@ Imports Task = System.Threading.Tasks.Task Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic + ' The option page configuration is duplicated in PackageRegistration.pkgdef. + ' + ' VB option pages tree + ' Basic + ' General (from editor) + ' Scroll Bars (from editor) + ' Tabs (from editor) + ' Advanced + ' Code Style (category) + ' General + + + + + Friend NotInheritable Class VisualBasicPackage Inherits AbstractPackage(Of VisualBasicPackage, VisualBasicLanguageService) diff --git a/src/VisualStudio/VisualBasic/Impl/PackageRegistration.pkgdef b/src/VisualStudio/VisualBasic/Impl/PackageRegistration.pkgdef index 4996b9098875a..dbe659ca5c657 100644 --- a/src/VisualStudio/VisualBasic/Impl/PackageRegistration.pkgdef +++ b/src/VisualStudio/VisualBasic/Impl/PackageRegistration.pkgdef @@ -54,6 +54,8 @@ "ProfileSave"=dword:00000001 "VSSettingsMigration"=dword:00000001 +// The option page configuration is duplicated on VisualBasicPackage type definition. +// // VB option pages tree // Basic // General (from editor) diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef index f9023150c5f31..7cc97da92b57f 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef @@ -5,6 +5,8 @@ [$RootKey$\Menus] "{49e24138-9ee3-49e0-8ede-6b39f49303bf}"=", Menus.ctmenu, 1" +// The option page configuration is duplicated on VisualStudioDiagnosticsWindowPackage type definition. + [$RootKey$\ToolsOptionsPages\Roslyn\Diagnostics] @="#0" "Package"="{49e24138-9ee3-49e0-8ede-6b39f49303bf}" diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs index 1dd2e02d3a4eb..53589752b7004 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs @@ -15,6 +15,7 @@ using Microsoft.CodeAnalysis.Remote; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.LanguageServices; +using Microsoft.VisualStudio.LanguageServices.Implementation.Options; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages; @@ -22,6 +23,16 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow { + // The option page configuration is duplicated in PackageRegistration.pkgdef. + // These attributes specify the menu structure to be used in Tools | Options. These are not + // localized because they are for internal use only. + [ProvideOptionPage(typeof(InternalFeaturesOnOffPage), @"Roslyn\FeatureManager", @"Features", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(InternalComponentsOnOffPage), @"Roslyn\FeatureManager", @"Components", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(PerformanceFunctionIdPage), @"Roslyn\Performance", @"FunctionId", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(PerformanceLoggersPage), @"Roslyn\Performance", @"Loggers", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(InternalDiagnosticsPage), @"Roslyn\Diagnostics", @"Internal", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(InternalSolutionCrawlerPage), @"Roslyn\SolutionCrawler", @"Internal", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(ExperimentationPage), @"Roslyn\Experimentation", @"Internal", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] [Guid(GuidList.guidVisualStudioDiagnosticsWindowPkgString)] [Description("Roslyn Diagnostics Window")] public sealed class VisualStudioDiagnosticsWindowPackage : AsyncPackage From f9525105d23161e688c65f1d9b539f30f8a47930 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 14 May 2020 11:08:17 -0700 Subject: [PATCH 182/222] Remove automatic retry in GetPackageSourcesImplAsync --- .../PackageInstallerServiceFactory.cs | 27 +++++++++---------- .../Packaging/IPackageInstallerService.cs | 9 +++++-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 6cf902ecb9356..5322d4172787e 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -55,7 +55,7 @@ internal partial class PackageInstallerService : AbstractDelayStartedService, IP private readonly Lazy _packageUninstaller; private readonly Lazy _packageSourceProvider; - private JoinableTask> _packageSourcesAsync; + private JoinableTask?> _packageSourcesAsync; private IVsPackage _nugetPackageManager; private CancellationTokenSource _tokenSource = new CancellationTokenSource(); @@ -97,7 +97,7 @@ public PackageInstallerService( { // Only read from _packageSourcesAsync once, since OnSourceProviderSourcesChanged could reset it to default // at any time while this method is running. - JoinableTask> packageSourcesAsync; + JoinableTask?> packageSourcesAsync; lock (_gate) { if (_packageSourcesAsync is null) @@ -125,21 +125,18 @@ public PackageInstallerService( } } - private async Task> GetPackageSourcesImplAsync() + private async Task?> GetPackageSourcesImplAsync() { - // Automatically retry the operation if it gets cancelled due to a change in the workspace. - while (true) + var cancellationToken = _tokenSource.Token; + try { - var cancellationToken = _tokenSource.Token; - try - { - return await GetPackageSourcesImplAsync(cancellationToken).ConfigureAwait(false); - } - catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) - { - // The failure may have been caused by a workspace change; try again after a short delay - await Task.Delay(TimeSpan.FromMilliseconds(250)).ConfigureAwait(false); - } + return await GetPackageSourcesImplAsync(cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + // The failure may have been caused by a workspace change. The task has already been invalidated at + // a higher level, so just return indicating the data is not complete. + return null; } // Local function diff --git a/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs b/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs index c81314cf1aca7..b9c25df6a8b1d 100644 --- a/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs +++ b/src/Workspaces/Core/Portable/Packaging/IPackageInstallerService.cs @@ -37,8 +37,13 @@ bool TryInstallPackage(Workspace workspace, DocumentId documentId, /// answer if such a switch would be required. /// The cancellation token that the asynchronous operation will observe. /// - /// A collection of package sources, or if is - /// and the package sources could not be computed without switching to the main thread. + /// A collection of package sources. + /// -or- + /// if is and + /// the package sources could not be computed without switching to the main thread. + /// -or- + /// if the package sources were invalidated by the project system before the + /// computation completed. /// ValueTask?> TryGetPackageSourcesAsync(bool allowSwitchToMainThread, CancellationToken cancellationToken); From bbb96d003d53a25271c99a7f0f643e7c59b1df28 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 14 May 2020 11:09:51 -0700 Subject: [PATCH 183/222] Inline local function --- .../PackageInstallerServiceFactory.cs | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 5322d4172787e..0950b40df54bc 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -130,7 +130,7 @@ public PackageInstallerService( var cancellationToken = _tokenSource.Token; try { - return await GetPackageSourcesImplAsync(cancellationToken).ConfigureAwait(false); + await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); } catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { @@ -139,27 +139,21 @@ public PackageInstallerService( return null; } - // Local function - async Task> GetPackageSourcesImplAsync(CancellationToken cancellationToken) + try { - await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); - - try - { - return _packageSourceProvider.Value.GetSources(includeUnOfficial: true, includeDisabled: false) - .SelectAsArray(r => new PackageSource(r.Key, r.Value)); - } - catch (Exception ex) when (ex is InvalidDataException || ex is InvalidOperationException) - { - // These exceptions can happen when the nuget.config file is broken. - return ImmutableArray.Empty; - } - catch (ArgumentException ae) when (FatalError.ReportWithoutCrash(ae)) - { - // This exception can happen when the nuget.config file is broken, e.g. invalid credentials. - // https://github.com/dotnet/roslyn/issues/40857 - return ImmutableArray.Empty; - } + return _packageSourceProvider.Value.GetSources(includeUnOfficial: true, includeDisabled: false) + .SelectAsArray(r => new PackageSource(r.Key, r.Value)); + } + catch (Exception ex) when (ex is InvalidDataException || ex is InvalidOperationException) + { + // These exceptions can happen when the nuget.config file is broken. + return ImmutableArray.Empty; + } + catch (ArgumentException ae) when (FatalError.ReportWithoutCrash(ae)) + { + // This exception can happen when the nuget.config file is broken, e.g. invalid credentials. + // https://github.com/dotnet/roslyn/issues/40857 + return ImmutableArray.Empty; } } From de1e0adecd1f3b8ff55c6e256c2577d94e33115d Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 14 May 2020 11:28:46 -0700 Subject: [PATCH 184/222] Gate the access to _tokenSource --- .../Core/Def/Packaging/PackageInstallerServiceFactory.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs index 0950b40df54bc..1d910fa591bc2 100644 --- a/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs +++ b/src/VisualStudio/Core/Def/Packaging/PackageInstallerServiceFactory.cs @@ -127,7 +127,14 @@ public PackageInstallerService( private async Task?> GetPackageSourcesImplAsync() { - var cancellationToken = _tokenSource.Token; + CancellationToken cancellationToken; + lock (_gate) + { + // Read the current cancellation token within the gate to ensure the token source is not disposed at the + // time of the read. + cancellationToken = _tokenSource.Token; + } + try { await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); From a75722301f94bdbc29d2a0025c95d1db4f04c4a4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 11:46:40 -0700 Subject: [PATCH 185/222] Simplify and make our code for resolving body-level symbols more resilient. --- .../SymbolKey/SymbolKey.BodyLevelSymbolKey.cs | 133 +++++++----------- 1 file changed, 54 insertions(+), 79 deletions(-) diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs index a788fafe4467b..0c5ec43d09b62 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs @@ -4,6 +4,8 @@ using System.Collections.Generic; using System.Threading; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis { @@ -13,41 +15,50 @@ private static class BodyLevelSymbolKey { public static void Create(ISymbol symbol, SymbolKeyWriter visitor) { - var containingSymbol = symbol.ContainingSymbol; - - while (containingSymbol.DeclaringSyntaxReferences.IsDefaultOrEmpty) - { - containingSymbol = containingSymbol.ContainingSymbol; - } + // Store the body level symbol in two forms. The first, a highly precise form that should find explicit + // symbols for the case of resolving a symbol key back in the *same* solution snapshot it was created + // from. The second, in a more query-oriented form that can allow the symbol to be found in some cases + // even if the solution changed (which is a supported use case for SymbolKey). + // + // The first way just stores the location of the symbol, which we can then validate during resolution + // maps back to the same symbol kind/name. + // + // The second determines the sequence of symbols of the same kind and same name in the file and keeps + // track of our index in that sequence. That way, if trivial edits happen, or symbols with different + // names/types are added/removed, we can still find what is likely to be this symbol after the edit. - var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; var kind = symbol.Kind; var localName = symbol.Name; - // Use two mechanisms to try to find the symbol across compilations. First, we use a whitespace - // insensitive system where we keep track of the list of all locals in the container and we just store - // our index in it. - // - // The above works for cases where the symbol has a real declaration and can be found by walking the - // declarations of the container. However, not all symbols can be found that way. For example, error - // locals in VB can't be found using GetDeclaredSymbol. For those, we store the actual local span and - // use GetSymbolInfo to find it. - var ordinal = GetOrdinal(); + Contract.ThrowIfTrue(symbol.DeclaringSyntaxReferences.IsEmpty); + var syntaxRef = symbol.DeclaringSyntaxReferences[0].GetSyntax(visitor.CancellationToken); visitor.WriteString(localName); - visitor.WriteSymbolKey(containingSymbol); - visitor.WriteInteger(ordinal); - visitor.WriteLocation(symbol.Locations[0]); visitor.WriteInteger((int)kind); + // write out the location for precision + visitor.WriteLocation(syntaxRef.GetLocation()); + + // and the ordinal for resilience + visitor.WriteInteger(GetOrdinal()); + return; int GetOrdinal() { - foreach (var possibleSymbol in EnumerateSymbols(compilation, containingSymbol, kind, localName, visitor.CancellationToken)) + var syntaxTree = syntaxRef.SyntaxTree; + var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; + + // Ensure that the tree we're looking at is actually in this compilation. It may not be in the + // compilation in the case of work done with a speculative model. + if (Contains(compilation.SyntaxTrees, syntaxTree)) { - if (possibleSymbol.symbol.Equals(symbol)) - return possibleSymbol.ordinal; + var semanticModel = compilation.GetSemanticModel(syntaxTree); + foreach (var possibleSymbol in EnumerateSymbols(semanticModel, kind, localName, visitor.CancellationToken)) + { + if (possibleSymbol.symbol.Equals(symbol)) + return possibleSymbol.ordinal; + } } return int.MaxValue; @@ -59,27 +70,24 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader) var cancellationToken = reader.CancellationToken; var localName = reader.ReadString(); - var containingSymbolResolution = reader.ReadSymbolKey(); - var ordinal = reader.ReadInteger(); - var location = reader.ReadLocation(); var kind = (SymbolKind)reader.ReadInteger(); + var location = reader.ReadLocation(); + var ordinal = reader.ReadInteger(); - var containingSymbol = containingSymbolResolution.Symbol; - if (containingSymbol != null) + // First check if we can recover the symbol just through the original location. + var semanticModel = reader.Compilation.GetSemanticModel(location.SourceTree); + var declaredSymbol = semanticModel.GetDeclaredSymbol(location.FindNode(reader.CancellationToken)); + + if (declaredSymbol?.Name == localName && declaredSymbol?.Kind == kind) + return new SymbolKeyResolution(declaredSymbol); + + // Couldn't recover. See if we can still find a match across the textual drift. + if (ordinal != int.MaxValue) { - if (ordinal != int.MaxValue) - { - foreach (var symbol in EnumerateSymbols(reader.Compilation, containingSymbol, kind, localName, cancellationToken)) - { - if (symbol.ordinal == ordinal) - return new SymbolKeyResolution(symbol.symbol); - } - } - else + foreach (var symbol in EnumerateSymbols(semanticModel, kind, localName, cancellationToken)) { - var resolution = reader.ResolveLocation(location); - if (resolution != null) - return resolution.Value; + if (symbol.ordinal == ordinal) + return new SymbolKeyResolution(symbol.symbol); } } @@ -87,52 +95,19 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader) } private static IEnumerable<(ISymbol symbol, int ordinal)> EnumerateSymbols( - Compilation compilation, ISymbol containingSymbol, - SymbolKind kind, string localName, - CancellationToken cancellationToken) + SemanticModel semanticModel, SymbolKind kind, string localName, CancellationToken cancellationToken) { var ordinal = 0; + var root = semanticModel.SyntaxTree.GetRoot(cancellationToken); - foreach (var declaringLocation in containingSymbol.DeclaringSyntaxReferences) + foreach (var node in root.DescendantNodes()) { - // This operation can potentially fail. If containingSymbol came from - // a SpeculativeSemanticModel, containingSymbol.ContainingAssembly.Compilation - // may not have been rebuilt to reflect the trees used by the - // SpeculativeSemanticModel to produce containingSymbol. In that case, - // asking the ContainingAssembly's compilation for a SemanticModel based - // on trees for containingSymbol with throw an ArgumentException. - // Unfortunately, the best way to avoid this (currently) is to see if - // we're asking for a model for a tree that's part of the compilation. - // (There's no way to get back to a SemanticModel from a symbol). - - // TODO (rchande): It might be better to call compilation.GetSemanticModel - // and catch the ArgumentException. The compilation internally has a - // Dictionary that it uses to check if the SyntaxTree - // is applicable wheras the public interface requires us to enumerate - // the entire IEnumerable of trees in the Compilation. - if (!Contains(compilation.SyntaxTrees, declaringLocation.SyntaxTree)) - { - continue; - } + var symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken); - var node = declaringLocation.GetSyntax(cancellationToken); - if (node.Language == LanguageNames.VisualBasic) + if (symbol?.Kind == kind && + SymbolKey.Equals(semanticModel.Compilation, symbol.Name, localName)) { - node = node.Parent; - } - - var semanticModel = compilation.GetSemanticModel(node.SyntaxTree); - - foreach (var token in node.DescendantNodes()) - { - var symbol = semanticModel.GetDeclaredSymbol(token, cancellationToken); - - if (symbol != null && - symbol.Kind == kind && - SymbolKey.Equals(compilation, symbol.Name, localName)) - { - yield return (symbol, ordinal++); - } + yield return (symbol, ordinal++); } } } From 57d89528a6a1fab47bdb7c10b93cf97569f67eb8 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 14 May 2020 13:16:31 -0700 Subject: [PATCH 186/222] Add formatting tests for comments after line continuation --- .../Formatting/FormattingTests.vb | 177 +++++++++++------- 1 file changed, 110 insertions(+), 67 deletions(-) diff --git a/src/Workspaces/VisualBasicTest/Formatting/FormattingTests.vb b/src/Workspaces/VisualBasicTest/Formatting/FormattingTests.vb index 12699b5d9286e..6160378410beb 100644 --- a/src/Workspaces/VisualBasicTest/Formatting/FormattingTests.vb +++ b/src/Workspaces/VisualBasicTest/Formatting/FormattingTests.vb @@ -780,98 +780,139 @@ End Class Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) End Function - - Public Async Function LineContinuation1() As Task - Dim code = Class C + + + + Public Async Function LineContinuation1(continuation As String) As Task + Dim code = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim a = 1 + _ - 2 + _ + Dim a = 1 + {continuation} + 2 + {continuation} 3 End Sub -End Class +End Class" - Dim expected = Class C + Dim expected = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim a = 1 + _ - 2 + _ + Dim a = 1 + {continuation} + 2 + {continuation} 3 End Sub -End Class +End Class" - Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) + Await AssertFormatAsync(code, expected) End Function - - Public Async Function LineContinuation2() As Task - Dim code = Class C + + + + Public Async Function LineContinuation2(continuation As String) As Task + Dim code = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim aa = 1 + _ - 2 + _ + Dim aa = 1 + {continuation} + 2 + {continuation} 3 End Sub -End Class +End Class" - Dim expected = Class C + Dim expected = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim aa = 1 + _ - 2 + _ + Dim aa = 1 + {continuation} + 2 + {continuation} 3 End Sub -End Class +End Class" - Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) + Await AssertFormatAsync(code, expected) End Function - - Public Async Function LineContinuation3() As Task - Dim code = Class C + + + + Public Async Function LineContinuation3(continuation As String) As Task + Dim code = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim aa = 1 + _ - 2 + _ + Dim aa = 1 + {continuation} + 2 + {continuation} 3 End Sub -End Class +End Class" - Dim expected = Class C + Dim expected = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim aa = 1 + _ -2 + _ + Dim aa = 1 + {continuation} +2 + {continuation} 3 End Sub -End Class +End Class" - Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) + Await AssertFormatAsync(code, expected) End Function - - Public Async Function LineContinuation4() As Task - Dim code = Class C + + + + Public Async Function LineContinuation4(continuation As String) As Task + Dim code = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim aa = 1 + _ - _ - _ - _ - _ - _ - 2 + _ + Dim aa = 1 + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + 2 + {continuation} 3 End Sub -End Class +End Class" - Dim expected = Class C + Dim expected = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim aa = 1 + _ - _ - _ - _ - _ - _ -2 + _ + Dim aa = 1 + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} +2 + {continuation} 3 End Sub -End Class +End Class" - Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) + Await AssertFormatAsync(code, expected) + End Function + + + + + Public Async Function LineContinuation5(continuation As String) As Task + Dim code = $"Class C + Sub Method(Optional ByVal i As Integer = 1) + Dim aa = 1 + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + 2 + {continuation} + 3 + End Sub +End Class" + + Dim expected = $"Class C + Sub Method(Optional ByVal i As Integer = 1) + Dim aa = 1 + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + {continuation} + 2 + {continuation} + 3 + End Sub +End Class" + + Await AssertFormatAsync(code, expected) End Function @@ -1029,27 +1070,29 @@ End Class Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) End Function - - Public Async Function Trivia3() As Task - Dim code = Class C + + + + Public Async Function Trivia3(continuation As String) As Task + Dim code = $"Class C Sub Method(Optional ByVal i As Integer = 1) -Dim a = _ - _ - _ +Dim a = {continuation} + {continuation} + {continuation} 1 End Sub -End Class +End Class" - Dim expected = Class C + Dim expected = $"Class C Sub Method(Optional ByVal i As Integer = 1) - Dim a = _ - _ - _ + Dim a = {continuation} + {continuation} + {continuation} 1 End Sub -End Class +End Class" - Await AssertFormatLf2CrLfAsync(code.Value, expected.Value) + Await AssertFormatAsync(code, expected) End Function From d7d64d39b6d8e66fb779b9cb135fac928778fcee Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 14:13:45 -0700 Subject: [PATCH 187/222] Only report designer attributes for the primary project of a multi-project config. --- .../VisualStudioDesignerAttributeService.cs | 9 +- .../CPS/IWorkspaceProjectContext.cs | 8 + .../ProjectSystem/VisualStudioProject.cs | 14 ++ .../VisualStudioWorkspaceImpl.cs | 17 ++ .../CPSProject_IWorkspaceProjectContext.cs | 6 + .../SymbolKey/SymbolKey.BodyLevelSymbolKey.cs | 154 ------------------ 6 files changed, 53 insertions(+), 155 deletions(-) delete mode 100644 src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs diff --git a/src/VisualStudio/Core/Def/Implementation/DesignerAttribute/VisualStudioDesignerAttributeService.cs b/src/VisualStudio/Core/Def/Implementation/DesignerAttribute/VisualStudioDesignerAttributeService.cs index 6a4e736834072..7853750f73f0f 100644 --- a/src/VisualStudio/Core/Def/Implementation/DesignerAttribute/VisualStudioDesignerAttributeService.cs +++ b/src/VisualStudio/Core/Def/Implementation/DesignerAttribute/VisualStudioDesignerAttributeService.cs @@ -176,7 +176,7 @@ private async Task NotifyProjectSystemAsync( var cpsUpdateService = await GetUpdateServiceIfCpsProjectAsync(projectId, cancellationToken).ConfigureAwait(false); var task = cpsUpdateService == null ? NotifyLegacyProjectSystemAsync(projectId, data, cancellationToken) - : NotifyCpsProjectSystemAsync(cpsUpdateService, data, cancellationToken); + : NotifyCpsProjectSystemAsync(projectId, cpsUpdateService, data, cancellationToken); await task.ConfigureAwait(false); } @@ -242,12 +242,19 @@ private void NotifyLegacyProjectSystemOnUIThread( } private async Task NotifyCpsProjectSystemAsync( + ProjectId projectId, IProjectItemDesignerTypeUpdateService updateService, IEnumerable data, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); + // We may have updates for many different configurations of the same logical project system project. + // However, the project system only associates designer attributes with one of those projects. So just drop + // the notifications for any sibling configurations. + if (!_workspace.IsPrimaryProject(projectId)) + return; + // Broadcast all the information about all the documents in parallel to CPS. using var _ = ArrayBuilder.GetInstance(out var tasks); diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs index d61a8ae818d85..a7ebc8ea13c4a 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/CPS/IWorkspaceProjectContext.cs @@ -20,6 +20,14 @@ internal interface IWorkspaceProjectContext : IDisposable bool LastDesignTimeBuildSucceeded { get; set; } string BinOutputPath { get; set; } + /// + /// When this project is one of a multi-targeting group of projects, this value indicates whether or not this + /// particular project is the primary one. The primary project is responsible for certain things when reporting + /// data from Roslyn's individual projects back to the project system itself. For example, designer attributes + /// are only associated with the primary project, and should be skipped for other projects. + /// + bool IsPrimary { get; set; } + ProjectId Id { get; } // Options. diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs index 21ab4b5ec8a48..1da972a03a058 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.Debugger.Interop; using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList; using Microsoft.VisualStudio.PlatformUI; using Roslyn.Utilities; @@ -68,6 +69,13 @@ internal sealed class VisualStudioProject private string? _outputRefFilePath; private string? _defaultNamespace; + /// + /// We store if this is a primary project or not as a tri-state. Only means that it's + /// not a primary project. This way, if the value hasn't been set, or is never set, we still consider the + /// project to be a primary one. + /// + private bool? _isPrimary; + // Actual property values for 'RunAnalyzers' and 'RunAnalyzersDuringLiveAnalysis' properties from the project file. // Both these properties can be used to configure running analyzers, with RunAnalyzers overriding RunAnalyzersDuringLiveAnalysis. private bool? _runAnalyzersPropertyValue; @@ -289,6 +297,12 @@ internal bool HasAllInformation set => ChangeProjectProperty(ref _hasAllInformation, value, s => s.WithHasAllInformation(Id, value)); } + internal bool IsPrimary + { + get => _isPrimary != false; + set => _isPrimary = value; + } + internal bool? RunAnalyzers { get => _runAnalyzersPropertyValue; diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs index 1f566b0d7defc..4310006974770 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs @@ -406,6 +406,23 @@ internal bool IsCPSProject(ProjectId projectId) return false; } + internal bool IsPrimaryProject(ProjectId projectId) + { + lock (_gate) + { + foreach (var (_, projects) in this._projectSystemNameToProjectsMap) + { + foreach (var project in projects) + { + if (project.Id == projectId) + return project.IsPrimary; + } + } + } + + return true; + } + protected override bool CanApplyCompilationOptionChange(CompilationOptions oldOptions, CompilationOptions newOptions, CodeAnalysis.Project project) => project.LanguageServices.GetRequiredService().CanApplyChange(oldOptions, newOptions); diff --git a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs index 6dfaa271090b7..bbb44339149d3 100644 --- a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs +++ b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs @@ -46,6 +46,12 @@ public string? ProjectFilePath set => _visualStudioProject.FilePath = value; } + public bool IsPrimary + { + get => _visualStudioProject.IsPrimary; + set => _visualStudioProject.IsPrimary = value; + } + public Guid Guid { get; diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs deleted file mode 100644 index a788fafe4467b..0000000000000 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections.Generic; -using System.Threading; - -namespace Microsoft.CodeAnalysis -{ - internal partial struct SymbolKey - { - private static class BodyLevelSymbolKey - { - public static void Create(ISymbol symbol, SymbolKeyWriter visitor) - { - var containingSymbol = symbol.ContainingSymbol; - - while (containingSymbol.DeclaringSyntaxReferences.IsDefaultOrEmpty) - { - containingSymbol = containingSymbol.ContainingSymbol; - } - - var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; - var kind = symbol.Kind; - var localName = symbol.Name; - - // Use two mechanisms to try to find the symbol across compilations. First, we use a whitespace - // insensitive system where we keep track of the list of all locals in the container and we just store - // our index in it. - // - // The above works for cases where the symbol has a real declaration and can be found by walking the - // declarations of the container. However, not all symbols can be found that way. For example, error - // locals in VB can't be found using GetDeclaredSymbol. For those, we store the actual local span and - // use GetSymbolInfo to find it. - var ordinal = GetOrdinal(); - - visitor.WriteString(localName); - visitor.WriteSymbolKey(containingSymbol); - visitor.WriteInteger(ordinal); - visitor.WriteLocation(symbol.Locations[0]); - visitor.WriteInteger((int)kind); - - return; - - int GetOrdinal() - { - foreach (var possibleSymbol in EnumerateSymbols(compilation, containingSymbol, kind, localName, visitor.CancellationToken)) - { - if (possibleSymbol.symbol.Equals(symbol)) - return possibleSymbol.ordinal; - } - - return int.MaxValue; - } - } - - public static SymbolKeyResolution Resolve(SymbolKeyReader reader) - { - var cancellationToken = reader.CancellationToken; - - var localName = reader.ReadString(); - var containingSymbolResolution = reader.ReadSymbolKey(); - var ordinal = reader.ReadInteger(); - var location = reader.ReadLocation(); - var kind = (SymbolKind)reader.ReadInteger(); - - var containingSymbol = containingSymbolResolution.Symbol; - if (containingSymbol != null) - { - if (ordinal != int.MaxValue) - { - foreach (var symbol in EnumerateSymbols(reader.Compilation, containingSymbol, kind, localName, cancellationToken)) - { - if (symbol.ordinal == ordinal) - return new SymbolKeyResolution(symbol.symbol); - } - } - else - { - var resolution = reader.ResolveLocation(location); - if (resolution != null) - return resolution.Value; - } - } - - return new SymbolKeyResolution(); - } - - private static IEnumerable<(ISymbol symbol, int ordinal)> EnumerateSymbols( - Compilation compilation, ISymbol containingSymbol, - SymbolKind kind, string localName, - CancellationToken cancellationToken) - { - var ordinal = 0; - - foreach (var declaringLocation in containingSymbol.DeclaringSyntaxReferences) - { - // This operation can potentially fail. If containingSymbol came from - // a SpeculativeSemanticModel, containingSymbol.ContainingAssembly.Compilation - // may not have been rebuilt to reflect the trees used by the - // SpeculativeSemanticModel to produce containingSymbol. In that case, - // asking the ContainingAssembly's compilation for a SemanticModel based - // on trees for containingSymbol with throw an ArgumentException. - // Unfortunately, the best way to avoid this (currently) is to see if - // we're asking for a model for a tree that's part of the compilation. - // (There's no way to get back to a SemanticModel from a symbol). - - // TODO (rchande): It might be better to call compilation.GetSemanticModel - // and catch the ArgumentException. The compilation internally has a - // Dictionary that it uses to check if the SyntaxTree - // is applicable wheras the public interface requires us to enumerate - // the entire IEnumerable of trees in the Compilation. - if (!Contains(compilation.SyntaxTrees, declaringLocation.SyntaxTree)) - { - continue; - } - - var node = declaringLocation.GetSyntax(cancellationToken); - if (node.Language == LanguageNames.VisualBasic) - { - node = node.Parent; - } - - var semanticModel = compilation.GetSemanticModel(node.SyntaxTree); - - foreach (var token in node.DescendantNodes()) - { - var symbol = semanticModel.GetDeclaredSymbol(token, cancellationToken); - - if (symbol != null && - symbol.Kind == kind && - SymbolKey.Equals(compilation, symbol.Name, localName)) - { - yield return (symbol, ordinal++); - } - } - } - } - - private static bool Contains(IEnumerable trees, SyntaxTree tree) - { - foreach (var current in trees) - { - if (current == tree) - { - return true; - } - } - - return false; - } - } - } -} From 699eed6a1dadf1a1a54c0aaf8ac120c5315deb91 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 14:15:17 -0700 Subject: [PATCH 188/222] restore file --- .../SymbolKey/SymbolKey.BodyLevelSymbolKey.cs | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs new file mode 100644 index 0000000000000..a788fafe4467b --- /dev/null +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; + +namespace Microsoft.CodeAnalysis +{ + internal partial struct SymbolKey + { + private static class BodyLevelSymbolKey + { + public static void Create(ISymbol symbol, SymbolKeyWriter visitor) + { + var containingSymbol = symbol.ContainingSymbol; + + while (containingSymbol.DeclaringSyntaxReferences.IsDefaultOrEmpty) + { + containingSymbol = containingSymbol.ContainingSymbol; + } + + var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; + var kind = symbol.Kind; + var localName = symbol.Name; + + // Use two mechanisms to try to find the symbol across compilations. First, we use a whitespace + // insensitive system where we keep track of the list of all locals in the container and we just store + // our index in it. + // + // The above works for cases where the symbol has a real declaration and can be found by walking the + // declarations of the container. However, not all symbols can be found that way. For example, error + // locals in VB can't be found using GetDeclaredSymbol. For those, we store the actual local span and + // use GetSymbolInfo to find it. + var ordinal = GetOrdinal(); + + visitor.WriteString(localName); + visitor.WriteSymbolKey(containingSymbol); + visitor.WriteInteger(ordinal); + visitor.WriteLocation(symbol.Locations[0]); + visitor.WriteInteger((int)kind); + + return; + + int GetOrdinal() + { + foreach (var possibleSymbol in EnumerateSymbols(compilation, containingSymbol, kind, localName, visitor.CancellationToken)) + { + if (possibleSymbol.symbol.Equals(symbol)) + return possibleSymbol.ordinal; + } + + return int.MaxValue; + } + } + + public static SymbolKeyResolution Resolve(SymbolKeyReader reader) + { + var cancellationToken = reader.CancellationToken; + + var localName = reader.ReadString(); + var containingSymbolResolution = reader.ReadSymbolKey(); + var ordinal = reader.ReadInteger(); + var location = reader.ReadLocation(); + var kind = (SymbolKind)reader.ReadInteger(); + + var containingSymbol = containingSymbolResolution.Symbol; + if (containingSymbol != null) + { + if (ordinal != int.MaxValue) + { + foreach (var symbol in EnumerateSymbols(reader.Compilation, containingSymbol, kind, localName, cancellationToken)) + { + if (symbol.ordinal == ordinal) + return new SymbolKeyResolution(symbol.symbol); + } + } + else + { + var resolution = reader.ResolveLocation(location); + if (resolution != null) + return resolution.Value; + } + } + + return new SymbolKeyResolution(); + } + + private static IEnumerable<(ISymbol symbol, int ordinal)> EnumerateSymbols( + Compilation compilation, ISymbol containingSymbol, + SymbolKind kind, string localName, + CancellationToken cancellationToken) + { + var ordinal = 0; + + foreach (var declaringLocation in containingSymbol.DeclaringSyntaxReferences) + { + // This operation can potentially fail. If containingSymbol came from + // a SpeculativeSemanticModel, containingSymbol.ContainingAssembly.Compilation + // may not have been rebuilt to reflect the trees used by the + // SpeculativeSemanticModel to produce containingSymbol. In that case, + // asking the ContainingAssembly's compilation for a SemanticModel based + // on trees for containingSymbol with throw an ArgumentException. + // Unfortunately, the best way to avoid this (currently) is to see if + // we're asking for a model for a tree that's part of the compilation. + // (There's no way to get back to a SemanticModel from a symbol). + + // TODO (rchande): It might be better to call compilation.GetSemanticModel + // and catch the ArgumentException. The compilation internally has a + // Dictionary that it uses to check if the SyntaxTree + // is applicable wheras the public interface requires us to enumerate + // the entire IEnumerable of trees in the Compilation. + if (!Contains(compilation.SyntaxTrees, declaringLocation.SyntaxTree)) + { + continue; + } + + var node = declaringLocation.GetSyntax(cancellationToken); + if (node.Language == LanguageNames.VisualBasic) + { + node = node.Parent; + } + + var semanticModel = compilation.GetSemanticModel(node.SyntaxTree); + + foreach (var token in node.DescendantNodes()) + { + var symbol = semanticModel.GetDeclaredSymbol(token, cancellationToken); + + if (symbol != null && + symbol.Kind == kind && + SymbolKey.Equals(compilation, symbol.Name, localName)) + { + yield return (symbol, ordinal++); + } + } + } + } + + private static bool Contains(IEnumerable trees, SyntaxTree tree) + { + foreach (var current in trees) + { + if (current == tree) + { + return true; + } + } + + return false; + } + } + } +} From 806555e354d24e4637fa3c415a80ec22588e7507 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 15:09:02 -0700 Subject: [PATCH 189/222] Ensure we clear out existing todo comments when a user deletes a file. --- .../VisualStudioTodoCommentsService.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs b/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs index 7b62594d3b0e4..40cb186518775 100644 --- a/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs +++ b/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs @@ -127,7 +127,7 @@ private Task ProcessTodoCommentInfosAsync( { cancellationToken.ThrowIfCancellationRequested(); - using var _ = ArrayBuilder.GetInstance(out var filteredArray); + using var _1 = ArrayBuilder.GetInstance(out var filteredArray); AddFilteredInfos(docAndCommentsArray, filteredArray); foreach (var docAndComments in filteredArray) @@ -141,7 +141,14 @@ private Task ProcessTodoCommentInfosAsync( // only one thread can be executing ProcessTodoCommentInfosAsync at a time, // so it's safe to remove/add here. - _documentToInfos[documentId] = newComments; + if (newComments.IsEmpty) + { + _documentToInfos.TryRemove(documentId, out _); + } + else + { + _documentToInfos[documentId] = newComments; + } // If we have someone listening for updates, and our new items are different from // our old ones, then notify them of the change. @@ -191,10 +198,13 @@ public IEnumerable GetTodoItemsUpdatedEventArgs( /// /// Callback from the OOP service back into us. /// - public Task OnDocumentRemovedAsync(DocumentId documentId, CancellationToken cancellationToken) + public async Task OnDocumentRemovedAsync(DocumentId documentId, CancellationToken cancellationToken) { - _documentToInfos.TryRemove(documentId, out _); - return Task.CompletedTask; + var workQueue = await _workQueueSource.Task.ConfigureAwait(false); + + // treat this as if we have no todo comments for this file. ProcessTodoCommentInfosAsync + // will handle actually clearing out the data. + workQueue.AddWork(new DocumentAndComments(documentId, ImmutableArray.Empty)); } /// From f8ecb16d0cc5b0a3d53fb904ff80c9221d92e32d Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Thu, 14 May 2020 15:22:22 -0700 Subject: [PATCH 190/222] Update src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs --- .../Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs index 803f84f18f0be..3ab59e771021d 100644 --- a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs +++ b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs @@ -77,7 +77,7 @@ protected override ImmutableArray GetReducers() /// Adds #nullable enable and #nullable disable annotations to the file as necessary. Note that /// this does not try to be 100% accurate, but rather it handles the most common cases out there. Specifically, /// if a file contains any nullable annotated/not-annotated types, then we prefix the file with #nullable - /// enable. Then if we hit any members that explicitly have *oblivious* types, not no annotated or + /// enable. Then if we hit any members that explicitly have *oblivious* types, but no annotated or /// non-annotated types, then we switch to #nullable disable for those specific members. /// /// This is technically innacurate for possible, but very uncommon cases. For example, if the user's code From 45b6c2e25f134effe536e79125ca10c0d4cd9e3e Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 15:35:33 -0700 Subject: [PATCH 191/222] Add comment --- .../CodeGeneration/NullableSyntaxAnnotation.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs b/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs index 2f7c5cc482697..c2f31ee2a8cf6 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs @@ -2,16 +2,18 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Microsoft.CodeAnalysis.Editing; + namespace Microsoft.CodeAnalysis.CodeGeneration { /// - /// Annotation placed if the code generator encounters a NullableAttribute or NullableContextAttribute while - /// generating the code. + /// Annotation placed on s that the converts to a node. This + /// information tracks the original nullable state of the symbol and is used by metadata-as-source to determine if + /// it needs to add #nullable directives in the file. /// internal sealed class NullableSyntaxAnnotation { - public static readonly SyntaxAnnotation None = new SyntaxAnnotation($"{nameof(NullableAnnotation)}.{NullableAnnotation.None}"); - public static readonly SyntaxAnnotation Annotated = new SyntaxAnnotation($"{nameof(NullableAnnotation)}.{NullableAnnotation.Annotated}"); - public static readonly SyntaxAnnotation NotAnnotated = new SyntaxAnnotation($"{nameof(NullableAnnotation)}.{NullableAnnotation.NotAnnotated}"); + public static readonly SyntaxAnnotation Oblivious = new SyntaxAnnotation($"{nameof(NullableSyntaxAnnotation)}.{Oblivious}"); + public static readonly SyntaxAnnotation NotOblivious = new SyntaxAnnotation($"{nameof(NullableSyntaxAnnotation)}.{NotOblivious}"); } } From 6601df1617a169583047f84efb6ec9bfec14d2cc Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 15:44:30 -0700 Subject: [PATCH 192/222] Simplify --- .../CSharpMetadataAsSourceService.cs | 17 +++++++++-------- .../CodeGeneration/NullableSyntaxAnnotation.cs | 8 +++++++- .../CSharp/Extensions/ITypeSymbolExtensions.cs | 6 +++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs index 3ab59e771021d..1bca978c9a2b4 100644 --- a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs +++ b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs @@ -106,10 +106,10 @@ protected override async Task AddNullableRegionsAsync(Document documen var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); - var (_, annotated, notAnnotated) = GetNullableAnnotations(root); + var (_, annotatedOrNotAnnotated) = GetNullableAnnotations(root); // If there are no annotated or not-annotated types, then no need to add `#nullable enable`. - if (!annotated && !notAnnotated) + if (!annotatedOrNotAnnotated) return document; var newRoot = AddNullableRegions(root, cancellationToken); @@ -118,11 +118,10 @@ protected override async Task AddNullableRegionsAsync(Document documen return document.WithSyntaxRoot(newRoot); } - private (bool oblivious, bool annotated, bool notAnnotated) GetNullableAnnotations(SyntaxNode node) + private (bool oblivious, bool annotatedOrNotAnnotated) GetNullableAnnotations(SyntaxNode node) { - return (HasAnnotation(node, NullableSyntaxAnnotation.None), - HasAnnotation(node, NullableSyntaxAnnotation.Annotated), - HasAnnotation(node, NullableSyntaxAnnotation.NotAnnotated)); + return (HasAnnotation(node, NullableSyntaxAnnotation.Oblivious), + HasAnnotation(node, NullableSyntaxAnnotation.AnnotatedOrNotAnnotated)); } private bool HasAnnotation(SyntaxNode node, SyntaxAnnotation annotation) @@ -176,6 +175,8 @@ private TypeDeclarationSyntax AddNullableRegionsAroundTypeMembers( foreach (var member in type.Members) { + cancellationToken.ThrowIfCancellationRequested(); + if (member is BaseTypeDeclarationSyntax) { // if we hit a type, and we're currently disabled, then switch us back to enabled for that type. @@ -185,10 +186,10 @@ private TypeDeclarationSyntax AddNullableRegionsAroundTypeMembers( } // we hit a member. see what sort of types it contained. - var (oblivious, annotated, notAnnotated) = GetNullableAnnotations(member); + var (oblivious, annotatedOrNotAnnotated) = GetNullableAnnotations(member); // if we have null annotations, transition us back to the enabled state - if (annotated || notAnnotated) + if (annotatedOrNotAnnotated) { builder.Add(TransitionTo(member, enabled: true, ref currentlyEnabled)); } diff --git a/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs b/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs index c2f31ee2a8cf6..925ce03bfc64e 100644 --- a/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs +++ b/src/Workspaces/Core/Portable/CodeGeneration/NullableSyntaxAnnotation.cs @@ -13,7 +13,13 @@ namespace Microsoft.CodeAnalysis.CodeGeneration /// internal sealed class NullableSyntaxAnnotation { + /// + /// For string~ types. + /// public static readonly SyntaxAnnotation Oblivious = new SyntaxAnnotation($"{nameof(NullableSyntaxAnnotation)}.{Oblivious}"); - public static readonly SyntaxAnnotation NotOblivious = new SyntaxAnnotation($"{nameof(NullableSyntaxAnnotation)}.{NotOblivious}"); + /// + /// For string! or string? types. + /// + public static readonly SyntaxAnnotation AnnotatedOrNotAnnotated = new SyntaxAnnotation($"{nameof(NullableSyntaxAnnotation)}.{AnnotatedOrNotAnnotated}"); } } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs index f1e43cd00e060..77e53f1c502d8 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs @@ -65,9 +65,9 @@ private static TypeSyntax GenerateTypeSyntax( syntax = syntax.WithAdditionalAnnotations( type.NullableAnnotation switch { - NullableAnnotation.None => NullableSyntaxAnnotation.None, - NullableAnnotation.Annotated => NullableSyntaxAnnotation.Annotated, - NullableAnnotation.NotAnnotated => NullableSyntaxAnnotation.NotAnnotated, + NullableAnnotation.None => NullableSyntaxAnnotation.Oblivious, + NullableAnnotation.Annotated => NullableSyntaxAnnotation.AnnotatedOrNotAnnotated, + NullableAnnotation.NotAnnotated => NullableSyntaxAnnotation.AnnotatedOrNotAnnotated, _ => throw ExceptionUtilities.UnexpectedValue(type.NullableAnnotation), }); } From f21590df2549fdf2acdf09d37078a08caa27b4ff Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 15:52:56 -0700 Subject: [PATCH 193/222] Filter out dynamic attribute. --- .../MetadataAsSource/MetadataAsSourceTests.cs | 44 +++++++++++++++++++ .../CodeGeneration/AttributeGenerator.cs | 7 ++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index c4422114f3494..7dc6172adc53b 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -2627,5 +2627,49 @@ public class TestType var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); context.VerifyResult(metadataAsSourceFile, expected); } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestDynamic1() + { + var metadata = @" +using System; + +public class TestType +{ + public void M1(dynamic s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +public class TestType +{{ + public TestType(); + + public void [|M1|](dynamic s); +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } } } diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs index 0c864e30159b7..afa7b550a3ed1 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/AttributeGenerator.cs @@ -93,8 +93,13 @@ private static bool IsCompilerInternalAttribute(AttributeData attribute) var name = attrClass.Name; - if (name != "NullableAttribute" && name != "NullableContextAttribute" && name != "NativeIntegerAttribute") + if (name != "NullableAttribute" && + name != "NullableContextAttribute" && + name != "NativeIntegerAttribute" && + name != "DynamicAttribute") + { return false; + } var ns = attrClass.ContainingNamespace; return ns?.Name == nameof(System.Runtime.CompilerServices) && From 9183eb709b54a24e99e8ee9b25bc29751609c17b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 16:09:22 -0700 Subject: [PATCH 194/222] Fix nullable ref type parameters. --- .../MetadataAsSource/MetadataAsSourceTests.cs | 278 ++++++++++++++++++ ...olExtensions.TypeSyntaxGeneratorVisitor.cs | 8 +- 2 files changed, 285 insertions(+), 1 deletion(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index 7dc6172adc53b..96d3176beb5fc 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -2628,6 +2628,284 @@ public class TestType context.VerifyResult(metadataAsSourceFile, expected); } + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable6() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(T? s) where T : class + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](""""); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +public class TestType +{{ + public TestType(); + + public void [|M1|](T? s) where T : class; +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable7() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(T s) where T : class + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](""""); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +public class TestType +{{ + public TestType(); + + public void [|M1|](T s) where T : class; +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable8() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(T? s) where T : struct + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](0); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +public class TestType +{{ + public TestType(); + + public void [|M1|](T? s) where T : struct; +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable9() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(T s) where T : struct + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](0); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +public class TestType +{{ + public TestType(); + + public void [|M1|](T s) where T : struct; +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable10() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(T s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](""""); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +public class TestType +{{ + public TestType(); + + public void [|M1|](T s); +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable11() + { + var metadata = @" +using System; + +public class TestType +{ + public void M1(T s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](""""); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +public class TestType +{{ + public TestType(); + + public void [|M1|](T s); +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] public async Task TestDynamic1() { diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.TypeSyntaxGeneratorVisitor.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.TypeSyntaxGeneratorVisitor.cs index ce43f3b0d2afc..731a2028d3b64 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.TypeSyntaxGeneratorVisitor.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.TypeSyntaxGeneratorVisitor.cs @@ -304,7 +304,13 @@ public override TypeSyntax VisitPointerType(IPointerTypeSymbol symbol) } public override TypeSyntax VisitTypeParameter(ITypeParameterSymbol symbol) - => AddInformationTo(symbol.Name.ToIdentifierName(), symbol); + { + TypeSyntax typeSyntax = AddInformationTo(symbol.Name.ToIdentifierName(), symbol); + if (symbol.NullableAnnotation == NullableAnnotation.Annotated) + typeSyntax = AddInformationTo(SyntaxFactory.NullableType(typeSyntax), symbol); + + return typeSyntax; + } } } } From 6c8c3a04c37147e82874063e03c0721f88363d8c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 16:17:38 -0700 Subject: [PATCH 195/222] Add tests --- .../MetadataAsSource/MetadataAsSourceTests.cs | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index 96d3176beb5fc..7c8fb731e215a 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -2743,7 +2743,7 @@ class C { void M() { - var obj = new TestType().[|M1|](0); + var obj = new TestType().[|M1|]((int?)0); } }"; var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null @@ -2906,6 +2906,70 @@ public class TestType context.VerifyResult(metadataAsSourceFile, expected); } + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable12() + { + var metadata = @" +#nullable enable + +using System; + +namespace N +{ + public class TestType + { + public void M1(string s) + { + } + + #nullable disable + + public void M2(string s) + { + } + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new N.TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +namespace N +{{ + public class TestType + {{ + public TestType(); + + public void [|M1|](string s); +#nullable disable + public void M2(string s); + +#nullable enable + }} +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] public async Task TestDynamic1() { From 02c58e02e19ac1ab70e896613d8fd242bca551eb Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 16:29:45 -0700 Subject: [PATCH 196/222] Add test for nested type --- .../MetadataAsSource/MetadataAsSourceTests.cs | 74 +++++++++++++++++++ .../CSharpMetadataAsSourceService.cs | 13 ++-- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index 7c8fb731e215a..9cf7a324ad0ea 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -2970,6 +2970,80 @@ public class TestType context.VerifyResult(metadataAsSourceFile, expected); } + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] + public async Task TestNullableEnableDisable13() + { + var metadata = @" +#nullable enable + +using System; + +public class TestType +{ + public void M1(string s) + { + } + +#nullable disable + + public class Nested + { + public void NestedM(string s) + { + } + } + +#nullable enable + + public void M2(string s) + { + } +}"; + var sourceWithSymbolReference = @" +class C +{ + void M() + { + var obj = new TestType().[|M1|](null); + } +}"; + var expected = $@"#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// {CodeAnalysisResources.InMemoryAssembly} +#endregion + +#nullable enable + +public class TestType +{{ + public TestType(); + + public void [|M1|](string s); + public void M2(string s); + + public class Nested + {{ + public Nested(); + +#nullable disable + public void NestedM(string s); + +#nullable enable + }} +}}"; + + using var context = TestContext.Create( + LanguageNames.CSharp, + SpecializedCollections.SingletonEnumerable(metadata), + includeXmlDocComments: false, + languageVersion: "CSharp8", + sourceWithSymbolReference: sourceWithSymbolReference, + metadataLanguageVersion: "CSharp8"); + + var navigationSymbol = await context.GetNavigationSymbolAsync(); + var metadataAsSourceFile = await context.GenerateSourceAsync(navigationSymbol); + context.VerifyResult(metadataAsSourceFile, expected); + } + [Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)] public async Task TestDynamic1() { diff --git a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs index 1bca978c9a2b4..a24fc06bf6dd6 100644 --- a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs +++ b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs @@ -143,13 +143,14 @@ private static SyntaxTrivia[] CreateNullableTrivia(bool enable) }; } - private SyntaxNode AddNullableRegions(SyntaxNode node, CancellationToken cancellationToken) + private TSyntax AddNullableRegions(TSyntax node, CancellationToken cancellationToken) + where TSyntax : SyntaxNode { return node switch { - CompilationUnitSyntax compilationUnit => compilationUnit.WithMembers(AddNullableRegions(compilationUnit.Members, cancellationToken)), - NamespaceDeclarationSyntax ns => ns.WithMembers(AddNullableRegions(ns.Members, cancellationToken)), - TypeDeclarationSyntax type => AddNullableRegionsAroundTypeMembers(type, cancellationToken), + CompilationUnitSyntax compilationUnit => (TSyntax)(object)compilationUnit.WithMembers(AddNullableRegions(compilationUnit.Members, cancellationToken)), + NamespaceDeclarationSyntax ns => (TSyntax)(object)ns.WithMembers(AddNullableRegions(ns.Members, cancellationToken)), + TypeDeclarationSyntax type => (TSyntax)(object)AddNullableRegionsAroundTypeMembers(type, cancellationToken), _ => node, }; } @@ -161,7 +162,7 @@ private SyntaxList AddNullableRegions( using var _ = ArrayBuilder.GetInstance(out var builder); foreach (var member in members) - builder.Add((MemberDeclarationSyntax)AddNullableRegions(member, cancellationToken)); + builder.Add(AddNullableRegions(member, cancellationToken)); return SyntaxFactory.List(builder); } @@ -181,7 +182,7 @@ private TypeDeclarationSyntax AddNullableRegionsAroundTypeMembers( { // if we hit a type, and we're currently disabled, then switch us back to enabled for that type. // This ensures whenever we walk into a type-decl, we're always in the enabled-state. - builder.Add(TransitionTo(member, enabled: true, ref currentlyEnabled)); + builder.Add(TransitionTo(AddNullableRegions(member, cancellationToken), enabled: true, ref currentlyEnabled)); continue; } From d9c2d616901abf3aee84c846d9fd07727ef6ae9c Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 16:30:44 -0700 Subject: [PATCH 197/222] Whitespace --- .../Test/MetadataAsSource/MetadataAsSourceTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs index 9cf7a324ad0ea..58b6a6034b9ad 100644 --- a/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs +++ b/src/EditorFeatures/Test/MetadataAsSource/MetadataAsSourceTests.cs @@ -3028,7 +3028,7 @@ public class Nested public void NestedM(string s); #nullable enable - }} + }} }}"; using var context = TestContext.Create( From d37728cdb6dd683e18cc1a19299a983161967b9a Mon Sep 17 00:00:00 2001 From: Jason Malinowski Date: Thu, 14 May 2020 16:57:08 -0700 Subject: [PATCH 198/222] Fix up Theory that wasn't actually using the test parameters Originally there was just the TestSourceFilePathMappingWithDriveLetterOnly test which was a simple fact that only covered one case. It looks like I copied that intending to add a second test, and then converted the second copy to a Theory...and then never updated that properly either nor deleted the original. This puts everything back in order. Fixes https://github.com/dotnet/roslyn/issues/44224 --- .../GeneratorTest/CompilerInvocationTests.vb | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb index 63e5f40c84718..829fbd928bbdb 100644 --- a/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb +++ b/src/Features/Lsif/GeneratorTest/CompilerInvocationTests.vb @@ -59,11 +59,9 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests Assert.Equal(referencePath, DirectCast(metadataReference, PortableExecutableReference).FilePath) End Sub -#Disable Warning IDE0060 ' Remove unused parameter - https://github.com/dotnet/roslyn/issues/44224 - Public Async Sub TestSourceFilePathMappingWithDriveLetters( from As String, [to] As String) -#Enable Warning IDE0060 ' Remove unused parameter + Public Async Sub TestSourceFilePathMappingWithDriveLetters( from As String, [to] As String) Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" { ""tool"": ""csc"", @@ -72,28 +70,8 @@ Namespace Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.UnitTests ""sourceRootPath"": ""F:\\"", ""pathMappings"": [ { - ""from"": ""F:\\"", - ""to"": ""T:\\"" - }] - }") - - Dim syntaxTree = Assert.Single(compilerInvocation.Compilation.SyntaxTrees) - - Assert.Equal("T:\SourceFile.cs", syntaxTree.FilePath) - End Sub - - - Public Async Sub TestSourceFilePathMappingWithDriveLetterOnly() - Dim compilerInvocation = Await Microsoft.CodeAnalysis.LanguageServerIndexFormat.Generator.CompilerInvocation.CreateFromJsonAsync(" - { - ""tool"": ""csc"", - ""arguments"": ""/noconfig /nowarn:1701,1702 /fullpaths /define:DEBUG F:\\SourceFile.cs /target:library /out:F:\\Output.dll"", - ""projectFilePath"": ""F:\\Project.csproj"", - ""sourceRootPath"": ""F:\\"", - ""pathMappings"": [ - { - ""from"": ""F:\\"", - ""to"": ""T:"" + ""from"": """ + from.Replace("\", "\\") + """, + ""to"": """ + [to].Replace("\", "\\") + """ }] }") From 0a4abc85d58b5701911c7793ba08bc2a32f44521 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 17:00:40 -0700 Subject: [PATCH 199/222] Always get locations --- .../Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs | 2 +- src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs index 8b1c14aee4de0..012a2a73de384 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs @@ -289,7 +289,7 @@ public override void Dispose() _idToResult.Clear(); Compilation = null; IgnoreAssemblyKey = false; - _resolveLocations = false; + _resolveLocations = true; Comparer = null; _methodSymbolStack.Clear(); diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs index 6e15f95dd6179..3039c93efd558 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs @@ -128,7 +128,7 @@ internal static IEqualityComparer GetComparer(bool ignoreCase = false internal static SymbolKeyResolution ResolveString( string symbolKey, Compilation compilation, - bool ignoreAssemblyKey = false, bool resolveLocations = false, + bool ignoreAssemblyKey = false, bool resolveLocations = true, CancellationToken cancellationToken = default) { using var reader = SymbolKeyReader.GetReader( @@ -164,7 +164,7 @@ internal static string CreateStringWorker(int version, ISymbol symbol, Cancellat /// the locations resolved may not actually be correct in the final compilation. /// public SymbolKeyResolution Resolve( - Compilation compilation, bool ignoreAssemblyKey = false, bool resolveLocations = false, CancellationToken cancellationToken = default) + Compilation compilation, bool ignoreAssemblyKey = false, bool resolveLocations = true, CancellationToken cancellationToken = default) { return ResolveString(_symbolKeyData, compilation, ignoreAssemblyKey, resolveLocations, cancellationToken); } From 6a00bb7027c668aee9734e1b00219ddac4c98b30 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 17:30:27 -0700 Subject: [PATCH 200/222] Fixes --- .../SymbolKey/SymbolKey.BodyLevelSymbolKey.cs | 42 ++++++++++++------- .../SymbolKey/SymbolKey.SymbolKeyReader.cs | 4 ++ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs index 0c5ec43d09b62..d012bfb2342c0 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs @@ -30,14 +30,16 @@ public static void Create(ISymbol symbol, SymbolKeyWriter visitor) var kind = symbol.Kind; var localName = symbol.Name; - Contract.ThrowIfTrue(symbol.DeclaringSyntaxReferences.IsEmpty); - var syntaxRef = symbol.DeclaringSyntaxReferences[0].GetSyntax(visitor.CancellationToken); - visitor.WriteString(localName); visitor.WriteInteger((int)kind); - // write out the location for precision - visitor.WriteLocation(syntaxRef.GetLocation()); + // write out the locations for precision + Contract.ThrowIfTrue(symbol.DeclaringSyntaxReferences.IsEmpty && symbol.Locations.IsEmpty); + + var locations = symbol.Locations.Concat( + symbol.DeclaringSyntaxReferences.SelectAsArray(r => r.GetSyntax(visitor.CancellationToken).GetLocation())); + + visitor.WriteLocationArray(locations); // and the ordinal for resilience visitor.WriteInteger(GetOrdinal()); @@ -46,7 +48,7 @@ public static void Create(ISymbol symbol, SymbolKeyWriter visitor) int GetOrdinal() { - var syntaxTree = syntaxRef.SyntaxTree; + var syntaxTree = locations[0].SourceTree; var compilation = ((ISourceAssemblySymbol)symbol.ContainingAssembly).Compilation; // Ensure that the tree we're looking at is actually in this compilation. It may not be in the @@ -69,29 +71,39 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader) { var cancellationToken = reader.CancellationToken; - var localName = reader.ReadString(); + var name = reader.ReadString(); var kind = (SymbolKind)reader.ReadInteger(); - var location = reader.ReadLocation(); + var locations = reader.ReadLocationArray(); var ordinal = reader.ReadInteger(); // First check if we can recover the symbol just through the original location. - var semanticModel = reader.Compilation.GetSemanticModel(location.SourceTree); - var declaredSymbol = semanticModel.GetDeclaredSymbol(location.FindNode(reader.CancellationToken)); - - if (declaredSymbol?.Name == localName && declaredSymbol?.Kind == kind) - return new SymbolKeyResolution(declaredSymbol); + foreach (var loc in locations) + { + var resolutionOpt = reader.ResolveLocation(loc); + if (resolutionOpt.HasValue) + { + var resolution = resolutionOpt.Value; + var symbol = resolution.GetAnySymbol(); + if (symbol?.Kind == kind && + SymbolKey.Equals(reader.Compilation, name, symbol.Name)) + { + return resolution; + } + } + } // Couldn't recover. See if we can still find a match across the textual drift. if (ordinal != int.MaxValue) { - foreach (var symbol in EnumerateSymbols(semanticModel, kind, localName, cancellationToken)) + var semanticModel = reader.Compilation.GetSemanticModel(locations[0].SourceTree); + foreach (var symbol in EnumerateSymbols(semanticModel, kind, name, cancellationToken)) { if (symbol.ordinal == ordinal) return new SymbolKeyResolution(symbol.symbol); } } - return new SymbolKeyResolution(); + return default; } private static IEnumerable<(ISymbol symbol, int ordinal)> EnumerateSymbols( diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs index 012a2a73de384..51ee0c7a650d3 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs @@ -552,6 +552,10 @@ public Location ReadLocation() { var node = location.FindNode(findInsideTrivia: true, getInnermostNodeForTie: true, CancellationToken); var semanticModel = Compilation.GetSemanticModel(location.SourceTree); + var symbol = semanticModel.GetDeclaredSymbol(node, CancellationToken); + if (symbol != null) + return new SymbolKeyResolution(symbol); + var info = semanticModel.GetSymbolInfo(node, CancellationToken); if (info.Symbol != null) return new SymbolKeyResolution(info.Symbol); From 28109ea36f294865b7ab25113d95758761c7cef4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 21:27:41 -0700 Subject: [PATCH 201/222] Unused using --- .../Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs index d012bfb2342c0..6fd75261cbb3b 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.BodyLevelSymbolKey.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Threading; -using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis From f8de6566cbab6b2ebecd0fc6080d34b448bf06c3 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 21:51:49 -0700 Subject: [PATCH 202/222] Fix test --- .../GenerateConstructorFromMembersTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs index c67eaa36c27d0..6ac99d74b436d 100644 --- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateConstructorFromMembers/GenerateConstructorFromMembersTests.cs @@ -1069,7 +1069,7 @@ class Z where T : class string b; T? c; - public Z(int a, string b, T c{|Navigation:)|} + public Z(int a, string b, T? c{|Navigation:)|} { this.a = a; this.b = b ?? throw new ArgumentNullException(nameof(b)); From ad2a2e15b83d83e88002189e8d9789c1a94a41b9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 14 May 2020 23:48:07 -0700 Subject: [PATCH 203/222] lint --- .../Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs index 77e53f1c502d8..f46c55ad4604f 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs @@ -10,7 +10,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeGeneration; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Shared.Extensions; From 240bf6b9195a45c825f6e230741b0177d0eb8207 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 00:36:59 -0700 Subject: [PATCH 204/222] lint --- .../Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs index f46c55ad4604f..e19544cc8bdb7 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/CSharp/Extensions/ITypeSymbolExtensions.cs @@ -16,6 +16,10 @@ using Microsoft.CodeAnalysis.Simplification; using Roslyn.Utilities; +#if !CODE_STYLE +using Microsoft.CodeAnalysis.CodeGeneration; +#endif + namespace Microsoft.CodeAnalysis.CSharp.Extensions { internal static partial class ITypeSymbolExtensions From ab0f7acc78ad7de685d8d0ebf688008d53c1b2b4 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 10:23:24 -0700 Subject: [PATCH 205/222] Remove param --- .../Core/Portable/FindSymbols/SymbolFinder.cs | 2 +- .../Core/Portable/Remote/RemoteArguments.cs | 2 +- .../SymbolKey/SymbolKey.SymbolKeyReader.cs | 40 +++++++------------ .../Core/Portable/SymbolKey/SymbolKey.cs | 23 +++++------ 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs index d063f25556ada..6655081145f59 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/SymbolFinder.cs @@ -213,7 +213,7 @@ public static IEnumerable FindSimilarSymbols(TSymbol symbol, C // We may be talking about different compilations. So do not try to resolve locations. var result = new HashSet(); - var resolution = key.Resolve(compilation, resolveLocations: false, cancellationToken: cancellationToken); + var resolution = key.Resolve(compilation, cancellationToken: cancellationToken); foreach (var current in resolution.OfType()) { result.Add(current); diff --git a/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs b/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs index 58008f84f17ec..dcf144ee7c574 100644 --- a/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs +++ b/src/Workspaces/Core/Portable/Remote/RemoteArguments.cs @@ -76,7 +76,7 @@ public async Task TryRehydrateAsync( // The server and client should both be talking about the same compilation. As such // locations in symbols are save to resolve as we rehydrate the SymbolKey. var symbol = SymbolKey.ResolveString( - SymbolKeyData, compilation, resolveLocations: true, cancellationToken: cancellationToken).GetAnySymbol(); + SymbolKeyData, compilation, cancellationToken: cancellationToken).GetAnySymbol(); if (symbol == null) { diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs index 51ee0c7a650d3..cbf4cdc0388b0 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.SymbolKeyReader.cs @@ -275,7 +275,6 @@ private class SymbolKeyReader : Reader public SymbolEquivalenceComparer Comparer { get; private set; } private readonly List _methodSymbolStack = new List(); - private bool _resolveLocations; public SymbolKeyReader() { @@ -289,7 +288,6 @@ public override void Dispose() _idToResult.Clear(); Compilation = null; IgnoreAssemblyKey = false; - _resolveLocations = true; Comparer = null; _methodSymbolStack.Clear(); @@ -299,11 +297,11 @@ public override void Dispose() public static SymbolKeyReader GetReader( string data, Compilation compilation, - bool ignoreAssemblyKey, bool resolveLocations, + bool ignoreAssemblyKey, CancellationToken cancellationToken) { var reader = s_readerPool.Allocate(); - reader.Initialize(data, compilation, ignoreAssemblyKey, resolveLocations, cancellationToken); + reader.Initialize(data, compilation, ignoreAssemblyKey, cancellationToken); return reader; } @@ -311,13 +309,11 @@ private void Initialize( string data, Compilation compilation, bool ignoreAssemblyKey, - bool resolveLocations, CancellationToken cancellationToken) { base.Initialize(data, cancellationToken); Compilation = compilation; IgnoreAssemblyKey = ignoreAssemblyKey; - _resolveLocations = resolveLocations; Comparer = ignoreAssemblyKey ? SymbolEquivalenceComparer.IgnoreAssembliesInstance @@ -508,15 +504,12 @@ public Location ReadLocation() var start = ReadInteger(); var length = ReadInteger(); - if (_resolveLocations) + // The syntax tree can be null if we're resolving this location in a compilation + // that does not contain this file. In this case, just map this location to None. + var syntaxTree = GetSyntaxTree(filePath); + if (syntaxTree != null) { - // The syntax tree can be null if we're resolving this location in a compilation - // that does not contain this file. In this case, just map this location to None. - var syntaxTree = GetSyntaxTree(filePath); - if (syntaxTree != null) - { - return Location.Create(syntaxTree, new TextSpan(start, length)); - } + return Location.Create(syntaxTree, new TextSpan(start, length)); } } else if (kind == LocationKind.MetadataFile) @@ -524,20 +517,17 @@ public Location ReadLocation() var assemblyResolution = ReadSymbolKey(); var moduleName = ReadString(); - if (_resolveLocations) + // We may be resolving in a compilation where we don't have a module + // with this name. In that case, just map this location to none. + if (assemblyResolution.GetAnySymbol() is IAssemblySymbol assembly) { - // We may be resolving in a compilation where we don't have a module - // with this name. In that case, just map this location to none. - if (assemblyResolution.GetAnySymbol() is IAssemblySymbol assembly) + var module = GetModule(assembly.Modules, moduleName); + if (module != null) { - var module = GetModule(assembly.Modules, moduleName); - if (module != null) + var location = FirstOrDefault(module.Locations); + if (location != null) { - var location = FirstOrDefault(module.Locations); - if (location != null) - { - return location; - } + return location; } } } diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs index 3039c93efd558..cbaeadca57ddb 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKey.cs @@ -77,11 +77,10 @@ namespace Microsoft.CodeAnalysis /// The SymbolKey for both 'M' methods will be the same. The SymbolKey will then resolve to both methods. /// /// - /// s are not guaranteed to work across different versions of Roslyn. - /// They can be persisted in their form and used across sessions with - /// the same version of Roslyn. However, future versions may change the encoded format and may - /// no longer be able to previous - /// keys. As such, only persist if using for a cache that can be regenerated if necessary. + /// s are not guaranteed to work across different versions of Roslyn. They can be persisted + /// in their form and used across sessions with the same version of Roslyn. However, future + /// versions may change the encoded format and may no longer be able to previous keys. As + /// such, only persist if using for a cache that can be regenerated if necessary. /// /// internal partial struct SymbolKey @@ -128,11 +127,10 @@ internal static IEqualityComparer GetComparer(bool ignoreCase = false internal static SymbolKeyResolution ResolveString( string symbolKey, Compilation compilation, - bool ignoreAssemblyKey = false, bool resolveLocations = true, - CancellationToken cancellationToken = default) + bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default) { using var reader = SymbolKeyReader.GetReader( - symbolKey, compilation, ignoreAssemblyKey, resolveLocations, cancellationToken); + symbolKey, compilation, ignoreAssemblyKey, cancellationToken); var version = reader.ReadFormatVersion(); if (version != FormatVersion) { @@ -158,15 +156,12 @@ internal static string CreateStringWorker(int version, ISymbol symbol, Cancellat /// /// Tries to resolve this in the given - /// to a matching symbol. - /// should only be given if the symbol was produced from a compilation - /// that has the exact same source as the compilation we're resolving against. Otherwise - /// the locations resolved may not actually be correct in the final compilation. + /// to a matching symbol. /// public SymbolKeyResolution Resolve( - Compilation compilation, bool ignoreAssemblyKey = false, bool resolveLocations = true, CancellationToken cancellationToken = default) + Compilation compilation, bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default) { - return ResolveString(_symbolKeyData, compilation, ignoreAssemblyKey, resolveLocations, cancellationToken); + return ResolveString(_symbolKeyData, compilation, ignoreAssemblyKey, cancellationToken); } /// From f98dfe5697e59d146ea1a463d6a9e990a99bf8f0 Mon Sep 17 00:00:00 2001 From: Nikolay Date: Fri, 15 May 2020 20:55:59 +0300 Subject: [PATCH 206/222] Remove obsolete ToTestDisplayString method (#44219) --- .../Test/Emit/Attributes/AttributeTests.cs | 1 + .../Emit/Attributes/AttributeTests_Dynamic.cs | 1 + .../Emit/CodeGen/CodeGenAsyncIteratorTests.cs | 1 + .../Emit/CodeGen/CodeGenAwaitForeachTests.cs | 1 + .../Emit/CodeGen/CodeGenDeconstructTests.cs | 1 + .../Emit/CodeGen/CodeGenLocalFunctionTests.cs | 1 + .../Test/Emit/CodeGen/CodeGenRefLocalTests.cs | 1 + .../Emit/CodeGen/CodeGenTupleEqualityTests.cs | 1 + .../Test/Emit/CodeGen/CodeGenTupleTest.cs | 1 + .../Test/Emit/Emit/EmitMetadataTests.cs | 1 + ...perationTests_IBinaryOperatorExpression.cs | 1 + .../IOperationTests_IVariableDeclaration.cs | 1 + .../FlowAnalysis/RegionAnalysisTests.cs | 1 + .../Semantics/AwaitExpressionTests.cs | 1 + .../Semantic/Semantics/BetterCandidates.cs | 1 + .../Test/Semantic/Semantics/BindingTests.cs | 1 + .../Semantic/Semantics/ColorColorTests.cs | 1 + .../Semantics/ConditionalOperatorTests.cs | 1 + .../Semantic/Semantics/DeconstructionTests.cs | 1 + .../Test/Semantic/Semantics/DynamicTests.cs | 1 + .../Semantics/ExpressionBodiedMemberTests.cs | 1 + .../Test/Semantic/Semantics/ForEachTests.cs | 1 + .../Semantics/GenericConstraintsTests.cs | 1 + .../Semantics/ImplicitlyTypeArraysTests.cs | 1 + .../Semantic/Semantics/IndexAndRangeTests.cs | 1 + .../InteractiveSemanticModelTests.cs | 1 + .../Test/Semantic/Semantics/IteratorTests.cs | 1 + .../Semantics/LambdaDiscardParametersTests.cs | 1 + .../Test/Semantic/Semantics/LambdaTests.cs | 1 + .../Semantic/Semantics/LocalFunctionTests.cs | 1 + .../Semantic/Semantics/LookupPositionTests.cs | 4 +- .../Test/Semantic/Semantics/LookupTests.cs | 1 + .../Semantics/MethodTypeInferenceTests.cs | 1 + .../Semantics/MultiDimensionalArrayTests.cs | 1 + .../Semantic/Semantics/NativeIntegerTests.cs | 1 + .../NonTrailingNamedArgumentsTests.cs | 1 + .../Semantics/NullableReferenceTypesTests.cs | 1 + .../ObjectAndCollectionInitializerTests.cs | 1 + .../Test/Semantic/Semantics/OperatorTests.cs | 1 + .../Test/Semantic/Semantics/OutVarTests.cs | 1 + .../Semantics/OverloadResolutionTests.cs | 1 + .../Semantics/PatternMatchingTests.cs | 1 + .../Semantics/PatternMatchingTests2.cs | 1 + .../Semantics/PatternMatchingTests3.cs | 1 + .../Semantics/PatternMatchingTests4.cs | 1 + .../Semantics/PatternMatchingTests_Global.cs | 1 + .../Semantics/PatternMatchingTests_Scope.cs | 1 + .../Semantic/Semantics/PatternSwitchTests.cs | 1 + .../Test/Semantic/Semantics/QueryTests.cs | 1 + .../Semantics/ScriptSemanticsTests.cs | 1 + .../Semantic/Semantics/SemanticErrorTests.cs | 1 + .../Semantics/StackAllocInitializerTests.cs | 1 + .../Semantics/TargetTypedDefaultTests.cs | 1 + .../TargetTypedObjectCreationTests.cs | 1 + .../Test/Semantic/Semantics/TypeOfTests.cs | 1 + .../Test/Semantic/Semantics/UnsafeTests.cs | 1 + .../Semantic/Semantics/UsingStatementTests.cs | 1 + .../Compilation/GetSemanticInfoTests.cs | 1 + .../IndexedProperties_BindingTests.cs | 1 + .../Compilation/SemanticModelAPITests.cs | 1 + .../SemanticModelGetDeclaredSymbolAPITests.cs | 1 + .../SemanticModelGetSemanticInfoTests.cs | 1 + ...nticModelGetSemanticInfoTests_LateBound.cs | 1 + .../Symbol/DocumentationComments/CrefTests.cs | 4 +- .../DocumentationComments/ParameterTests.cs | 62 ++++++++++--------- .../Symbols/AnonymousTypesSemanticsTests.cs | 1 + .../Symbol/Symbols/CustomModifiersTests.cs | 1 + .../Symbol/Symbols/ExtensionMethodTests.cs | 1 + .../Test/Symbol/Symbols/IndexerTests.cs | 5 +- .../Metadata/PE/LoadCustomModifiers.cs | 1 + .../Symbols/Metadata/PE/LoadingFields.cs | 1 + .../Retargeting/RetargetCustomModifiers.cs | 1 + .../Symbol/Symbols/Source/BaseClassTests.cs | 1 + .../Symbols/Source/CustomModifierCopyTests.cs | 1 + .../Test/Symbol/Symbols/Source/EventTests.cs | 1 + .../Test/Symbol/Symbols/Source/FieldTests.cs | 1 + .../Symbols/Source/NullablePublicAPITests.cs | 1 + .../Symbol/Symbols/Source/UsingAliasTests.cs | 1 + .../Syntax/Syntax/LambdaUtilitiesTests.cs | 1 + .../WinRT/CodeGen/WinRTCollectionTests.cs | 1 + .../Utilities/CSharp/CompilationTestUtils.cs | 1 + .../Test/Utilities/CSharp/SymbolUtilities.cs | 8 +-- .../Test/Utilities/VisualBasic/Extensions.vb | 7 --- .../Emit/Attributes/AssemblyAttributes.vb | 1 + .../Test/Emit/Attributes/AttributeTests.vb | 1 + .../Attributes/AttributeTests_Synthesized.vb | 1 + .../Emit/Attributes/AttributeTests_Tuples.vb | 1 + .../AttributeTests_WellKnownAttributes.vb | 1 + .../Test/Emit/CodeGen/CodeGenEvents.vb | 1 + .../Emit/CodeGen/CodeGenRefReturnTests.vb | 1 + .../Test/Emit/CodeGen/CodeGenTuples.vb | 1 + .../Test/Emit/CodeGen/CodeGenVBCore.vb | 1 + .../Test/Emit/CodeGen/WinRTCollectionTests.vb | 1 + .../Test/Emit/Emit/CompilationEmitTests.vb | 1 + .../EditAndContinueClosureTests.vb | 1 + .../EditAndContinueStateMachineTests.vb | 1 + .../EditAndContinue/SymbolMatcherTests.vb | 1 + .../Test/Emit/Emit/EmitMetadata.vb | 1 + .../Test/Emit/Emit/NoPiaEmbedTypes.vb | 1 + .../Binding/Binder_Expressions_Tests.vb | 1 + .../BindingCollectionInitializerTests.vb | 1 + .../Semantic/Binding/BindingErrorTests.vb | 1 + .../Test/Semantic/Binding/ForEachTests.vb | 1 + .../Semantic/Binding/ImplicitVariableTests.vb | 1 + .../Test/Semantic/Binding/LookupTests.vb | 1 + .../Binding/MethodBodyBindingTests.vb | 1 + .../Compilation/CompilationAPITests.vb | 1 + .../Semantic/Compilation/MyTemplateTests.vb | 1 + .../Compilation/SemanticModelAPITests.vb | 1 + .../SemanticModelGetDeclaredSymbolAPITests.vb | 3 +- .../SemanticModelLookupSymbolsAPITests.vb | 1 + .../ExtensionMethods/SemanticModelTests.vb | 1 + .../FlowAnalysis/RegionAnalysisTests.vb | 1 + .../RegionAnalysisTestsWithStaticLocals.vb | 1 + .../Semantic/Semantics/ArrayLiteralTests.vb | 1 + .../Test/Semantic/Semantics/AsyncAwait.vb | 1 + .../Semantic/Semantics/BinaryOperators.vb | 1 + .../Semantic/Semantics/CompoundAssignment.vb | 1 + .../Semantics/ConditionalAccessTests.vb | 1 + .../Semantics/ConditionalExpressionsTests.vb | 1 + .../Conversions_AnonymousDelegates.vb | 1 + .../Semantics/GetExtendedSemanticInfoTests.vb | 1 + .../Semantics/GetSemanticInfoTests.vb | 1 + .../Test/Semantic/Semantics/GotoTests.vb | 1 + .../Semantics/LambdaSemanticInfoTests.vb | 1 + .../Lambda_AnonymousDelegateInference.vb | 1 + .../Semantic/Semantics/Lambda_Relaxation.vb | 1 + .../Semantics/MeMyBaseMyClassTests.vb | 1 + .../Semantics/MultiDimensionalTest.vb | 1 + .../Test/Semantic/Semantics/NameOfTests.vb | 1 + .../Semantic/Semantics/NewOnInterfaceTests.vb | 1 + .../NonTrailingNamedArgumentsTests.vb | 1 + .../Semantics/OptionalArgumentTests.vb | 1 + .../Semantic/Semantics/OverloadResolution.vb | 1 + .../Test/Semantic/Semantics/Parenthesized.vb | 1 + .../Semantic/Semantics/PartialMethodsTest.vb | 1 + .../QueryExpressions_LookupSymbols.vb | 1 + .../QueryExpressions_SemanticModel.vb | 1 + .../Semantics/ScriptSemanticsTests.vb | 1 + .../Semantic/Semantics/SelectCaseTests.vb | 1 + .../Test/Semantic/Semantics/SyncLockTests.vb | 1 + .../Test/Semantic/Semantics/UnaryOperators.vb | 1 + .../Semantics/UserDefinedBinaryOperators.vb | 1 + .../Semantics/UserDefinedConversions.vb | 1 + .../Semantics/UserDefinedUnaryOperators.vb | 1 + .../Semantics/VariableTypeInference.vb | 1 + .../Semantics/WithBlockSemanticModelTests.vb | 1 + .../Semantics/XmlLiteralSemanticModelTests.vb | 1 + .../DocumentationComments/DocCommentTests.vb | 1 + .../SymbolDisplay/SymbolDisplayTests.vb | 1 + .../AnonymousDelegates_CreationAndEmit.vb | 1 + .../AnonymousTypesSemanticsTests.vb | 1 + .../SymbolsTests/AssemblyAndNamespaceTests.vb | 1 + .../SymbolsTests/CompilationCreationTests.vb | 1 + .../SymbolsTests/CustomModifiersTests.vb | 1 + .../DefaultInterfaceImplementationTests.vb | 1 + .../SymbolsTests/InstantiatingGenerics.vb | 1 + .../Metadata/MetadataMemberTests.vb | 1 + .../Metadata/MetadataTypeTests.vb | 1 + .../Metadata/PE/BaseTypeResolution.vb | 1 + .../Metadata/PE/HasUnsupportedMetadata.vb | 1 + .../Metadata/PE/LoadCustomModifiers.vb | 1 + .../SymbolsTests/Metadata/PE/LoadingEvents.vb | 1 + .../PE/LoadingGenericTypeParameters.vb | 1 + .../Metadata/PE/LoadingMethods.vb | 1 + .../Metadata/PE/LoadingNamespacesAndTypes.vb | 1 + .../Metadata/PE/LoadingOperators.vb | 1 + .../Metadata/PE/MissingTypeReferences.vb | 1 + .../Symbol/SymbolsTests/Metadata/PE/NoPia.vb | 1 + .../NoPiaLocalHideAndTypeSubstitutionTests.vb | 1 + .../Metadata/PE/TypeForwarders.vb | 1 + .../Symbol/SymbolsTests/MockSymbolTests.vb | 1 + .../Symbol/SymbolsTests/Retargeting/NoPia.vb | 1 + .../Retargeting/RetargetCustomModifiers.vb | 1 + .../Retargeting/RetargetingTests.vb | 1 + .../SymbolsTests/Source/BindingsTests.vb | 1 + .../SymbolsTests/Source/ClsComplianceTests.vb | 1 + .../SymbolsTests/Source/ComClassTests.vb | 1 + .../Symbol/SymbolsTests/Source/EventTests.vb | 1 + .../Symbol/SymbolsTests/Source/FieldTests.vb | 1 + .../SymbolsTests/Source/GroupClassTests.vb | 1 + .../SymbolsTests/Source/ImplementsTests.vb | 1 + .../Symbol/SymbolsTests/Source/MethodTests.vb | 1 + .../SymbolsTests/Source/OperatorsTests.vb | 1 + .../SymbolsTests/Source/OverridesTests.vb | 1 + .../SymbolsTests/Source/SourceSymbolTests.vb | 1 + .../Source/SyntheticEntryPoint.vb | 1 + .../SymbolsTests/Source/TypeBindingTests.vb | 1 + .../Source/TypeSubstitutionTests.vb | 1 + .../Symbol/SymbolsTests/Source/TypeTests.vb | 1 + .../Symbol/SymbolsTests/SymbolErrorTests.vb | 1 + .../Symbol/SymbolsTests/UnboundGenericType.vb | 1 + .../SymbolsTests/WithStatementSymbolsTests.vb | 1 + .../EditAndContinue/TopLevelEditingTests.cs | 1 + .../EditAndContinue/RudeEditTopLevelTests.vb | 1 + .../Test/ExpressionCompiler/DteeTests.vb | 1 + .../Test/ExpressionCompiler/HoistedMeTests.vb | 1 + .../ImportDebugInfoTests.vb | 1 + 198 files changed, 234 insertions(+), 50 deletions(-) diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs index 80124d3a674da..ecafaa59f5743 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Dynamic.cs b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Dynamic.cs index ef3e53ade5239..b28bf9ab1ffb9 100644 --- a/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Dynamic.cs +++ b/src/Compilers/CSharp/Test/Emit/Attributes/AttributeTests_Dynamic.cs @@ -7,6 +7,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs index 23aa0898e705b..6776eb631b0cf 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs @@ -9,6 +9,7 @@ using System.Text; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs index 2cebfd3daa165..4221d557ca10a 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAwaitForeachTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs index a10027ec44b21..570c643ea14c4 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenDeconstructTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs index 6e4dcc5c84377..b5d2d8648c457 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenLocalFunctionTests.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefLocalTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefLocalTests.cs index 69fd0ced9df26..db0f1e3399bc5 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefLocalTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenRefLocalTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs index a2d2bff2f71bb..48e33b0268901 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleEqualityTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs index cca1eb8355dcc..899573d34540d 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EmitMetadataTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EmitMetadataTests.cs index 12dc974bd644b..bc6e135b3208f 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/EmitMetadataTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/EmitMetadataTests.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IBinaryOperatorExpression.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IBinaryOperatorExpression.cs index b99729106c562..5a5bd6623df53 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IBinaryOperatorExpression.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IBinaryOperatorExpression.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IVariableDeclaration.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IVariableDeclaration.cs index 507d997e4010f..7b72a1ae9570b 100644 --- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IVariableDeclaration.cs +++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_IVariableDeclaration.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Operations; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/RegionAnalysisTests.cs b/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/RegionAnalysisTests.cs index bada442325b3d..dd20e2a29e5e4 100644 --- a/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/RegionAnalysisTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/FlowAnalysis/RegionAnalysisTests.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs index 640922d1332b3..fa2b5624aaa0a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/AwaitExpressionTests.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs index 71138a4f3f28b..518bf24d1b16e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BetterCandidates.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs index 0391ad1bd3cbc..367e5b24d1d6b 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ColorColorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ColorColorTests.cs index aa6843c61be00..5a97b7a9e8510 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ColorColorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ColorColorTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ConditionalOperatorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ConditionalOperatorTests.cs index 6b2a95704df29..c4e49667e8143 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ConditionalOperatorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ConditionalOperatorTests.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs index 6296dfa2ace73..52578b1230e0c 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DeconstructionTests.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs index 9cc7d1f4cf6eb..2becb444180a7 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/DynamicTests.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; namespace Microsoft.CodeAnalysis.CSharp.UnitTests diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs index 71a21cff795a0..cd58cd28a104f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ExpressionBodiedMemberTests.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.UnitTests; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs index e55592f14c668..78e76d237af7c 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ForEachTests.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs index 0e1390c46d0e5..43d1997792802 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/GenericConstraintsTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.UnitTests; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ImplicitlyTypeArraysTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ImplicitlyTypeArraysTests.cs index c7717b42ea221..0c528475cbd42 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ImplicitlyTypeArraysTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ImplicitlyTypeArraysTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs index 5a66930764189..5559d221cb762 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/IndexAndRangeTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs index 037a541adf615..e52d6116bb05f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InteractiveSemanticModelTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs index 8905951b7eefe..d950216c6994e 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/IteratorTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Symbols; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using System.Linq; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaDiscardParametersTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaDiscardParametersTests.cs index 5a7e91d98c124..540845a7483f1 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaDiscardParametersTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaDiscardParametersTests.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs index 4f3519abc4515..c7013a68422ed 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LambdaTests.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs index 65e6fe3c6c022..27b0ca2ed10b6 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LocalFunctionTests.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using System; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs index 9d14e4fb4702c..e7bed0804e234 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LookupPositionTests.cs @@ -6,9 +6,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; @@ -1663,7 +1663,7 @@ private static SemanticModel GetModelAndKeyPositions(string markedText, out int[ /// private static void CheckSymbols(SemanticModel model, int keyPositionNum, int position, IEnumerable expectedSymbols) { - var actualSymbols = model.LookupSymbols(position).Select(SymbolUtilities.ToTestDisplayString).ToArray(); + var actualSymbols = model.LookupSymbols(position).Select(SymbolExtensions.ToTestDisplayString).ToArray(); Array.Sort(actualSymbols); SyntaxToken token = model.SyntaxTree.GetCompilationUnitRoot().FindToken(position, findInsideTrivia: true); diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/LookupTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/LookupTests.cs index 8254cdcdb8e0a..c0c01bdc77a88 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/LookupTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/LookupTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/MethodTypeInferenceTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/MethodTypeInferenceTests.cs index 80d61fbd6159f..6017f2bf806a1 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/MethodTypeInferenceTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/MethodTypeInferenceTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/MultiDimensionalArrayTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/MultiDimensionalArrayTests.cs index e92c43856a08a..bd9e707355864 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/MultiDimensionalArrayTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/MultiDimensionalArrayTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs index 866b28a6005d4..46af5e9b324d2 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs index cb98431710dcd..0b6fcf2121fa3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs index ec1702e2ca27e..b4359d2faaaf3 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullableReferenceTypesTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs index 383edbc7cbdc2..2ac87705f24b1 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ObjectAndCollectionInitializerTests.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OperatorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OperatorTests.cs index 912d7620e4307..d4d0f718ca364 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OperatorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OperatorTests.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Xunit; using Roslyn.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; namespace Microsoft.CodeAnalysis.CSharp.UnitTests diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs index 9a7f0a52a8c58..9e1a8096b18cc 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OutVarTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs index 1b2485ec5699e..9580d8eac9744 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/OverloadResolutionTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs index 0d9ee98208940..4f988b215f128 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs index 75feacc948cca..93ee81e61d771 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests2.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs index f1c621a338c17..1d0eb57955e5d 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests3.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests4.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests4.cs index 13eac97d90454..c02ee562b7b51 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests4.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests4.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Global.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Global.cs index 53e66828f36de..373049206ee32 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Global.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Global.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs index 1121fc2691ec4..67b6e1db6ff61 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternMatchingTests_Scope.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs index 2828780e5ff99..f82491a5dfe5a 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/PatternSwitchTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs index 126d45d4b240e..fb6c3a337e994 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/QueryTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs index edf274cadbd92..3b678cea2ad7c 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/ScriptSemanticsTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs index 387981fe986a6..f1782fb532dd2 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SemanticErrorTests.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs index 1968057bc2601..0747aea787058 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/StackAllocInitializerTests.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedDefaultTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedDefaultTests.cs index c50aef5fc3951..dc5688bcd10b2 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedDefaultTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedDefaultTests.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using System.Linq; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedObjectCreationTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedObjectCreationTests.cs index f7ae93a363438..0a9f229e4d5d5 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedObjectCreationTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/TargetTypedObjectCreationTests.cs @@ -6,6 +6,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/TypeOfTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/TypeOfTests.cs index 2f32607634dea..e19e0b8e8b724 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/TypeOfTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/TypeOfTests.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; using System.Linq; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs index 612bdad1da40e..324864165b8bd 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UnsafeTests.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs index 834006dbd9abe..ee9de19567bda 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/UsingStatementTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs index d1b00dfd7a51b..b3af847b28ae9 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/GetSemanticInfoTests.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/IndexedProperties_BindingTests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/IndexedProperties_BindingTests.cs index 708bcf2a01b48..d64c4b655d973 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/IndexedProperties_BindingTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/IndexedProperties_BindingTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs index be9b41058b837..8096c26c33df6 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelAPITests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs index f38a6acc4a256..1dc92a1972d2d 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetDeclaredSymbolAPITests.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests.cs index 64368d7ef32a2..a1683f9ff8367 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests.cs @@ -7,6 +7,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs index ab1eb83761710..21a5b2839f7c1 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/SemanticModelGetSemanticInfoTests_LateBound.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/CrefTests.cs b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/CrefTests.cs index 4f49014613365..e3a0adc328530 100644 --- a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/CrefTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/CrefTests.cs @@ -9,9 +9,11 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; +using SymbolExtensions = Microsoft.CodeAnalysis.Test.Extensions.SymbolExtensions; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { @@ -3347,7 +3349,7 @@ private class Inner { } int position = source.IndexOf("{U}", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(position).Select(SymbolUtilities.ToTestDisplayString), + AssertEx.SetEqual(model.LookupSymbols(position).Select(SymbolExtensions.ToTestDisplayString), // Implicit type parameter "U", diff --git a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/ParameterTests.cs b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/ParameterTests.cs index 7652ecf921981..6322924a7debe 100644 --- a/src/Compilers/CSharp/Test/Symbol/DocumentationComments/ParameterTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/DocumentationComments/ParameterTests.cs @@ -8,9 +8,11 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; +using SymbolExtensions = Microsoft.CodeAnalysis.Test.Extensions.SymbolExtensions; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { @@ -406,10 +408,10 @@ class C int pos3 = source.IndexOf("pos3", StringComparison.Ordinal); int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString), "T"); - AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolUtilities.ToTestDisplayString), "T"); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString), "T"); + AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolExtensions.ToTestDisplayString), "T"); } [Fact] @@ -433,10 +435,10 @@ void M(int x) { } int pos3 = source.IndexOf("pos3", StringComparison.Ordinal); int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 x"); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 x"); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString), "T"); - AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolUtilities.ToTestDisplayString), "T"); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 x"); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 x"); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString), "T"); + AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolExtensions.ToTestDisplayString), "T"); } [Fact] @@ -460,10 +462,10 @@ class C int pos3 = source.IndexOf("pos3", StringComparison.Ordinal); int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 value"); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 value"); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolUtilities.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 value"); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 value"); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolExtensions.ToTestDisplayString)); } [Fact] @@ -487,10 +489,10 @@ class C int pos3 = source.IndexOf("pos3", StringComparison.Ordinal); int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolUtilities.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolExtensions.ToTestDisplayString)); } [Fact] @@ -514,10 +516,10 @@ class C int pos3 = source.IndexOf("pos3", StringComparison.Ordinal); int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 x", "System.Int32 value"); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 x", "System.Int32 value"); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolUtilities.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 x", "System.Int32 value"); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 x", "System.Int32 value"); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolExtensions.ToTestDisplayString)); } [Fact] @@ -541,10 +543,10 @@ class C int pos3 = source.IndexOf("pos3", StringComparison.Ordinal); int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 x"); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString), "System.Int32 x"); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolUtilities.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 x"); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString), "System.Int32 x"); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos4).Select(SymbolExtensions.ToTestDisplayString)); } [Fact] @@ -569,9 +571,9 @@ event System.Action E { add { } remove { } } int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); // As in Dev11, we do not consider the value parameter. - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString)); AssertEx.SetEqual(model.LookupSymbols(pos4), compilation.GlobalNamespace.GetMember("C").TypeParameters.Single()); } @@ -597,9 +599,9 @@ class C int pos4 = source.IndexOf("pos4", StringComparison.Ordinal); // As in Dev11, we do not consider the value parameter. - AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolUtilities.ToTestDisplayString)); - AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolUtilities.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos1).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos2).Select(SymbolExtensions.ToTestDisplayString)); + AssertEx.SetEqual(model.LookupSymbols(pos3).Select(SymbolExtensions.ToTestDisplayString)); AssertEx.SetEqual(model.LookupSymbols(pos4), compilation.GlobalNamespace.GetMember("C").TypeParameters.Single()); } diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs index cab31fa477cad..740179b35b591 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/AnonymousTypesSemanticsTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs index e0bb837e2e7ad..8249b183bcf96 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/CustomModifiersTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/ExtensionMethodTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/ExtensionMethodTests.cs index 777a7e215c82a..36a18ee244243 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/ExtensionMethodTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/ExtensionMethodTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/IndexerTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/IndexerTests.cs index f753e66679ca2..de5d026e8d281 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/IndexerTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/IndexerTests.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; @@ -2543,11 +2544,11 @@ public void M() {} } "; var compilation = CreateCompilation(new string[] { text1, text2 }); - Assert.True(((TypeSymbol)compilation.GlobalNamespace.GetTypeMembers("C").Single()).GetMembers().Any(x => SymbolExtensions.IsIndexer(x))); + Assert.True(((TypeSymbol)compilation.GlobalNamespace.GetTypeMembers("C").Single()).GetMembers().Any(x => x.IsIndexer())); //test with text inputs reversed in case syntax ordering predicate ever changes. compilation = CreateCompilation(new string[] { text2, text1 }); - Assert.True(((TypeSymbol)compilation.GlobalNamespace.GetTypeMembers("C").Single()).GetMembers().Any(x => SymbolExtensions.IsIndexer(x))); + Assert.True(((TypeSymbol)compilation.GlobalNamespace.GetTypeMembers("C").Single()).GetMembers().Any(x => x.IsIndexer())); } [WorkItem(543957, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543957")] diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadCustomModifiers.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadCustomModifiers.cs index 4a28f3ae7be57..d6ca401b1da97 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadCustomModifiers.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadCustomModifiers.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadingFields.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadingFields.cs index da7db4a8cd260..6dd976b1b9069 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadingFields.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Metadata/PE/LoadingFields.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using System.Linq; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/RetargetCustomModifiers.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/RetargetCustomModifiers.cs index 46443ddc82cf9..4e28426bc92f1 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/RetargetCustomModifiers.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Retargeting/RetargetCustomModifiers.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs index 964a0f2587d75..cdd3aff59338a 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/BaseClassTests.cs @@ -11,6 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/CustomModifierCopyTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/CustomModifierCopyTests.cs index a906e1efb034c..16216bda925d0 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/CustomModifierCopyTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/CustomModifierCopyTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs index 351cb8aa36cbd..c756c8049e148 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/EventTests.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using System; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FieldTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FieldTests.cs index 305cf5bed28d3..5f13acd640139 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FieldTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/FieldTests.cs @@ -6,6 +6,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs index f18e2041d6c24..d93e5574e4761 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs index 76f3a8bad3e9b..f39a9827c09d9 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/UsingAliasTests.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using System.Linq; diff --git a/src/Compilers/CSharp/Test/Syntax/Syntax/LambdaUtilitiesTests.cs b/src/Compilers/CSharp/Test/Syntax/Syntax/LambdaUtilitiesTests.cs index 96eae7ed24184..7adda664dbfaf 100644 --- a/src/Compilers/CSharp/Test/Syntax/Syntax/LambdaUtilitiesTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Syntax/LambdaUtilitiesTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/WinRT/CodeGen/WinRTCollectionTests.cs b/src/Compilers/CSharp/Test/WinRT/CodeGen/WinRTCollectionTests.cs index 0309d95202cec..313cb155db164 100644 --- a/src/Compilers/CSharp/Test/WinRT/CodeGen/WinRTCollectionTests.cs +++ b/src/Compilers/CSharp/Test/WinRT/CodeGen/WinRTCollectionTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/Test/Utilities/CSharp/CompilationTestUtils.cs b/src/Compilers/Test/Utilities/CSharp/CompilationTestUtils.cs index 6f4aba8eefd60..62b547db461ea 100644 --- a/src/Compilers/Test/Utilities/CSharp/CompilationTestUtils.cs +++ b/src/Compilers/Test/Utilities/CSharp/CompilationTestUtils.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; diff --git a/src/Compilers/Test/Utilities/CSharp/SymbolUtilities.cs b/src/Compilers/Test/Utilities/CSharp/SymbolUtilities.cs index 464548090b5dd..705e5566104b4 100644 --- a/src/Compilers/Test/Utilities/CSharp/SymbolUtilities.cs +++ b/src/Compilers/Test/Utilities/CSharp/SymbolUtilities.cs @@ -8,6 +8,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Extensions; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests @@ -89,13 +90,6 @@ public static string ListToSortedString(this List listOfSymbol return text; } - // TODO: Remove this method and fix callsites to directly invoke Microsoft.CodeAnalysis.Test.Extensions.SymbolExtensions.ToTestDisplayString(). - // https://github.com/dotnet/roslyn/issues/11915 - public static string ToTestDisplayString(this ISymbol symbol) - { - return CodeAnalysis.Test.Extensions.SymbolExtensions.ToTestDisplayString(symbol); - } - private static SymbolDisplayFormat GetDisplayFormat(bool includeNonNullable) { var format = SymbolDisplayFormat.TestFormat; diff --git a/src/Compilers/Test/Utilities/VisualBasic/Extensions.vb b/src/Compilers/Test/Utilities/VisualBasic/Extensions.vb index e4494bd4c929a..84d195eff1126 100644 --- a/src/Compilers/Test/Utilities/VisualBasic/Extensions.vb +++ b/src/Compilers/Test/Utilities/VisualBasic/Extensions.vb @@ -21,13 +21,6 @@ Friend Module Extensions Return DirectCast(compilation.GetAssemblyOrModuleSymbol(reference), ModuleSymbol) End Function - ' TODO: Remove this method and fix callsites to directly invoke Microsoft.CodeAnalysis.Test.Extensions.SymbolExtensions.ToTestDisplayString(). - ' https://github.com/dotnet/roslyn/issues/11915 - - Public Function ToTestDisplayString(symbol As ISymbol) As String - Return Test.Extensions.SymbolExtensions.ToTestDisplayString(symbol) - End Function - Private Function SplitMemberName(qualifiedName As String) As ImmutableArray(Of String) Dim builder = ArrayBuilder(Of String).GetInstance() Dim curr = qualifiedName diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AssemblyAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AssemblyAttributes.vb index 5085180d99d03..fb4761e31d8f2 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AssemblyAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AssemblyAttributes.vb @@ -10,6 +10,7 @@ Imports System.Reflection.Metadata.Ecma335 Imports System.Runtime.InteropServices Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb index f616883363e51..26209d5429e1d 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests.vb @@ -8,6 +8,7 @@ Imports System.Reflection Imports System.Runtime.InteropServices Imports System.Xml.Linq Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Synthesized.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Synthesized.vb index 8486312789ba7..cab83941fa82b 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Synthesized.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Synthesized.vb @@ -7,6 +7,7 @@ Imports System.IO Imports System.Linq Imports System.Runtime.CompilerServices Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Tuples.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Tuples.vb index ab4ef1f491337..463da0aee5f3a 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Tuples.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_Tuples.vb @@ -7,6 +7,7 @@ Imports System.Reflection Imports System.Reflection.Metadata Imports System.Xml.Linq Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb index 5a0d76947435e..2109491469205 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/AttributeTests_WellKnownAttributes.vb @@ -9,6 +9,7 @@ Imports System.Reflection.Metadata.Ecma335 Imports System.Runtime.InteropServices Imports System.Text Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenEvents.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenEvents.vb index a05db981249ea..7e4d120cb2a6d 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenEvents.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenEvents.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenRefReturnTests.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenRefReturnTests.vb index 301b81d6a7d17..9a6214bc95a00 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenRefReturnTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenRefReturnTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb index 6407438c2ff64..5b2c82dbd3a0f 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Text Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenVBCore.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenVBCore.vb index 7e9b674b5116f..6a644110071e0 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenVBCore.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenVBCore.vb @@ -6,6 +6,7 @@ Imports System.IO Imports System.Text Imports System.Text.RegularExpressions Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Emit/CodeGen/WinRTCollectionTests.vb b/src/Compilers/VisualBasic/Test/Emit/CodeGen/WinRTCollectionTests.vb index 3289f03205f6e..b8aafd706868c 100644 --- a/src/Compilers/VisualBasic/Test/Emit/CodeGen/WinRTCollectionTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/CodeGen/WinRTCollectionTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb index 9b4221d2bdb97..65f1af4ea8c42 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/CompilationEmitTests.vb @@ -10,6 +10,7 @@ Imports System.Reflection.PortableExecutable Imports System.Text Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Emit diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb index 1e1e3abbe0b7d..341663567d292 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Reflection.Metadata.Ecma335 Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb index 526cdf543e07a..3d2a8e8118bf8 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Reflection.Metadata.Ecma335 Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb index b43bf1c40970f..9a7d559089935 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/SymbolMatcherTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Emit diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EmitMetadata.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EmitMetadata.vb index 5d8dac60012f3..a5959db2ff919 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/EmitMetadata.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EmitMetadata.vb @@ -7,6 +7,7 @@ Imports System.IO Imports System.Reflection Imports System.Reflection.Metadata Imports System.Reflection.Metadata.Ecma335 +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/NoPiaEmbedTypes.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/NoPiaEmbedTypes.vb index a0d4f7186f275..18f7608c1510b 100644 --- a/src/Compilers/VisualBasic/Test/Emit/Emit/NoPiaEmbedTypes.vb +++ b/src/Compilers/VisualBasic/Test/Emit/Emit/NoPiaEmbedTypes.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/Binder_Expressions_Tests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/Binder_Expressions_Tests.vb index 770ea965a7a17..4d32d7505680c 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/Binder_Expressions_Tests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/Binder_Expressions_Tests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingCollectionInitializerTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingCollectionInitializerTests.vb index 7a3c32a664547..acd1821288d1c 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingCollectionInitializerTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingCollectionInitializerTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb index 1f7cfcfc7ac29..8626ed1c10094 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/ForEachTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/ForEachTests.vb index 8d0f23bda5b56..5f719cb8ea229 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/ForEachTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/ForEachTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.Linq.Enumerable Imports System.Xml.Linq Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/ImplicitVariableTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/ImplicitVariableTests.vb index 9995a32e4dfeb..a970cd4b71ce4 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/ImplicitVariableTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/ImplicitVariableTests.vb @@ -8,6 +8,7 @@ Imports System.IO Imports System.Linq Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/LookupTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/LookupTests.vb index dd71f03f85ec5..63902151eb750 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/LookupTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/LookupTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Semantic/Binding/MethodBodyBindingTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Binding/MethodBodyBindingTests.vb index fc77b733f0691..f0ed62d3c5e11 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Binding/MethodBodyBindingTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Binding/MethodBodyBindingTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb index d76eb8009a754..cb78c73bae602 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb @@ -12,6 +12,7 @@ Imports System.Threading Imports System.Xml.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/MyTemplateTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/MyTemplateTests.vb index cfd26df62b8f3..c055a39cb042a 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/MyTemplateTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/MyTemplateTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.ObjectModel Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelAPITests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelAPITests.vb index 856307c1a2ea2..5f988f9dbaeb5 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelAPITests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelAPITests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelGetDeclaredSymbolAPITests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelGetDeclaredSymbolAPITests.vb index 6c79eb14d6eb4..0e1824082fbbb 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelGetDeclaredSymbolAPITests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelGetDeclaredSymbolAPITests.vb @@ -6,6 +6,7 @@ Imports System.IO Imports System.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic @@ -1943,7 +1944,7 @@ End Module Assert.NotNull(label2) Assert.Equal("Label2", label2.Name) Dim symLabel = DirectCast(label1, LabelSymbol) - Assert.False(SymbolExtensions.IsOverloadable(symLabel)) + Assert.False(symLabel.IsOverloadable()) Assert.False(symLabel.IsMustOverride) Assert.False(symLabel.IsOverrides) Assert.False(symLabel.IsOverridable) diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelLookupSymbolsAPITests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelLookupSymbolsAPITests.vb index f5c395c1a4661..127ea744f6a18 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelLookupSymbolsAPITests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/SemanticModelLookupSymbolsAPITests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/ExtensionMethods/SemanticModelTests.vb b/src/Compilers/VisualBasic/Test/Semantic/ExtensionMethods/SemanticModelTests.vb index 757cbcf5bd2ee..1969e806a5504 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/ExtensionMethods/SemanticModelTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/ExtensionMethods/SemanticModelTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTests.vb b/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTests.vb index 73f9e99a6d03d..25c9faf525622 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTestsWithStaticLocals.vb b/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTestsWithStaticLocals.vb index 888d93e82eb90..43f194405a907 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTestsWithStaticLocals.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/FlowAnalysis/RegionAnalysisTestsWithStaticLocals.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ArrayLiteralTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ArrayLiteralTests.vb index 4f2b973dae59c..4ec2172c2b270 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ArrayLiteralTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ArrayLiteralTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/AsyncAwait.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/AsyncAwait.vb index c6af331b9ec95..a3779b8f0da64 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/AsyncAwait.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/AsyncAwait.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperators.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperators.vb index 0dcab3f45852e..dd5c5091b5753 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperators.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperators.vb @@ -7,6 +7,7 @@ Imports System.Text Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/CompoundAssignment.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/CompoundAssignment.vb index 5305cdaac38a4..0b4cd46641fe8 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/CompoundAssignment.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/CompoundAssignment.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalAccessTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalAccessTests.vb index 68d9e050e26d5..a8cd3ea30ae12 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalAccessTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalAccessTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalExpressionsTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalExpressionsTests.vb index eb162ae3d798e..58b71f1f7a6a1 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalExpressionsTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ConditionalExpressionsTests.vb @@ -7,6 +7,7 @@ Imports System.Xml Imports System.Xml.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions_AnonymousDelegates.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions_AnonymousDelegates.vb index 75693b2d7ce0c..43f89cba8fd97 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions_AnonymousDelegates.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Conversions_AnonymousDelegates.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetExtendedSemanticInfoTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetExtendedSemanticInfoTests.vb index bed7b429f0cf1..e42202d03bb11 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetExtendedSemanticInfoTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetExtendedSemanticInfoTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetSemanticInfoTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetSemanticInfoTests.vb index 504036b2f472f..702512923b028 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetSemanticInfoTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/GetSemanticInfoTests.vb @@ -8,6 +8,7 @@ Imports System.Linq Imports System.Runtime.CompilerServices Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/GotoTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/GotoTests.vb index f40af92603f8a..99c94e1066dcd 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/GotoTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/GotoTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaSemanticInfoTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaSemanticInfoTests.vb index f88a9cbeba79a..77a697233a6c9 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaSemanticInfoTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaSemanticInfoTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_AnonymousDelegateInference.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_AnonymousDelegateInference.vb index 92edabcf696b4..8da3e39115d01 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_AnonymousDelegateInference.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_AnonymousDelegateInference.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_Relaxation.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_Relaxation.vb index f86402d47cad1..e547493035a6d 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_Relaxation.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Lambda_Relaxation.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/MeMyBaseMyClassTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/MeMyBaseMyClassTests.vb index d636221b05f66..ef0e5a25ffbe3 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/MeMyBaseMyClassTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/MeMyBaseMyClassTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/MultiDimensionalTest.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/MultiDimensionalTest.vb index 2e9b6be642499..09653c301e895 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/MultiDimensionalTest.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/MultiDimensionalTest.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/NameOfTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/NameOfTests.vb index 42e4980c67288..d8654ce6ec1aa 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/NameOfTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/NameOfTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/NewOnInterfaceTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/NewOnInterfaceTests.vb index 7de4af0779822..2bab634c8df6b 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/NewOnInterfaceTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/NewOnInterfaceTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.vb index 95379d25cf6b8..bd382dfcc18e3 100755 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/NonTrailingNamedArgumentsTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/OptionalArgumentTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/OptionalArgumentTests.vb index a8ccf29290278..d3f2be868268f 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/OptionalArgumentTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/OptionalArgumentTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Text Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/OverloadResolution.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/OverloadResolution.vb index 773bacc826040..dd2ca4e67659b 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/OverloadResolution.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/OverloadResolution.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Parenthesized.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Parenthesized.vb index b892a14aa4f54..f256f08f060c6 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/Parenthesized.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/Parenthesized.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/PartialMethodsTest.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/PartialMethodsTest.vb index 6b320940f33dc..1f6d217489bc6 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/PartialMethodsTest.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/PartialMethodsTest.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_LookupSymbols.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_LookupSymbols.vb index ab831331033f2..f826b8f77e750 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_LookupSymbols.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_LookupSymbols.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_SemanticModel.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_SemanticModel.vb index b69ac1977f148..aad59629a2533 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_SemanticModel.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/QueryExpressions_SemanticModel.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb index 73d8a3d30c5af..c50c598fc1dab 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/SelectCaseTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/SelectCaseTests.vb index e683559139bb1..390b2b4584947 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/SelectCaseTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/SelectCaseTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyncLockTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyncLockTests.vb index e4cd28e142e6d..afc912e6e2443 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyncLockTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyncLockTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UnaryOperators.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UnaryOperators.vb index bbd6fb38bdf20..7a9eabd8579bb 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UnaryOperators.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UnaryOperators.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb index 496041616321f..11b0c6295d3fb 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedConversions.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedConversions.vb index 2220df5edddf4..e5c831c284965 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedConversions.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedConversions.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedUnaryOperators.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedUnaryOperators.vb index b3f2cf1524f34..51bb52a0f5870 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedUnaryOperators.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedUnaryOperators.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/VariableTypeInference.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/VariableTypeInference.vb index cff7328fa23d4..a4582b91b8ff9 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/VariableTypeInference.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/VariableTypeInference.vb @@ -5,6 +5,7 @@ Imports System.IO Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/WithBlockSemanticModelTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/WithBlockSemanticModelTests.vb index d8fb94e4c1571..fe49c9abd1b43 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/WithBlockSemanticModelTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/WithBlockSemanticModelTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/XmlLiteralSemanticModelTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/XmlLiteralSemanticModelTests.vb index 90a66aab6622c..7a9fe0cd4015a 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/XmlLiteralSemanticModelTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/XmlLiteralSemanticModelTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/Compilers/VisualBasic/Test/Symbol/DocumentationComments/DocCommentTests.vb b/src/Compilers/VisualBasic/Test/Symbol/DocumentationComments/DocCommentTests.vb index 2763516289974..2f2ab8644daad 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/DocumentationComments/DocCommentTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/DocumentationComments/DocCommentTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports System.Xml.Linq Imports System.Text diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolDisplay/SymbolDisplayTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolDisplay/SymbolDisplayTests.vb index 56aa6981bc6f9..18b5696263d52 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolDisplay/SymbolDisplayTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolDisplay/SymbolDisplayTests.vb @@ -7,6 +7,7 @@ Imports System.Globalization Imports System.Threading Imports System.Xml.Linq Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousDelegates/AnonymousDelegates_CreationAndEmit.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousDelegates/AnonymousDelegates_CreationAndEmit.vb index 58d1eb502bc6b..66ffc5788ae25 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousDelegates/AnonymousDelegates_CreationAndEmit.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousDelegates/AnonymousDelegates_CreationAndEmit.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Runtime.CompilerServices +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesSemanticsTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesSemanticsTests.vb index 4892e8fbb4f0b..3e6835a2829d9 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesSemanticsTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AnonymousTypes/AnonymousTypesSemanticsTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Runtime.CompilerServices Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AssemblyAndNamespaceTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AssemblyAndNamespaceTests.vb index 138f46f0b2f6b..787e19436e368 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AssemblyAndNamespaceTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/AssemblyAndNamespaceTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CompilationCreationTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CompilationCreationTests.vb index 46a0aaed815c6..0845cb3abd84d 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CompilationCreationTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CompilationCreationTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Runtime.CompilerServices Imports CompilationCreationTestHelpers +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb index 70023459bc004..c3f11cd55d83c 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/CustomModifiersTests.vb @@ -4,6 +4,7 @@ Imports System.IO Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/DefaultInterfaceImplementationTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/DefaultInterfaceImplementationTests.vb index 684d188639893..104e8e7ba8ca1 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/DefaultInterfaceImplementationTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/DefaultInterfaceImplementationTests.vb @@ -4,6 +4,7 @@ Imports System.IO Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb index 53a22e123c800..5d1309d855303 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/InstantiatingGenerics.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports System.Runtime.CompilerServices +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataMemberTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataMemberTests.vb index 049abad7d07c1..59d283764a731 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataMemberTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataMemberTests.vb @@ -4,6 +4,7 @@ Imports CompilationCreationTestHelpers Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataTypeTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataTypeTests.vb index bcf0efc64e165..8d3e90e092a00 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataTypeTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/MetadataTypeTests.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports CompilationCreationTestHelpers Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/BaseTypeResolution.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/BaseTypeResolution.vb index e2d5cd6569724..3a1550c4f0bd1 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/BaseTypeResolution.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/BaseTypeResolution.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Reflection.Metadata +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/HasUnsupportedMetadata.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/HasUnsupportedMetadata.vb index 36a4752ef4eeb..932dddc0a9eee 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/HasUnsupportedMetadata.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/HasUnsupportedMetadata.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb index fe3ea19c04404..879b8655fca76 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadCustomModifiers.vb @@ -4,6 +4,7 @@ Imports System.Runtime.CompilerServices Imports CompilationCreationTestHelpers +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingEvents.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingEvents.vb index 8b9fba62f756c..9ba31f529d9d7 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingEvents.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingEvents.vb @@ -4,6 +4,7 @@ Imports System.Runtime.CompilerServices Imports CompilationCreationTestHelpers +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingGenericTypeParameters.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingGenericTypeParameters.vb index 10f16f58bbe59..79c0e5515549a 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingGenericTypeParameters.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingGenericTypeParameters.vb @@ -5,6 +5,7 @@ Imports System.Runtime.CompilerServices Imports CompilationCreationTestHelpers Imports Microsoft.CodeAnalysis.ImmutableArrayExtensions +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb index 8f457e8d1989d..a748070e0ce69 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb @@ -5,6 +5,7 @@ Imports System.Runtime.CompilerServices Imports CompilationCreationTestHelpers Imports Microsoft.CodeAnalysis.Collections +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingNamespacesAndTypes.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingNamespacesAndTypes.vb index 9e8b1d0880024..f1e84250eb322 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingNamespacesAndTypes.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingNamespacesAndTypes.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.IO Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingOperators.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingOperators.vb index 6e0a94a3a2f59..d37aa8301fff3 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingOperators.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingOperators.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/MissingTypeReferences.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/MissingTypeReferences.vb index b21cb0abb7b4c..0f699af737923 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/MissingTypeReferences.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/MissingTypeReferences.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Runtime.CompilerServices Imports CompilationCreationTestHelpers +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPia.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPia.vb index 7b4129af5b0d2..e7ffa6997d726 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPia.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPia.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports CompilationCreationTestHelpers Imports Microsoft.CodeAnalysis.VisualBasic.Symbols +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPiaLocalHideAndTypeSubstitutionTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPiaLocalHideAndTypeSubstitutionTests.vb index 3eee1025b67b4..dcd43bd20ed33 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPiaLocalHideAndTypeSubstitutionTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/NoPiaLocalHideAndTypeSubstitutionTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities Imports System.Collections.Immutable diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/TypeForwarders.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/TypeForwarders.vb index 829ed3c86784f..2194355cd456f 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/TypeForwarders.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/TypeForwarders.vb @@ -5,6 +5,7 @@ Imports System.Collections.Immutable Imports System.Reflection.Metadata Imports System.Reflection.Metadata.Ecma335 +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/MockSymbolTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/MockSymbolTests.vb index a198bd82a5481..0c70f2e7f4355 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/MockSymbolTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/MockSymbolTests.vb @@ -6,6 +6,7 @@ Imports System.Runtime.InteropServices Imports System.Text Imports System.Threading Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/NoPia.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/NoPia.vb index 943bbb8d55b37..41ec5ea60652c 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/NoPia.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/NoPia.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis.VisualBasic.Symbols +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Roslyn.Test.Utilities Imports System.Xml.Linq diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetCustomModifiers.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetCustomModifiers.vb index 9016bcd553281..82464e6aa5fb5 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetCustomModifiers.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetCustomModifiers.vb @@ -7,6 +7,7 @@ Imports System.[Text] Imports System.Collections.Generic Imports System.Linq Imports Microsoft.CodeAnalysis.Collections +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb index 727c2d4ce77b6..753b0c96606db 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BindingsTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BindingsTests.vb index ddad599cbdcac..3dbbc75a225b7 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BindingsTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/BindingsTests.vb @@ -6,6 +6,7 @@ Imports System.Collections.Immutable Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ClsComplianceTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ClsComplianceTests.vb index ec13f7c047527..dd58d0735b727 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ClsComplianceTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ClsComplianceTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ComClassTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ComClassTests.vb index 2c1360c763902..b519296a203c6 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ComClassTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ComClassTests.vb @@ -7,6 +7,7 @@ Imports System.Reflection.Metadata Imports System.Reflection.Metadata.Ecma335 Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/EventTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/EventTests.vb index b2b76a7ce6ef4..1daecab223c5f 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/EventTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/EventTests.vb @@ -9,6 +9,7 @@ Imports System.Runtime.CompilerServices Imports System.Runtime.InteropServices Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/FieldTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/FieldTests.vb index 5e6501abc2126..6977ac38dab73 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/FieldTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/FieldTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/GroupClassTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/GroupClassTests.vb index 9815374f30f1f..bbce174c51440 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/GroupClassTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/GroupClassTests.vb @@ -2,6 +2,7 @@ ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ImplementsTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ImplementsTests.vb index 0e857c0a6eccd..e2994e7c3cfcb 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ImplementsTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/ImplementsTests.vb @@ -6,6 +6,7 @@ Imports System Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/MethodTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/MethodTests.vb index 18765bbb8d50d..af5cc1fa19b0d 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/MethodTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/MethodTests.vb @@ -6,6 +6,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OperatorsTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OperatorsTests.vb index 9cfe163bb5f5b..8d3a031fee221 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OperatorsTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OperatorsTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb index 472022b8150a3..cfe84e3692258 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/OverridesTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SourceSymbolTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SourceSymbolTests.vb index 19637990cd712..6a38e028ab162 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SourceSymbolTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SourceSymbolTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SyntheticEntryPoint.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SyntheticEntryPoint.vb index ba8bfbda4e7b8..d9ef57420529a 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SyntheticEntryPoint.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/SyntheticEntryPoint.vb @@ -6,6 +6,7 @@ Imports System.IO Imports System.Xml.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.SpecialType +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeBindingTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeBindingTests.vb index 037b94f467240..068ce2cf5e9df 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeBindingTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeBindingTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeSubstitutionTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeSubstitutionTests.vb index c188f4da72bf9..ee518b96a53c6 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeSubstitutionTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeSubstitutionTests.vb @@ -5,6 +5,7 @@ Imports System.Globalization Imports System.Text Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeTests.vb index ec380a1e6f55a..4ac595c454d66 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Source/TypeTests.vb @@ -3,6 +3,7 @@ ' See the LICENSE file in the project root for more information. Imports System.Collections.Immutable +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/SymbolErrorTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/SymbolErrorTests.vb index 3f24ebed06750..9ba5ef536e871 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/SymbolErrorTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/SymbolErrorTests.vb @@ -4,6 +4,7 @@ Imports System.Collections.Immutable Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb index 907ce715089fc..7e1667093c2db 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/UnboundGenericType.vb @@ -4,6 +4,7 @@ Imports System.Runtime.CompilerServices Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WithStatementSymbolsTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WithStatementSymbolsTests.vb index 9c5d0fbc9c884..c67d137abc5db 100644 --- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WithStatementSymbolsTests.vb +++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/WithStatementSymbolsTests.vb @@ -4,6 +4,7 @@ Imports System.Runtime.CompilerServices Imports System.Xml.Linq +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs index 8680967ff3a85..0f91daba7bd1e 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.EditAndContinue.UnitTests; using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.Test.Extensions; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/EditorFeatures/VisualBasicTest/EditAndContinue/RudeEditTopLevelTests.vb b/src/EditorFeatures/VisualBasicTest/EditAndContinue/RudeEditTopLevelTests.vb index a6021b87a8c90..db18661d9b598 100644 --- a/src/EditorFeatures/VisualBasicTest/EditAndContinue/RudeEditTopLevelTests.vb +++ b/src/EditorFeatures/VisualBasicTest/EditAndContinue/RudeEditTopLevelTests.vb @@ -5,6 +5,7 @@ Imports Microsoft.CodeAnalysis.EditAndContinue Imports Microsoft.CodeAnalysis.EditAndContinue.UnitTests Imports Microsoft.CodeAnalysis.Emit +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DteeTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DteeTests.vb index 58418fe152979..64c57a1089e39 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DteeTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/DteeTests.vb @@ -8,6 +8,7 @@ Imports System.Threading Imports Microsoft.CodeAnalysis.Debugging Imports Microsoft.CodeAnalysis.ExpressionEvaluator Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests Imports Roslyn.Test.PdbUtilities diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/HoistedMeTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/HoistedMeTests.vb index e35767335df67..554411a9c461c 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/HoistedMeTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/HoistedMeTests.vb @@ -7,6 +7,7 @@ Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.ExpressionEvaluator Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests Imports Microsoft.CodeAnalysis.PooledObjects +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.UnitTests diff --git a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ImportDebugInfoTests.vb b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ImportDebugInfoTests.vb index 37d26a7cc7a0a..960391ebf9e6e 100644 --- a/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ImportDebugInfoTests.vb +++ b/src/ExpressionEvaluator/VisualBasic/Test/ExpressionCompiler/ImportDebugInfoTests.vb @@ -9,6 +9,7 @@ Imports Microsoft.CodeAnalysis.CodeGen Imports Microsoft.CodeAnalysis.Debugging Imports Microsoft.CodeAnalysis.Emit Imports Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests +Imports Microsoft.CodeAnalysis.Test.Extensions Imports Microsoft.CodeAnalysis.Test.Utilities Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax From bca9b9fbb3196a413140cfba244f87011255c187 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 10:56:56 -0700 Subject: [PATCH 207/222] Fix --- src/Workspaces/CoreTest/SymbolKeyTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Workspaces/CoreTest/SymbolKeyTests.cs b/src/Workspaces/CoreTest/SymbolKeyTests.cs index 478340c7b2437..b9419cef5e785 100644 --- a/src/Workspaces/CoreTest/SymbolKeyTests.cs +++ b/src/Workspaces/CoreTest/SymbolKeyTests.cs @@ -223,7 +223,7 @@ public void M(C c) { } public A GetA(A a) { return a; } public A GetA(A a, B b) { return a; } public B GetB(A a, B b) { return b; } - publi C GetC() { return default(C); } + public C GetC() { return default(C); } } public class C @@ -699,7 +699,7 @@ object LocalFunction() Assert.NotNull(found); // note: we don't check that the symbols are equal. That's because the compiler - // doesn't guarantee that the TypeParameters will be hte same across successive + // doesn't guarantee that the TypeParameters will be the same across successive // invocations. Assert.Equal(symbol.OriginalDefinition, found.OriginalDefinition); @@ -736,7 +736,7 @@ void Method((C, int) t) // Validate that if the client does ask to resolve locations that we // do not crash if those locations cannot be found. - var found = SymbolKey.ResolveString(id, compilation2, resolveLocations: true).GetAnySymbol(); + var found = SymbolKey.ResolveString(id, compilation2).GetAnySymbol(); Assert.NotNull(found); Assert.Equal(symbol.Name, found.Name); @@ -773,7 +773,7 @@ void Method((C a, int b) t) // Validate that if the client does ask to resolve locations that we // do not crash if those locations cannot be found. - var found = SymbolKey.ResolveString(id, compilation2, resolveLocations: true).GetAnySymbol(); + var found = SymbolKey.ResolveString(id, compilation2).GetAnySymbol(); Assert.NotNull(found); Assert.Equal(symbol.Name, found.Name); From d9749bdce8e49322503c8b7c426456393e639d8f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 11:21:18 -0700 Subject: [PATCH 208/222] NRT much of the rename core. --- .../Portable/Rename/ConflictResolution.cs | 4 +- .../Core/Portable/Rename/IRemoteRenamer.cs | 78 +++++++++++-------- .../Rename/IRenameRewriterLanguageService.cs | 2 + .../RenameLocation.ReferenceProcessing.cs | 45 +++++++---- .../Core/Portable/Rename/RenameLocation.cs | 4 +- .../Rename/RenameLocations.SearchResult.cs | 4 + .../Core/Portable/Rename/RenameLocations.cs | 4 +- .../Core/Portable/Rename/Renamer.cs | 14 ++-- 8 files changed, 96 insertions(+), 59 deletions(-) diff --git a/src/Workspaces/Core/Portable/Rename/ConflictResolution.cs b/src/Workspaces/Core/Portable/Rename/ConflictResolution.cs index b73182d59d65f..0904d3081df01 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictResolution.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictResolution.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Immutable; using Microsoft.CodeAnalysis.Rename.ConflictEngine; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -12,7 +14,7 @@ namespace Microsoft.CodeAnalysis.Rename { internal readonly partial struct ConflictResolution { - public readonly string ErrorMessage; + public readonly string? ErrorMessage; private readonly Solution _newSolutionWithoutRenamedDocument; private readonly (DocumentId documentId, string newName) _renamedDocument; diff --git a/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs b/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs index 78cc28d03af93..695df0893de2f 100644 --- a/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs +++ b/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs @@ -2,7 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -10,6 +13,7 @@ using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.Rename.ConflictEngine; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; @@ -68,36 +72,35 @@ internal class SerializableSearchResult { // We use arrays so we can represent default immutable arrays. - public SerializableRenameLocation[] Locations; - public SerializableReferenceLocation[] ImplicitLocations; - public SerializableSymbolAndProjectId[] ReferencedSymbols; + public SerializableRenameLocation[]? Locations; + public SerializableReferenceLocation[]? ImplicitLocations; + public SerializableSymbolAndProjectId[]? ReferencedSymbols; - public static SerializableSearchResult Dehydrate(Solution solution, RenameLocations.SearchResult result, CancellationToken cancellationToken) + [return: NotNullIfNotNull("result")] + public static SerializableSearchResult? Dehydrate(Solution solution, RenameLocations.SearchResult? result, CancellationToken cancellationToken) => result == null ? null : new SerializableSearchResult { - Locations = result.Locations?.Select(loc => SerializableRenameLocation.Dehydrate(loc)).ToArray(), + Locations = result.Locations.Select(loc => SerializableRenameLocation.Dehydrate(loc)).ToArray(), ImplicitLocations = result.ImplicitLocations.IsDefault ? null : result.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(), ReferencedSymbols = result.ReferencedSymbols.IsDefault ? null : result.ReferencedSymbols.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(), }; public async Task RehydrateAsync(Solution solution, CancellationToken cancellationToken) { - ImmutableHashSet locations = null; ImmutableArray implicitLocations = default; ImmutableArray referencedSymbols = default; - if (Locations != null) - { - using var _ = ArrayBuilder.GetInstance(Locations.Length, out var builder); - foreach (var loc in Locations) - builder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); + Contract.ThrowIfNull(Locations); - locations = builder.ToImmutableHashSet(); - } + using var _1 = ArrayBuilder.GetInstance(Locations.Length, out var locBuilder); + foreach (var loc in Locations) + locBuilder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); + + var locations = locBuilder.ToImmutableHashSet(); if (ImplicitLocations != null) { - using var _ = ArrayBuilder.GetInstance(ImplicitLocations.Length, out var builder); + using var _2 = ArrayBuilder.GetInstance(ImplicitLocations.Length, out var builder); foreach (var loc in ImplicitLocations) builder.Add(await loc.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); @@ -106,7 +109,7 @@ public static SerializableSearchResult Dehydrate(Solution solution, RenameLocati if (ReferencedSymbols != null) { - using var _ = ArrayBuilder.GetInstance(ReferencedSymbols.Length, out var builder); + using var _3 = ArrayBuilder.GetInstance(ReferencedSymbols.Length, out var builder); foreach (var symbol in ReferencedSymbols) builder.AddIfNotNull(await symbol.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); @@ -141,8 +144,8 @@ public static SerializableRenameLocation Dehydrate(RenameLocation location) public async Task RehydrateAsync(Solution solution, CancellationToken cancellation) { - var document = solution.GetDocument(DocumentId); - var tree = await document.GetSyntaxTreeAsync(cancellation).ConfigureAwait(false); + var document = solution.GetRequiredDocument(DocumentId); + var tree = await document.GetRequiredSyntaxTreeAsync(cancellation).ConfigureAwait(false); return new RenameLocation( CodeAnalysis.Location.Create(tree, Location), @@ -169,11 +172,14 @@ public SerializableRenameLocations Dehydrate(Solution solution, CancellationToke CommentsResult = _commentsResult.IsDefault ? null : _commentsResult.Select(r => SerializableRenameLocation.Dehydrate(r)).ToArray(), }; - internal static async Task RehydrateAsync(Solution solution, SerializableRenameLocations locations, CancellationToken cancellationToken) + internal static async Task TryRehydrateAsync(Solution solution, SerializableRenameLocations locations, CancellationToken cancellationToken) { if (locations == null) return null; + if (locations.Symbol == null) + return null; + var symbol = await locations.Symbol.TryRehydrateAsync(solution, cancellationToken).ConfigureAwait(false); if (symbol == null) return null; @@ -209,11 +215,17 @@ internal static async Task RehydrateAsync(Solution solution, Se commentsResult = builder.ToImmutable(); } + var originalSymbolResult = locations.OriginalSymbolResult == null + ? null + : await locations.OriginalSymbolResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false); + + Contract.ThrowIfNull(locations.MergedResult); + return new RenameLocations( symbol, solution, locations.Options.Rehydrate(), - await locations.OriginalSymbolResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false), + originalSymbolResult, await locations.MergedResult.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false), overloadsResult, stringsResult, @@ -223,15 +235,15 @@ await locations.MergedResult.RehydrateAsync(solution, cancellationToken).Configu internal class SerializableRenameLocations { - public SerializableSymbolAndProjectId Symbol; + public SerializableSymbolAndProjectId? Symbol; public SerializableRenameOptionSet Options; - public SerializableSearchResult OriginalSymbolResult; - public SerializableSearchResult MergedResult; + public SerializableSearchResult? OriginalSymbolResult; + public SerializableSearchResult? MergedResult; // We use arrays so we can represent default immutable arrays. - public SerializableSearchResult[] OverloadsResult; - public SerializableRenameLocation[] StringsResult; - public SerializableRenameLocation[] CommentsResult; + public SerializableSearchResult[]? OverloadsResult; + public SerializableRenameLocation[]? StringsResult; + public SerializableRenameLocation[]? CommentsResult; } internal class SerializableComplexifiedSpan @@ -257,7 +269,7 @@ internal class SerializableRelatedLocation public TextSpan ConflictCheckSpan; public RelatedLocationType Type; public bool IsReference; - public DocumentId DocumentId; + public DocumentId? DocumentId; public TextSpan ComplexifiedTargetSpan; public RelatedLocation Rehydrate() @@ -276,7 +288,7 @@ public static SerializableRelatedLocation Dehydrate(RelatedLocation location) internal class SerializableConflictResolution { - public string ErrorMessage; + public string? ErrorMessage; public bool ReplacementTextValid; @@ -286,12 +298,12 @@ internal class SerializableConflictResolution // // We also flatten dictionaries into key/value tuples because jsonrpc only supports dictionaries with string keys. - public DocumentId[] DocumentIds; - public SerializableRelatedLocation[] RelatedLocations; - public (DocumentId, TextChange[])[] DocumentTextChanges; - public (DocumentId, ImmutableArray<(TextSpan oldSpan, TextSpan newSpan)>)[] DocumentToModifiedSpansMap; - public (DocumentId, ImmutableArray)[] DocumentToComplexifiedSpansMap; - public (DocumentId, ImmutableArray)[] DocumentToRelatedLocationsMap; + public DocumentId[]? DocumentIds; + public SerializableRelatedLocation[]? RelatedLocations; + public (DocumentId, TextChange[])[]? DocumentTextChanges; + public (DocumentId, ImmutableArray<(TextSpan oldSpan, TextSpan newSpan)>)[]? DocumentToModifiedSpansMap; + public (DocumentId, ImmutableArray)[]? DocumentToComplexifiedSpansMap; + public (DocumentId, ImmutableArray)[]? DocumentToRelatedLocationsMap; public async Task RehydrateAsync(Solution oldSolution, CancellationToken cancellationToken) { diff --git a/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs b/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs index a68b6f0b0f6a4..2d4b0c49e1b7b 100644 --- a/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs +++ b/src/Workspaces/Core/Portable/Rename/IRenameRewriterLanguageService.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs b/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs index 0628d4e288cb8..13c8cccf4c858 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocation.ReferenceProcessing.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -31,14 +33,12 @@ internal static class ReferenceProcessing /// Given a symbol in a document, returns the "right" symbol that should be renamed in /// the case the name binds to things like aliases _and_ the underlying type at once. /// - public static async Task GetRenamableSymbolAsync( + public static async Task TryGetRenamableSymbolAsync( Document document, int position, CancellationToken cancellationToken) { var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false); if (symbol == null) - { return null; - } var definitionSymbol = await FindDefinitionSymbolAsync(symbol, document.Project.Solution, cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(definitionSymbol); @@ -115,7 +115,7 @@ public static async Task FindDefinitionSymbolAsync( } // in case this is e.g. an overridden property accessor, we'll treat the property itself as the definition symbol - var property = await GetPropertyFromAccessorOrAnOverrideAsync(bestSymbol, solution, cancellationToken).ConfigureAwait(false); + var property = await TryGetPropertyFromAccessorOrAnOverrideAsync(bestSymbol, solution, cancellationToken).ConfigureAwait(false); return property ?? bestSymbol; } @@ -214,7 +214,7 @@ static bool IsConstructorForType(ISymbol possibleConstructor, ISymbol possibleTy } } - internal static async Task GetPropertyFromAccessorOrAnOverrideAsync( + internal static async Task TryGetPropertyFromAccessorOrAnOverrideAsync( ISymbol symbol, Solution solution, CancellationToken cancellationToken) { if (symbol.IsPropertyAccessor()) @@ -229,7 +229,7 @@ internal static async Task GetPropertyFromAccessorOrAnOverrideAsync( if (originalSourceSymbol != null) { - return await GetPropertyFromAccessorOrAnOverrideAsync(originalSourceSymbol, solution, cancellationToken).ConfigureAwait(false); + return await TryGetPropertyFromAccessorOrAnOverrideAsync(originalSourceSymbol, solution, cancellationToken).ConfigureAwait(false); } } @@ -241,7 +241,7 @@ internal static async Task GetPropertyFromAccessorOrAnOverrideAsync( foreach (var methodImplementor in methodImplementors) { - var propertyAccessorOrAnOverride = await GetPropertyFromAccessorOrAnOverrideAsync(methodImplementor, solution, cancellationToken).ConfigureAwait(false); + var propertyAccessorOrAnOverride = await TryGetPropertyFromAccessorOrAnOverrideAsync(methodImplementor, solution, cancellationToken).ConfigureAwait(false); if (propertyAccessorOrAnOverride != null) { return propertyAccessorOrAnOverride; @@ -255,7 +255,7 @@ internal static async Task GetPropertyFromAccessorOrAnOverrideAsync( private static async Task IsPropertyAccessorOrAnOverrideAsync( ISymbol symbol, Solution solution, CancellationToken cancellationToken) { - var result = await GetPropertyFromAccessorOrAnOverrideAsync( + var result = await TryGetPropertyFromAccessorOrAnOverrideAsync( symbol, solution, cancellationToken).ConfigureAwait(false); return result != null; } @@ -300,7 +300,8 @@ public static async Task> GetRenamableDefinitionL if (originalSymbol.Kind == SymbolKind.Alias) { var location = originalSymbol.Locations.Single(); - results.Add(new RenameLocation(location, solution.GetDocument(location.SourceTree).Id)); + Contract.ThrowIfNull(location.SourceTree); + results.Add(new RenameLocation(location, solution.GetRequiredDocument(location.SourceTree).Id)); return results.ToImmutableAndFree(); } @@ -309,9 +310,10 @@ public static async Task> GetRenamableDefinitionL { if (location.IsInSource) { + Contract.ThrowIfNull(location.SourceTree); results.Add(new RenameLocation( location, - solution.GetDocument(location.SourceTree).Id, + solution.GetRequiredDocument(location.SourceTree).Id, isRenamableAccessor: isRenamableAccessor)); } } @@ -320,7 +322,10 @@ public static async Task> GetRenamableDefinitionL // destructors declarations that match the name if (referencedSymbol.Kind == SymbolKind.NamedType && referencedSymbol.Locations.All(l => l.IsInSource)) { - var syntaxFacts = solution.GetDocument(referencedSymbol.Locations[0].SourceTree).GetLanguageService(); + var firstLocation = referencedSymbol.Locations[0]; + Contract.ThrowIfNull(firstLocation.SourceTree); + var syntaxFacts = solution.GetRequiredDocument(firstLocation.SourceTree) + .GetRequiredLanguageService(); var namedType = (INamedTypeSymbol)referencedSymbol; foreach (var method in namedType.GetMembers().OfType()) @@ -337,7 +342,8 @@ public static async Task> GetRenamableDefinitionL if (!syntaxFacts.IsReservedOrContextualKeyword(token) && token.ValueText == referencedSymbol.Name) { - results.Add(new RenameLocation(location, solution.GetDocument(location.SourceTree).Id)); + Contract.ThrowIfNull(location.SourceTree); + results.Add(new RenameLocation(location, solution.GetRequiredDocument(location.SourceTree).Id)); } } } @@ -376,7 +382,8 @@ internal static async Task> GetRenamableReferenceLoc // We also need to add the location of the alias // itself var aliasLocation = location.Alias.Locations.Single(); - results.Add(new RenameLocation(aliasLocation, solution.GetDocument(aliasLocation.SourceTree).Id)); + Contract.ThrowIfNull(aliasLocation.SourceTree); + results.Add(new RenameLocation(aliasLocation, solution.GetRequiredDocument(aliasLocation.SourceTree).Id)); } } else @@ -394,7 +401,8 @@ internal static async Task> GetRenamableReferenceLoc // We also need to add the location of the alias itself var aliasLocation = location.Alias.Locations.Single(); - results.Add(new RenameLocation(aliasLocation, solution.GetDocument(aliasLocation.SourceTree).Id)); + Contract.ThrowIfNull(aliasLocation.SourceTree); + results.Add(new RenameLocation(aliasLocation, solution.GetRequiredDocument(aliasLocation.SourceTree).Id)); } } else @@ -459,7 +467,7 @@ private static async Task AddLocationsToRenameInStringsAsync( Document document, string renameText, ISyntaxFactsService syntaxFactsService, ArrayBuilder renameLocations, CancellationToken cancellationToken) { - var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var renameTextLength = renameText.Length; var renameStringsAndPositions = root @@ -477,7 +485,7 @@ private static async Task AddLocationsToRenameInStringsAsync( private static async Task AddLocationsToRenameInCommentsAsync( Document document, string renameText, ArrayBuilder renameLocations, CancellationToken cancellationToken) { - var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var renameTextLength = renameText.Length; var renameStringsAndPositions = root @@ -508,8 +516,11 @@ private static void AddLocationsToRenameInStringsAndComments( var matches = regex.Matches(renameString); - foreach (Match match in matches) + foreach (Match? match in matches) { + if (match == null) + continue; + var start = renameStringPosition + match.Index; Debug.Assert(renameText.Length == match.Length); var matchTextSpan = new TextSpan(start, renameText.Length); diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocation.cs b/src/Workspaces/Core/Portable/Rename/RenameLocation.cs index 2922c57f76fa1..6062296a346ec 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocation.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocation.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Text; @@ -48,7 +50,7 @@ public RenameLocation(ReferenceLocation referenceLocation, DocumentId documentId public bool Equals(RenameLocation other) => Location == other.Location; - public override bool Equals(object obj) + public override bool Equals(object? obj) { return obj is RenameLocation loc && Equals(loc); diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocations.SearchResult.cs b/src/Workspaces/Core/Portable/Rename/RenameLocations.SearchResult.cs index ce700b5f82f4c..1953f8e1cb099 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocations.SearchResult.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocations.SearchResult.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Immutable; using Microsoft.CodeAnalysis.FindSymbols; +using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Rename { @@ -20,6 +23,7 @@ public SearchResult( ImmutableArray implicitLocations, ImmutableArray referencedSymbols) { + Contract.ThrowIfNull(locations); this.Locations = locations; this.ImplicitLocations = implicitLocations; this.ReferencedSymbols = referencedSymbols; diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocations.cs b/src/Workspaces/Core/Portable/Rename/RenameLocations.cs index 3b6f38c086ba4..378a995b1737c 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocations.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocations.cs @@ -150,8 +150,10 @@ public static async Task FindLocationsAsync( if (result.HasValue) { - return await RenameLocations.RehydrateAsync( + var rehydrated = await RenameLocations.TryRehydrateAsync( solution, result.Value, cancellationToken).ConfigureAwait(false); + if (rehydrated != null) + return rehydrated; } } } diff --git a/src/Workspaces/Core/Portable/Rename/Renamer.cs b/src/Workspaces/Core/Portable/Rename/Renamer.cs index e909bf6ad91fa..f3cc281740bfc 100644 --- a/src/Workspaces/Core/Portable/Rename/Renamer.cs +++ b/src/Workspaces/Core/Portable/Rename/Renamer.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -35,7 +37,7 @@ public static async Task RenameSymbolAsync( RenameOptionSet.From(solution, optionSet), nonConflictSymbols: null, cancellationToken).ConfigureAwait(false); - // This is a public entrypoint. So if rename failed to resolve conflicts, we report that back to caller as + // This is a public entry-point. So if rename failed to resolve conflicts, we report that back to caller as // an exception. if (resolution.ErrorMessage != null) throw new ArgumentException(resolution.ErrorMessage); @@ -66,8 +68,8 @@ public static async Task RenameSymbolAsync( public static async Task RenameDocumentAsync( Document document, string newDocumentName, - IReadOnlyList newDocumentFolders = null, - OptionSet optionSet = null, + IReadOnlyList? newDocumentFolders = null, + OptionSet? optionSet = null, CancellationToken cancellationToken = default) { if (document is null) @@ -109,7 +111,7 @@ internal static async Task RenameSymbolAsync( ISymbol symbol, string newName, RenameOptionSet optionSet, - ImmutableHashSet nonConflictSymbols, + ImmutableHashSet? nonConflictSymbols, CancellationToken cancellationToken) { Contract.ThrowIfNull(solution); @@ -130,7 +132,7 @@ internal static async Task RenameSymbolAsync( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteRenamer.RenameSymbolAsync), solution, - new object[] + new object?[] { SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken), newName, @@ -156,7 +158,7 @@ private static async Task RenameSymbolInCurrentProcessAsync( ISymbol symbol, string newName, RenameOptionSet optionSet, - ImmutableHashSet nonConflictSymbols, + ImmutableHashSet? nonConflictSymbols, CancellationToken cancellationToken) { Contract.ThrowIfNull(solution); From 87ca51d9a1a26233a42fc76ff72eb866958cdfbf Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 11:47:57 -0700 Subject: [PATCH 209/222] More NRT --- .../AbstractEditorInlineRenameService.cs | 2 +- .../CSharpRenameRewriterLanguageService.cs | 2 +- .../Rename/ConflictEngine/ConflictResolver.cs | 57 +++++++++++-------- .../Core/Portable/Rename/IRemoteRenamer.cs | 6 +- .../Core/Portable/Rename/RenameLocations.cs | 4 +- .../Core/Portable/Rename/Renamer.cs | 4 +- .../Services/CodeAnalysisService_Renamer.cs | 22 ++++--- 7 files changed, 57 insertions(+), 40 deletions(-) diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs index 1f14d30638e9c..1cbaa9f187c6f 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/AbstractEditorInlineRenameService.cs @@ -91,7 +91,7 @@ internal static async Task GetRenameInfoAsync( } } - var symbol = await RenameLocations.ReferenceProcessing.GetRenamableSymbolAsync(document, triggerToken.SpanStart, cancellationToken: cancellationToken).ConfigureAwait(false); + var symbol = await RenameLocations.ReferenceProcessing.TryGetRenamableSymbolAsync(document, triggerToken.SpanStart, cancellationToken: cancellationToken).ConfigureAwait(false); if (symbol == null) { return new FailureInlineRenameInfo(EditorFeaturesResources.You_cannot_rename_this_element); diff --git a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs index e79f3f3686b28..fdf0bcc6fd524 100644 --- a/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs +++ b/src/Workspaces/CSharp/Portable/Rename/CSharpRenameRewriterLanguageService.cs @@ -816,7 +816,7 @@ renamedSymbol.ContainingSymbol is IMethodSymbol methodSymbol && var properties = new List(); foreach (var referencedSymbol in referencedSymbols) { - var property = await RenameLocations.ReferenceProcessing.GetPropertyFromAccessorOrAnOverrideAsync( + var property = await RenameLocations.ReferenceProcessing.TryGetPropertyFromAccessorOrAnOverrideAsync( referencedSymbol, baseSolution, cancellationToken).ConfigureAwait(false); if (property != null) { diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index 114b679188004..2783e006096be 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -50,11 +52,11 @@ internal static async Task ResolveConflictsAsync( var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { - var result = await client.TryRunRemoteAsync( + var result = await client.TryRunRemoteAsync( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteRenamer.ResolveConflictsAsync), solution, - new object[] + new object?[] { renameLocationSet.Dehydrate(solution, cancellationToken), replacementText, @@ -63,10 +65,8 @@ internal static async Task ResolveConflictsAsync( callbackTarget: null, cancellationToken).ConfigureAwait(false); - if (result.HasValue) - { + if (result.HasValue && result.Value != null) return await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false); - } } } @@ -77,7 +77,7 @@ internal static async Task ResolveConflictsAsync( private static async Task ResolveConflictsInCurrentProcessAsync( RenameLocations renameLocationSet, string replacementText, - ImmutableHashSet nonConflictSymbols, + ImmutableHashSet? nonConflictSymbols, CancellationToken cancellationToken) { var resolution = await ResolveMutableConflictsAsync( @@ -88,7 +88,7 @@ private static async Task ResolveConflictsInCurrentProcessAs private static Task ResolveMutableConflictsAsync( RenameLocations renameLocationSet, string replacementText, - ImmutableHashSet nonConflictSymbols, + ImmutableHashSet? nonConflictSymbols, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -120,25 +120,25 @@ private static ImmutableArray SymbolsForEnclosingInvocationExpressionWo private static SyntaxNode GetExpansionTargetForLocationPerLanguage(SyntaxToken tokenOrNode, Document document) { - var renameRewriterService = document.GetLanguageService(); + var renameRewriterService = document.GetRequiredLanguageService(); var complexifiedTarget = renameRewriterService.GetExpansionTargetForLocation(tokenOrNode); return complexifiedTarget; } private static bool LocalVariableConflictPerLanguage(SyntaxToken tokenOrNode, Document document, ImmutableArray newReferencedSymbols) { - var renameRewriterService = document.GetLanguageService(); + var renameRewriterService = document.GetRequiredLanguageService(); var isConflict = renameRewriterService.LocalVariableConflict(tokenOrNode, newReferencedSymbols); return isConflict; } private static bool IsIdentifierValid_Worker(Solution solution, string replacementText, IEnumerable projectIds) { - foreach (var language in projectIds.Select(p => solution.GetProject(p).Language).Distinct()) + foreach (var language in projectIds.Select(p => solution.GetRequiredProject(p).Language).Distinct()) { var languageServices = solution.Workspace.Services.GetLanguageServices(language); - var renameRewriterLanguageService = languageServices.GetService(); - var syntaxFactsLanguageService = languageServices.GetService(); + var renameRewriterLanguageService = languageServices.GetRequiredService(); + var syntaxFactsLanguageService = languageServices.GetRequiredService(); if (!renameRewriterLanguageService.IsIdentifierValid(replacementText, syntaxFactsLanguageService)) { return false; @@ -166,11 +166,15 @@ private static async Task AddImplicitConflictsAsync( CancellationToken cancellationToken) { { - var renameRewriterService = conflictResolution.CurrentSolution.Workspace.Services.GetLanguageServices(renamedSymbol.Language).GetService(); + var renameRewriterService = + conflictResolution.CurrentSolution.Workspace.Services.GetLanguageServices(renamedSymbol.Language) + .GetRequiredService(); var implicitUsageConflicts = renameRewriterService.ComputePossibleImplicitUsageConflicts(renamedSymbol, semanticModel, originalDeclarationLocation, newDeclarationLocationStartingPosition, cancellationToken); foreach (var implicitUsageConflict in implicitUsageConflicts) { - conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation(implicitUsageConflict.SourceSpan, conflictResolution.OldSolution.GetDocument(implicitUsageConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); + Contract.ThrowIfNull(implicitUsageConflict.SourceTree); + conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation( + implicitUsageConflict.SourceSpan, conflictResolution.OldSolution.GetRequiredDocument(implicitUsageConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); } } @@ -183,7 +187,7 @@ private static async Task AddImplicitConflictsAsync( { // the location of the implicit reference defines the language rules to check. // E.g. foreach in C# using a MoveNext in VB that is renamed to MOVENEXT (within VB) - var renameRewriterService = implicitReferenceLocationsPerLanguage.First().Document.Project.LanguageServices.GetService(); + var renameRewriterService = implicitReferenceLocationsPerLanguage.First().Document.Project.LanguageServices.GetRequiredService(); var implicitConflicts = await renameRewriterService.ComputeImplicitReferenceConflictsAsync( originalSymbol, renamedSymbol, @@ -192,7 +196,9 @@ private static async Task AddImplicitConflictsAsync( foreach (var implicitConflict in implicitConflicts) { - conflictResolution.AddRelatedLocation(new RelatedLocation(implicitConflict.SourceSpan, conflictResolution.OldSolution.GetDocument(implicitConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); + Contract.ThrowIfNull(implicitConflict.SourceTree); + conflictResolution.AddRelatedLocation(new RelatedLocation( + implicitConflict.SourceSpan, conflictResolution.OldSolution.GetRequiredDocument(implicitConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); } } } @@ -214,7 +220,7 @@ private static async Task AddDeclarationConflictsAsync( try { var project = conflictResolution.CurrentSolution.GetProject(renamedSymbol.ContainingAssembly, cancellationToken); - + Contract.ThrowIfNull(project); if (renamedSymbol.ContainingSymbol.IsKind(SymbolKind.NamedType)) { var otherThingsNamedTheSame = renamedSymbol.ContainingType.GetMembers(renamedSymbol.Name) @@ -224,7 +230,7 @@ private static async Task AddDeclarationConflictsAsync( IEnumerable otherThingsNamedTheSameExcludeMethodAndParameterizedProperty; // Possibly overloaded symbols are excluded here and handled elsewhere - var semanticFactsService = project.LanguageServices.GetService(); + var semanticFactsService = project.LanguageServices.GetRequiredService(); if (semanticFactsService.SupportsParameterizedProperties) { otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame @@ -270,7 +276,7 @@ private static async Task AddDeclarationConflictsAsync( if (renamedSymbol.ContainingAssembly != null) { // There also might be language specific rules we need to include - var languageRenameService = project.LanguageServices.GetService(); + var languageRenameService = project.LanguageServices.GetRequiredService(); var languageConflicts = await languageRenameService.ComputeDeclarationConflictsAsync( conflictResolution.ReplacementText, renamedSymbol, @@ -283,7 +289,9 @@ private static async Task AddDeclarationConflictsAsync( foreach (var languageConflict in languageConflicts) { - conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation(languageConflict.SourceSpan, conflictResolution.OldSolution.GetDocument(languageConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); + Contract.ThrowIfNull(languageConflict.SourceTree); + conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation( + languageConflict.SourceSpan, conflictResolution.OldSolution.GetRequiredDocument(languageConflict.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); } } } @@ -308,7 +316,9 @@ private static void AddConflictingSymbolLocations(IEnumerable conflicti { if (reverseMappedLocations.TryGetValue(newLocation, out var oldLocation)) { - conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation(oldLocation.SourceSpan, conflictResolution.OldSolution.GetDocument(oldLocation.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); + Contract.ThrowIfNull(oldLocation.SourceTree); + conflictResolution.AddOrReplaceRelatedLocation(new RelatedLocation( + oldLocation.SourceSpan, conflictResolution.OldSolution.GetRequiredDocument(oldLocation.SourceTree).Id, RelatedLocationType.UnresolvableConflict)); } } } @@ -382,7 +392,8 @@ private static async Task GetSymbolLocationAsync(Solution solution, IS locations = originalsourcesymbol.Locations; } - var orderedLocations = locations.OrderBy(l => l.IsInSource ? solution.GetDocumentId(l.SourceTree).Id : Guid.Empty) + var orderedLocations = locations + .OrderBy(l => l.IsInSource ? solution.GetDocumentId(l.SourceTree)!.Id : Guid.Empty) .ThenBy(l => l.IsInSource ? l.SourceSpan.Start : int.MaxValue); return orderedLocations.FirstOrDefault(); @@ -405,7 +416,7 @@ private static bool HeuristicMetadataNameEquivalenceCheck( // Every loop updates the newMetadataName to resemble the oldMetadataName while (index != -1 && index < oldMetadataName.Length) { - // This check is to ses if the part of string before the string match, matches + // This check is to see if the part of string before the string match, matches if (!IsSubStringEqual(oldMetadataName, newMetadataName, index)) { return false; diff --git a/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs b/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs index 695df0893de2f..4b980b0d4660c 100644 --- a/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs +++ b/src/Workspaces/Core/Portable/Rename/IRemoteRenamer.cs @@ -26,7 +26,7 @@ internal interface IRemoteRenamer /// forth marshaling) when the intermediary results of rename are not needed. To get the individual parts of /// rename remoted use and . /// - Task RenameSymbolAsync( + Task RenameSymbolAsync( PinnedSolutionInfo solutionInfo, SerializableSymbolAndProjectId symbolAndProjectId, string replacementText, @@ -34,13 +34,13 @@ Task RenameSymbolAsync( SerializableSymbolAndProjectId[] nonConflictSymbolIds, CancellationToken cancellationToken); - Task FindRenameLocationsAsync( + Task FindRenameLocationsAsync( PinnedSolutionInfo solutionInfo, SerializableSymbolAndProjectId symbolAndProjectId, SerializableRenameOptionSet options, CancellationToken cancellationToken); - Task ResolveConflictsAsync( + Task ResolveConflictsAsync( PinnedSolutionInfo solutionInfo, SerializableRenameLocations renameLocationSet, string replacementText, diff --git a/src/Workspaces/Core/Portable/Rename/RenameLocations.cs b/src/Workspaces/Core/Portable/Rename/RenameLocations.cs index 378a995b1737c..54f78e9462dea 100644 --- a/src/Workspaces/Core/Portable/Rename/RenameLocations.cs +++ b/src/Workspaces/Core/Portable/Rename/RenameLocations.cs @@ -136,7 +136,7 @@ public static async Task FindLocationsAsync( var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { - var result = await client.TryRunRemoteAsync( + var result = await client.TryRunRemoteAsync( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteRenamer.FindRenameLocationsAsync), solution, @@ -148,7 +148,7 @@ public static async Task FindLocationsAsync( callbackTarget: null, cancellationToken).ConfigureAwait(false); - if (result.HasValue) + if (result.HasValue && result.Value != null) { var rehydrated = await RenameLocations.TryRehydrateAsync( solution, result.Value, cancellationToken).ConfigureAwait(false); diff --git a/src/Workspaces/Core/Portable/Rename/Renamer.cs b/src/Workspaces/Core/Portable/Rename/Renamer.cs index f3cc281740bfc..e8b4637d1d65a 100644 --- a/src/Workspaces/Core/Portable/Rename/Renamer.cs +++ b/src/Workspaces/Core/Portable/Rename/Renamer.cs @@ -128,7 +128,7 @@ internal static async Task RenameSymbolAsync( var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { - var result = await client.TryRunRemoteAsync( + var result = await client.TryRunRemoteAsync( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteRenamer.RenameSymbolAsync), solution, @@ -142,7 +142,7 @@ internal static async Task RenameSymbolAsync( callbackTarget: null, cancellationToken).ConfigureAwait(false); - if (result.HasValue) + if (result.HasValue && result.Value != null) return await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false); } } diff --git a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Renamer.cs b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Renamer.cs index 0610094ce094e..7ae362ed70f94 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Renamer.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/CodeAnalysisService_Renamer.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable enable + using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; @@ -13,7 +15,7 @@ namespace Microsoft.CodeAnalysis.Remote // root level service for all Roslyn services internal partial class CodeAnalysisService : IRemoteRenamer { - public Task RenameSymbolAsync( + public Task RenameSymbolAsync( PinnedSolutionInfo solutionInfo, SerializableSymbolAndProjectId symbolAndProjectId, string newName, @@ -21,7 +23,7 @@ public Task RenameSymbolAsync( SerializableSymbolAndProjectId[] nonConflictSymbolIds, CancellationToken cancellationToken) { - return RunServiceAsync(async () => + return RunServiceAsync(async () => { using (UserOperationBooster.Boost()) { @@ -43,13 +45,13 @@ public Task RenameSymbolAsync( }, cancellationToken); } - public Task FindRenameLocationsAsync( + public Task FindRenameLocationsAsync( PinnedSolutionInfo solutionInfo, SerializableSymbolAndProjectId symbolAndProjectId, SerializableRenameOptionSet options, CancellationToken cancellationToken) { - return RunServiceAsync(async () => + return RunServiceAsync(async () => { using (UserOperationBooster.Boost()) { @@ -68,22 +70,26 @@ public Task FindRenameLocationsAsync( }, cancellationToken); } - public Task ResolveConflictsAsync( + public Task ResolveConflictsAsync( PinnedSolutionInfo solutionInfo, SerializableRenameLocations renameLocationSet, string replacementText, SerializableSymbolAndProjectId[] nonConflictSymbolIds, CancellationToken cancellationToken) { - return RunServiceAsync(async () => + return RunServiceAsync(async () => { using (UserOperationBooster.Boost()) { var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false); var nonConflictSymbols = await GetNonConflictSymbolsAsync(solution, nonConflictSymbolIds, cancellationToken).ConfigureAwait(false); + var rehydratedSet = await RenameLocations.TryRehydrateAsync(solution, renameLocationSet, cancellationToken).ConfigureAwait(false); + if (rehydratedSet == null) + return null; + var result = await ConflictResolver.ResolveConflictsAsync( - await RenameLocations.RehydrateAsync(solution, renameLocationSet, cancellationToken).ConfigureAwait(false), + rehydratedSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false); @@ -92,7 +98,7 @@ await RenameLocations.RehydrateAsync(solution, renameLocationSet, cancellationTo }, cancellationToken); } - private async Task> GetNonConflictSymbolsAsync(Solution solution, SerializableSymbolAndProjectId[] nonConflictSymbolIds, CancellationToken cancellationToken) + private async Task?> GetNonConflictSymbolsAsync(Solution solution, SerializableSymbolAndProjectId[] nonConflictSymbolIds, CancellationToken cancellationToken) { if (nonConflictSymbolIds == null) return null; From ce0332bf2f1e0617b42dc15dc22385f146fcfde1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 11:52:08 -0700 Subject: [PATCH 210/222] More NRT --- src/EditorFeatures/Test2/Rename/RenameEngineResult.vb | 2 +- .../Core/Portable/Rename/ConflictEngine/ConflictResolver.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb index e393e7f394ff4..725dac0b1cac4 100644 --- a/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb +++ b/src/EditorFeatures/Test2/Rename/RenameEngineResult.vb @@ -69,7 +69,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Rename Dim document = workspace.CurrentSolution.GetDocument(cursorDocument.Id) - Dim symbol = RenameLocations.ReferenceProcessing.GetRenamableSymbolAsync(document, cursorPosition, CancellationToken.None).Result + Dim symbol = RenameLocations.ReferenceProcessing.TryGetRenamableSymbolAsync(document, cursorPosition, CancellationToken.None).Result If symbol Is Nothing Then AssertEx.Fail("The symbol touching the $$ could not be found.") End If diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index 2783e006096be..db4c21535b202 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -41,7 +41,7 @@ internal static partial class ConflictResolver internal static async Task ResolveConflictsAsync( RenameLocations renameLocationSet, string replacementText, - ImmutableHashSet nonConflictSymbols, + ImmutableHashSet? nonConflictSymbols, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); From e2703dc7a6fbaf77ec319424141356aa2b21393a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 11:56:53 -0700 Subject: [PATCH 211/222] Simplify --- .../ProjectSystem/VisualStudioProject.cs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs index 1da972a03a058..2c35aa9c091cb 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioProject.cs @@ -70,11 +70,11 @@ internal sealed class VisualStudioProject private string? _defaultNamespace; /// - /// We store if this is a primary project or not as a tri-state. Only means that it's - /// not a primary project. This way, if the value hasn't been set, or is never set, we still consider the - /// project to be a primary one. + /// If this project is the 'primary' project the project system cares about for a group of Roslyn projects that + /// correspond to different configurations of a single project system project. by + /// default. /// - private bool? _isPrimary; + internal bool IsPrimary { get; set; } = true; // Actual property values for 'RunAnalyzers' and 'RunAnalyzersDuringLiveAnalysis' properties from the project file. // Both these properties can be used to configure running analyzers, with RunAnalyzers overriding RunAnalyzersDuringLiveAnalysis. @@ -297,12 +297,6 @@ internal bool HasAllInformation set => ChangeProjectProperty(ref _hasAllInformation, value, s => s.WithHasAllInformation(Id, value)); } - internal bool IsPrimary - { - get => _isPrimary != false; - set => _isPrimary = value; - } - internal bool? RunAnalyzers { get => _runAnalyzersPropertyValue; From 65ae2cf1693e16a766036de18f3f9a26c548fba9 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 12:05:28 -0700 Subject: [PATCH 212/222] Add tests --- .../CPSProject_IWorkspaceProjectContext.cs | 2 - .../PrimaryProjectTests.vb | 50 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb diff --git a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs index bbb44339149d3..e8509e5e46a4e 100644 --- a/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs +++ b/src/VisualStudio/Core/Impl/ProjectSystem/CPS/CPSProject_IWorkspaceProjectContext.cs @@ -14,8 +14,6 @@ using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel; using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList; using Microsoft.VisualStudio.LanguageServices.ProjectSystem; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.CPS diff --git a/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb new file mode 100644 index 0000000000000..ef37eeb52212d --- /dev/null +++ b/src/VisualStudio/Core/Test/ProjectSystemShim/VisualStudioProjectTests/PrimaryProjectTests.vb @@ -0,0 +1,50 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Framework +Imports Roslyn.Test.Utilities + +Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim + <[UseExportProvider]> + Public Class PrimaryProjectTests + + Public Sub ProjectIsPrimaryByDefault() + Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) + Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( + "project", + LanguageNames.CSharp) + + Assert.True(project.IsPrimary) + End Using + End Sub + + + Public Sub ChangeProjectIsPrimary() + Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) + Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( + "project", + LanguageNames.CSharp) + + project.IsPrimary = False + Assert.False(project.IsPrimary) + End Using + End Sub + + + Public Sub ChangeProjectIsPrimaryBack() + Using environment = New TestEnvironment(GetType(TestDynamicFileInfoProviderThatProducesNoFiles)) + Dim project = environment.ProjectFactory.CreateAndAddToWorkspace( + "project", + LanguageNames.CSharp) + + project.IsPrimary = False + project.IsPrimary = True + Assert.True(project.IsPrimary) + End Using + End Sub + End Class +End Namespace + From 6fad70bbf1c87d2af102d4167c1623bbf835160a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 12:23:45 -0700 Subject: [PATCH 213/222] Simplify approach --- .../TodoComments/VisualStudioTodoCommentsService.cs | 12 ------------ .../Portable/TodoComments/ITodoCommentsListener.cs | 4 +--- .../RemoteTodoCommentsIncrementalAnalyzer.cs | 6 ++++-- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs b/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs index 40cb186518775..722d54facdb5c 100644 --- a/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs +++ b/src/VisualStudio/Core/Def/Implementation/TodoComments/VisualStudioTodoCommentsService.cs @@ -195,18 +195,6 @@ public IEnumerable GetTodoItemsUpdatedEventArgs( return SpecializedCollections.EmptyEnumerable(); } - /// - /// Callback from the OOP service back into us. - /// - public async Task OnDocumentRemovedAsync(DocumentId documentId, CancellationToken cancellationToken) - { - var workQueue = await _workQueueSource.Task.ConfigureAwait(false); - - // treat this as if we have no todo comments for this file. ProcessTodoCommentInfosAsync - // will handle actually clearing out the data. - workQueue.AddWork(new DocumentAndComments(documentId, ImmutableArray.Empty)); - } - /// /// Callback from the OOP service back into us. /// diff --git a/src/Workspaces/Core/Portable/TodoComments/ITodoCommentsListener.cs b/src/Workspaces/Core/Portable/TodoComments/ITodoCommentsListener.cs index 6069012a0316a..9a4d718b5ffb2 100644 --- a/src/Workspaces/Core/Portable/TodoComments/ITodoCommentsListener.cs +++ b/src/Workspaces/Core/Portable/TodoComments/ITodoCommentsListener.cs @@ -11,12 +11,10 @@ namespace Microsoft.CodeAnalysis.TodoComments { /// - /// Callback the host (VS) passes to the OOP service to allow it to send batch notifications - /// about todo comments. + /// Callback the host (VS) passes to the OOP service to allow it to send batch notifications about todo comments. /// internal interface ITodoCommentsListener { - Task OnDocumentRemovedAsync(DocumentId documentId, CancellationToken cancellationToken); Task ReportTodoCommentDataAsync(DocumentId documentId, ImmutableArray data, CancellationToken cancellationToken); } } diff --git a/src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsIncrementalAnalyzer.cs b/src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsIncrementalAnalyzer.cs index 3d8086b2b78ea..10509557e3571 100644 --- a/src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsIncrementalAnalyzer.cs +++ b/src/Workspaces/Remote/ServiceHub/Services/TodoComments/RemoteTodoCommentsIncrementalAnalyzer.cs @@ -4,6 +4,7 @@ #nullable enable +using System; using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; @@ -38,9 +39,10 @@ public override bool NeedsReanalysisOnOptionChanged(object sender, OptionChanged public override Task RemoveDocumentAsync(DocumentId documentId, CancellationToken cancellationToken) { + // Just report this back as there being no more comments for this document. return _endPoint.InvokeAsync( - nameof(ITodoCommentsListener.OnDocumentRemovedAsync), - new object[] { documentId }, + nameof(ITodoCommentsListener.ReportTodoCommentDataAsync), + new object[] { documentId, Array.Empty() }, cancellationToken); } From 759c6cd67038bf8e50f8eb526f5e8eec96125210 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 12:30:09 -0700 Subject: [PATCH 214/222] lint --- .../Core/Portable/SymbolKey/SymbolKeyResolution.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Workspaces/Core/Portable/SymbolKey/SymbolKeyResolution.cs b/src/Workspaces/Core/Portable/SymbolKey/SymbolKeyResolution.cs index ca267d8b6f850..573e00e44bfaf 100644 --- a/src/Workspaces/Core/Portable/SymbolKey/SymbolKeyResolution.cs +++ b/src/Workspaces/Core/Portable/SymbolKey/SymbolKeyResolution.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Collections.Immutable; -using System.Threading; #if DEBUG using System.Diagnostics; @@ -12,11 +11,10 @@ namespace Microsoft.CodeAnalysis { /// - /// The result of . - /// If the could be uniquely mapped to a single - /// then that will be returned in . Otherwise, if - /// the key resolves to multiple symbols (which can happen in error scenarios), then - /// and will be returned. + /// The result of . If the could be uniquely mapped to a + /// single then that will be returned in . Otherwise, if the key resolves + /// to multiple symbols (which can happen in error scenarios), then and will be returned. /// /// If no symbol can be found will be null and /// will be empty. From 3553f79d0fc03d4eb7a861b1bb2fb30da05afdaa Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Fri, 15 May 2020 13:30:37 -0700 Subject: [PATCH 215/222] Skip failing integration test CPSProject_GeneralPropertyGroupUpdated See #44301 --- .../IntegrationTests/CSharp/CSharpUpdateProjectToAllowUnsafe.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpUpdateProjectToAllowUnsafe.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpUpdateProjectToAllowUnsafe.cs index 8d98ba6fbc3ff..30ce00f82fbe8 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpUpdateProjectToAllowUnsafe.cs +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpUpdateProjectToAllowUnsafe.cs @@ -33,7 +33,7 @@ unsafe class C VisualStudio.Editor.Verify.CodeAction("Allow unsafe code in this project", applyFix: true); } - [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsUpdateProjectToAllowUnsafe)] + [WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/44301"), Trait(Traits.Feature, Traits.Features.CodeActionsUpdateProjectToAllowUnsafe)] public void CPSProject_GeneralPropertyGroupUpdated() { var project = new ProjectUtils.Project(ProjectName); From 2b05417bb16dcc551fa314f4acdc69c26a8b132b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 15 May 2020 13:55:11 -0700 Subject: [PATCH 216/222] Fix --- .../Portable/Rename/ConflictEngine/ConflictResolver.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs index db4c21535b202..ae29030858dd4 100644 --- a/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs +++ b/src/Workspaces/Core/Portable/Rename/ConflictEngine/ConflictResolver.cs @@ -219,10 +219,10 @@ private static async Task AddDeclarationConflictsAsync( { try { - var project = conflictResolution.CurrentSolution.GetProject(renamedSymbol.ContainingAssembly, cancellationToken); - Contract.ThrowIfNull(project); + var projectOpt = conflictResolution.CurrentSolution.GetProject(renamedSymbol.ContainingAssembly, cancellationToken); if (renamedSymbol.ContainingSymbol.IsKind(SymbolKind.NamedType)) { + Contract.ThrowIfNull(projectOpt); var otherThingsNamedTheSame = renamedSymbol.ContainingType.GetMembers(renamedSymbol.Name) .Where(s => !s.Equals(renamedSymbol) && string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal)); @@ -230,7 +230,7 @@ private static async Task AddDeclarationConflictsAsync( IEnumerable otherThingsNamedTheSameExcludeMethodAndParameterizedProperty; // Possibly overloaded symbols are excluded here and handled elsewhere - var semanticFactsService = project.LanguageServices.GetRequiredService(); + var semanticFactsService = projectOpt.LanguageServices.GetRequiredService(); if (semanticFactsService.SupportsParameterizedProperties) { otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame @@ -246,7 +246,6 @@ private static async Task AddDeclarationConflictsAsync( AddConflictingSymbolLocations(otherThingsNamedTheSameExcludeMethodAndParameterizedProperty, conflictResolution, reverseMappedLocations); } - if (renamedSymbol.IsKind(SymbolKind.Namespace) && renamedSymbol.ContainingSymbol.IsKind(SymbolKind.Namespace)) { var otherThingsNamedTheSame = ((INamespaceSymbol)renamedSymbol.ContainingSymbol).GetMembers(renamedSymbol.Name) @@ -275,8 +274,9 @@ private static async Task AddDeclarationConflictsAsync( // Some types of symbols (namespaces, cref stuff, etc) might not have ContainingAssemblies if (renamedSymbol.ContainingAssembly != null) { + Contract.ThrowIfNull(projectOpt); // There also might be language specific rules we need to include - var languageRenameService = project.LanguageServices.GetRequiredService(); + var languageRenameService = projectOpt.LanguageServices.GetRequiredService(); var languageConflicts = await languageRenameService.ComputeDeclarationConflictsAsync( conflictResolution.ReplacementText, renamedSymbol, From 61b78b4e7cbe807b884c12315cc58c8ec7fd01f1 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Fri, 15 May 2020 15:54:53 -0700 Subject: [PATCH 217/222] Fix yaml --- azure-pipelines-official.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 5d2f16d1b13d8..3f3e399fdb880 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -291,6 +291,8 @@ stages: enableSourceLinkValidation: false validateDependsOn: - SetValidateDependency + dependsOn: + - SetValidateDependency # Enable SDL validation, passing through values from the 'DotNet-Roslyn-SDLValidation-Params' group. SDLValidationParameters: enable: true From 7397b6224a0999fdd2e287c5052d96ce5d85d027 Mon Sep 17 00:00:00 2001 From: Gen Lu Date: Fri, 15 May 2020 16:21:16 -0700 Subject: [PATCH 218/222] Add comment --- azure-pipelines-official.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 3f3e399fdb880..121a55c534700 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -289,6 +289,8 @@ stages: # https://github.com/dotnet/arcade/issues/2871 is resolved. enableSymbolValidation: false enableSourceLinkValidation: false + # It's important that post-build stages are depends on 'SetValidateDependency' stage instead of 'build', + # since we don't want to publish validation build. validateDependsOn: - SetValidateDependency dependsOn: From f03f87fbb636dfba824947c0e19e779ee9a39626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Matou=C5=A1ek?= Date: Sat, 16 May 2020 16:52:06 -0700 Subject: [PATCH 219/222] Delete RemoteHostClientMock (#44318) --- Roslyn.sln | 7 --- .../Roslyn.Services.Test.Utilities.csproj | 1 - ...osoft.VisualStudio.LanguageServices.csproj | 1 - .../Remote/RemoteHostClientFactory.cs | 37 ------------- .../Remote/RemoteHostClientFactoryOptions.cs | 36 ------------ ...n.VisualStudio.RemoteHostClientMock.csproj | 55 ------------------- .../source.extension.vsixmanifest | 24 -------- ...oft.CodeAnalysis.Workspaces.Desktop.csproj | 1 - .../Microsoft.CodeAnalysis.Workspaces.csproj | 1 - 9 files changed, 163 deletions(-) delete mode 100644 src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactory.cs delete mode 100644 src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactoryOptions.cs delete mode 100644 src/VisualStudio/RemoteHostClientMock/Roslyn.VisualStudio.RemoteHostClientMock.csproj delete mode 100644 src/VisualStudio/RemoteHostClientMock/source.extension.vsixmanifest diff --git a/Roslyn.sln b/Roslyn.sln index a4233ec289724..574c83269b5a9 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -292,8 +292,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Remo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.Tasks.CodeAnalysis", "src\Compilers\Core\MSBuildTask\Microsoft.Build.Tasks.CodeAnalysis.csproj", "{7AD4FE65-9A30-41A6-8004-AA8F89BCB7F3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roslyn.VisualStudio.RemoteHostClientMock", "src\VisualStudio\RemoteHostClientMock\Roslyn.VisualStudio.RemoteHostClientMock.csproj", "{7259740A-FD0E-480F-A7D4-08BE90AC9051}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roslyn.VisualStudio.Next.UnitTests", "src\VisualStudio\Core\Test.Next\Roslyn.VisualStudio.Next.UnitTests.csproj", "{2E1658E2-5045-4F85-A64C-C0ECCD39F719}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BuildBoss", "src\Tools\BuildBoss\BuildBoss.csproj", "{9C0660D9-48CA-40E1-BABA-8F6A1F11FE10}" @@ -977,10 +975,6 @@ Global {7AD4FE65-9A30-41A6-8004-AA8F89BCB7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {7AD4FE65-9A30-41A6-8004-AA8F89BCB7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {7AD4FE65-9A30-41A6-8004-AA8F89BCB7F3}.Release|Any CPU.Build.0 = Release|Any CPU - {7259740A-FD0E-480F-A7D4-08BE90AC9051}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7259740A-FD0E-480F-A7D4-08BE90AC9051}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7259740A-FD0E-480F-A7D4-08BE90AC9051}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7259740A-FD0E-480F-A7D4-08BE90AC9051}.Release|Any CPU.Build.0 = Release|Any CPU {2E1658E2-5045-4F85-A64C-C0ECCD39F719}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E1658E2-5045-4F85-A64C-C0ECCD39F719}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E1658E2-5045-4F85-A64C-C0ECCD39F719}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1358,7 +1352,6 @@ Global {F822F72A-CC87-4E31-B57D-853F65CBEBF3} = {55A62CFA-1155-46F1-ADF3-BEEE51B58AB5} {80FDDD00-9393-47F7-8BAF-7E87CE011068} = {55A62CFA-1155-46F1-ADF3-BEEE51B58AB5} {7AD4FE65-9A30-41A6-8004-AA8F89BCB7F3} = {A41D1B99-F489-4C43-BBDF-96D61B19A6B9} - {7259740A-FD0E-480F-A7D4-08BE90AC9051} = {8DBA5174-B0AA-4561-82B1-A46607697753} {2E1658E2-5045-4F85-A64C-C0ECCD39F719} = {8DBA5174-B0AA-4561-82B1-A46607697753} {9C0660D9-48CA-40E1-BABA-8F6A1F11FE10} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC} {21A01C2D-2501-4619-8144-48977DD22D9C} = {38940C5F-97FD-4B2A-B2CD-C4E4EF601B05} diff --git a/src/EditorFeatures/TestUtilities/Roslyn.Services.Test.Utilities.csproj b/src/EditorFeatures/TestUtilities/Roslyn.Services.Test.Utilities.csproj index e0f3216d1df9d..8dc550264c98e 100644 --- a/src/EditorFeatures/TestUtilities/Roslyn.Services.Test.Utilities.csproj +++ b/src/EditorFeatures/TestUtilities/Roslyn.Services.Test.Utilities.csproj @@ -64,7 +64,6 @@ - diff --git a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj index 0fa03c5b20722..d3fca8428f1a8 100644 --- a/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj +++ b/src/VisualStudio/Core/Def/Microsoft.VisualStudio.LanguageServices.csproj @@ -92,7 +92,6 @@ - diff --git a/src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactory.cs b/src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactory.cs deleted file mode 100644 index 46b1345b7bfc5..0000000000000 --- a/src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactory.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Composition; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Remote; -using Microsoft.VisualStudio.LanguageServices.Remote; -using Roslyn.Test.Utilities.Remote; - -namespace Roslyn.VisualStudio.DiagnosticsWindow.Remote -{ - [ExportWorkspaceService(typeof(IRemoteHostClientFactory), layer: ServiceLayer.Host), Shared] - internal class RemoteHostClientFactory : IRemoteHostClientFactory - { - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RemoteHostClientFactory() - { - } - - public Task CreateAsync(Workspace workspace, CancellationToken cancellationToken) - { - // this is the point where we can create different kind of remote host client in future (cloud or etc) - if (workspace.Options.GetOption(RemoteHostClientFactoryOptions.RemoteHost_InProc)) - { - return InProcRemoteHostClient.CreateAsync(workspace, runCacheCleanup: true); - } - - return ServiceHubRemoteHostClient.CreateAsync(workspace, cancellationToken); - } - } -} diff --git a/src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactoryOptions.cs b/src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactoryOptions.cs deleted file mode 100644 index 210e3ef2c4232..0000000000000 --- a/src/VisualStudio/RemoteHostClientMock/Remote/RemoteHostClientFactoryOptions.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Immutable; -using System.Composition; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.Options; -using Microsoft.CodeAnalysis.Options.Providers; - -namespace Roslyn.VisualStudio.DiagnosticsWindow.Remote -{ - internal static class RemoteHostClientFactoryOptions - { - internal const string LocalRegistryPath = @"Roslyn\Internal\OnOff\Features\"; - - public static readonly Option RemoteHost_InProc = new Option( - "InternalFeatureOnOffOptions", nameof(RemoteHost_InProc), defaultValue: false, - storageLocations: new LocalUserProfileStorageLocation(LocalRegistryPath + nameof(RemoteHost_InProc))); - } - - [ExportOptionProvider, Shared] - internal class RemoteHostClientFactoryOptionsProvider : IOptionProvider - { - [ImportingConstructor] - [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public RemoteHostClientFactoryOptionsProvider() - { - } - - public ImmutableArray Options { get; } = ImmutableArray.Create( - RemoteHostClientFactoryOptions.RemoteHost_InProc); - } -} diff --git a/src/VisualStudio/RemoteHostClientMock/Roslyn.VisualStudio.RemoteHostClientMock.csproj b/src/VisualStudio/RemoteHostClientMock/Roslyn.VisualStudio.RemoteHostClientMock.csproj deleted file mode 100644 index d9348d30d070f..0000000000000 --- a/src/VisualStudio/RemoteHostClientMock/Roslyn.VisualStudio.RemoteHostClientMock.csproj +++ /dev/null @@ -1,55 +0,0 @@ - - - - - Library - Roslyn.VisualStudio.RemoteHostClientMock - net472 - false - - - true - false - true - false - false - - - - - - BuiltProjectOutputGroup%3b - false - - - BuiltProjectOutputGroup%3b - - - BuiltProjectOutputGroup%3b - - - - - - - - - - - - - - - - - - - - - - - - Designer - - - \ No newline at end of file diff --git a/src/VisualStudio/RemoteHostClientMock/source.extension.vsixmanifest b/src/VisualStudio/RemoteHostClientMock/source.extension.vsixmanifest deleted file mode 100644 index 0ef9da988886f..0000000000000 --- a/src/VisualStudio/RemoteHostClientMock/source.extension.vsixmanifest +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Roslyn RemoteHostClient Mock - Roslyn RemoteHostClient Mock - EULA.rtf - - - - - - - - - - - - - - - - - diff --git a/src/Workspaces/Core/Desktop/Microsoft.CodeAnalysis.Workspaces.Desktop.csproj b/src/Workspaces/Core/Desktop/Microsoft.CodeAnalysis.Workspaces.Desktop.csproj index c5a60fe76fcf2..e78deaf59df2b 100644 --- a/src/Workspaces/Core/Desktop/Microsoft.CodeAnalysis.Workspaces.Desktop.csproj +++ b/src/Workspaces/Core/Desktop/Microsoft.CodeAnalysis.Workspaces.Desktop.csproj @@ -30,7 +30,6 @@ - From 1cf3804f82055268dcf8b239654c422e08a074fa Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Mon, 18 May 2020 11:34:12 -0700 Subject: [PATCH 222/222] Add using after merge. --- .../CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs | 1 + .../CSharp/Test/Symbol/Symbols/FunctionPointerTypeSymbolTests.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs index e48bab5e6e89d..0a51c43421404 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/FunctionPointerTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/FunctionPointerTypeSymbolTests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/FunctionPointerTypeSymbolTests.cs index 878ea86ec968c..d3d16cce6379e 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/FunctionPointerTypeSymbolTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/FunctionPointerTypeSymbolTests.cs @@ -8,6 +8,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Xunit;