未验证 提交 c3d87114 编写于 作者: M msftbot[bot] 提交者: GitHub

Merge pull request #43132 from dotnet/merges/release/dev16.6-to-master

Merge release/dev16.6 to master
......@@ -29,7 +29,7 @@
<!-- Versions used by several individual references below -->
<RoslynDiagnosticsNugetPackageVersion>3.0.0-beta2.20169.3</RoslynDiagnosticsNugetPackageVersion>
<CodeStyleLayerCodeAnalysisVersion>3.3.1</CodeStyleLayerCodeAnalysisVersion>
<MicrosoftCodeAnalysisTestingVersion>1.0.1-beta1.20126.2</MicrosoftCodeAnalysisTestingVersion>
<MicrosoftCodeAnalysisTestingVersion>1.0.1-beta1.20206.1</MicrosoftCodeAnalysisTestingVersion>
<CodeStyleAnalyzerVersion>3.6.0-2.20157.5</CodeStyleAnalyzerVersion>
<VisualStudioEditorPackagesVersion>16.4.248</VisualStudioEditorPackagesVersion>
<ILToolsPackageVersion>5.0.0-alpha1.19409.1</ILToolsPackageVersion>
......
......@@ -31,6 +31,11 @@ public sealed partial class AnalyzerConfig
public bool IsMatch(string s)
{
if (_numberRangePairs.IsEmpty)
{
return Regex.IsMatch(s);
}
var match = Regex.Match(s);
if (!match.Success)
{
......
......@@ -142,9 +142,6 @@ public AnalyzerConfigOptionsResult GetOptionsForSourcePath(string sourcePath)
throw new ArgumentNullException(nameof(sourcePath));
}
var treeOptionsBuilder = _treeOptionsPool.Allocate();
var analyzerOptionsBuilder = _analyzerOptionsPool.Allocate();
var diagnosticBuilder = ArrayBuilder<Diagnostic>.GetInstance();
var sectionKey = _sectionKeyPool.Allocate();
var normalizedPath = PathUtilities.NormalizeWithForwardSlash(sourcePath);
......@@ -161,9 +158,7 @@ public AnalyzerConfigOptionsResult GetOptionsForSourcePath(string sourcePath)
// to this source file.
if (config.IsRoot)
{
analyzerOptionsBuilder.Clear();
treeOptionsBuilder.Clear();
diagnosticBuilder.Clear();
sectionKey.Clear();
}
int dirLength = config.NormalizedDirectory.Length;
......@@ -182,13 +177,6 @@ public AnalyzerConfigOptionsResult GetOptionsForSourcePath(string sourcePath)
if (matchers[sectionIndex]?.IsMatch(relativePath) == true)
{
var section = config.NamedSections[sectionIndex];
addOptions(
section,
treeOptionsBuilder,
analyzerOptionsBuilder,
diagnosticBuilder,
config.PathToFile,
_diagnosticIdCache);
sectionKey.Add(section);
}
}
......@@ -199,10 +187,44 @@ public AnalyzerConfigOptionsResult GetOptionsForSourcePath(string sourcePath)
// exact same options
if (!_optionsCache.TryGetValue(sectionKey, out var result))
{
var treeOptionsBuilder = _treeOptionsPool.Allocate();
var analyzerOptionsBuilder = _analyzerOptionsPool.Allocate();
var diagnosticBuilder = ArrayBuilder<Diagnostic>.GetInstance();
int sectionKeyIndex = 0;
for (int analyzerConfigIndex = 0;
analyzerConfigIndex < _analyzerConfigs.Length && sectionKeyIndex < sectionKey.Count;
analyzerConfigIndex++)
{
AnalyzerConfig config = _analyzerConfigs[analyzerConfigIndex];
ImmutableArray<SectionNameMatcher?> matchers = _analyzerMatchers[analyzerConfigIndex];
for (int matcherIndex = 0; matcherIndex < matchers.Length; matcherIndex++)
{
if (sectionKey[sectionKeyIndex] == config.NamedSections[matcherIndex])
{
addOptions(
sectionKey[sectionKeyIndex],
treeOptionsBuilder,
analyzerOptionsBuilder,
diagnosticBuilder,
config.PathToFile,
_diagnosticIdCache);
sectionKeyIndex++;
if (sectionKeyIndex == sectionKey.Count)
{
// Exit the inner 'for' loop now that work is done. The outer loop is handled by a
// top-level condition.
break;
}
}
}
}
result = new AnalyzerConfigOptionsResult(
treeOptionsBuilder.Count > 0 ? treeOptionsBuilder.ToImmutable() : SyntaxTree.EmptyDiagnosticOptions,
analyzerOptionsBuilder.Count > 0 ? analyzerOptionsBuilder.ToImmutable() : AnalyzerConfigOptions.EmptyDictionary,
diagnosticBuilder.ToImmutableAndFree());
if (_optionsCache.TryAdd(sectionKey, result))
{
// Release the pooled object to be used as a key
......@@ -212,17 +234,17 @@ public AnalyzerConfigOptionsResult GetOptionsForSourcePath(string sourcePath)
{
freeKey(sectionKey, _sectionKeyPool);
}
treeOptionsBuilder.Clear();
analyzerOptionsBuilder.Clear();
_treeOptionsPool.Free(treeOptionsBuilder);
_analyzerOptionsPool.Free(analyzerOptionsBuilder);
}
else
{
freeKey(sectionKey, _sectionKeyPool);
}
treeOptionsBuilder.Clear();
analyzerOptionsBuilder.Clear();
_treeOptionsPool.Free(treeOptionsBuilder);
_analyzerOptionsPool.Free(analyzerOptionsBuilder);
return result;
static void freeKey(List<Section> sectionKey, ObjectPool<List<Section>> pool)
......
......@@ -38,6 +38,9 @@ namespace Microsoft.CodeAnalysis.Editor.CommandHandlers
[ContentType(ContentTypeNames.RoslynContentType)]
[Name(PredefinedCommandHandlerNames.SignatureHelpAfterCompletion)]
[Order(After = PredefinedCompletionNames.CompletionCommandHandler)]
// Ensure roslyn comes after LSP to allow them to provide results.
// https://github.com/dotnet/roslyn/issues/42338
[Order(After = "LSP SignatureHelpCommandHandler")]
internal class SignatureHelpAfterCompletionCommandHandler :
AbstractSignatureHelpCommandHandler,
IChainedCommandHandler<EscapeKeyCommandArgs>,
......
......@@ -38,6 +38,9 @@ namespace Microsoft.CodeAnalysis.Editor.CommandHandlers
[ContentType(ContentTypeNames.RoslynContentType)]
[Name(PredefinedCommandHandlerNames.SignatureHelpBeforeCompletion)]
[Order(Before = PredefinedCompletionNames.CompletionCommandHandler)]
// Ensure roslyn comes after LSP to allow them to provide results.
// https://github.com/dotnet/roslyn/issues/42338
[Order(After = "LSP SignatureHelpCommandHandler")]
internal class SignatureHelpBeforeCompletionCommandHandler :
AbstractSignatureHelpCommandHandler,
IChainedCommandHandler<TypeCharCommandArgs>,
......
......@@ -57,8 +57,6 @@
<PackageReference Include="Microsoft.VisualStudio.Utilities" Version="$(MicrosoftVisualStudioUtilitiesVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="$(MicrosoftVisualStudioValidationVersion)" />
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="$(SystemThreadingTasksDataflowVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="$(MicrosoftCodeAnalysisCSharpCodeFixTestingXUnitVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.XUnit" Version="$(MicrosoftCodeAnalysisVisualBasicCodeFixTestingXUnitVersion)" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\VisualStudio\Core\Def\Implementation\Remote\JsonRpcConnection.cs">
......
......@@ -171,14 +171,27 @@ public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
private static Action<CodeAction, ImmutableArray<Diagnostic>> GetRegisterCodeFixAction(
FixAllState fixAllState,
ConcurrentBag<(Diagnostic diagnostic, CodeAction action)> result)
=> (action, diagnostics) =>
{
if (action != null && action.EquivalenceKey == fixAllState.CodeActionEquivalenceKey)
{
result.Add((diagnostics.First(), action));
}
};
{
return (action, diagnostics) =>
{
using var _ = ArrayBuilder<CodeAction>.GetInstance(out var builder);
builder.Push(action);
while (builder.Count > 0)
{
var currentAction = builder.Pop();
if (currentAction is { EquivalenceKey: var equivalenceKey }
&& equivalenceKey == fixAllState.CodeActionEquivalenceKey)
{
result.Add((diagnostics.First(), currentAction));
}
foreach (var nestedAction in currentAction.NestedCodeActions)
{
builder.Push(nestedAction);
}
}
};
}
protected virtual Task AddProjectFixesAsync(
Project project, ImmutableArray<Diagnostic> diagnostics,
......
// 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.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests
{
public class BatchFixAllProviderTests
{
[Fact]
public async Task TestDefaultSelectionNestedFixers()
{
var testCode = @"
class TestClass {
int field = [|0|];
}
";
var fixedCode = $@"
class TestClass {{
int field = 1;
}}
";
// Three CodeFixProviders provide three actions
var codeFixes = ImmutableArray.Create(
ImmutableArray.Create(1),
ImmutableArray.Create(2),
ImmutableArray.Create(3));
await new CSharpTest(codeFixes, nested: true)
{
TestCode = testCode,
FixedCode = fixedCode,
}.RunAsync();
}
[DiagnosticAnalyzer(LanguageNames.CSharp)]
private class LiteralZeroAnalyzer : DiagnosticAnalyzer
{
internal static readonly DiagnosticDescriptor Descriptor =
new DiagnosticDescriptor("LiteralZero", "title", "message", "category", DiagnosticSeverity.Warning, isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor);
public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.RegisterSyntaxNodeAction(HandleNumericLiteralExpression, SyntaxKind.NumericLiteralExpression);
}
private void HandleNumericLiteralExpression(SyntaxNodeAnalysisContext context)
{
var node = (LiteralExpressionSyntax)context.Node;
if (node.Token.ValueText == "0")
{
context.ReportDiagnostic(Diagnostic.Create(Descriptor, node.Token.GetLocation()));
}
}
}
private class ReplaceZeroFix : CodeFixProvider
{
private readonly ImmutableArray<int> _replacements;
private readonly bool _nested;
public ReplaceZeroFix(ImmutableArray<int> replacements, bool nested)
{
Debug.Assert(replacements.All(replacement => replacement >= 0), $"Assertion failed: {nameof(replacements)}.All(replacement => replacement >= 0)");
_replacements = replacements;
_nested = nested;
}
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(LiteralZeroAnalyzer.Descriptor.Id);
public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
foreach (var diagnostic in context.Diagnostics)
{
var fixes = new List<CodeAction>();
foreach (var replacement in _replacements)
{
fixes.Add(CodeAction.Create(
"ThisToBase",
cancellationToken => CreateChangedDocument(context.Document, diagnostic.Location.SourceSpan, replacement, cancellationToken),
$"{nameof(ReplaceZeroFix)}_{replacement}"));
}
if (_nested)
{
#if NETCOREAPP2_0 || NET472
fixes = new List<CodeAction> { CodeAction.Create("Container", fixes.ToImmutableArray(), isInlinable: false) };
#else
throw new NotSupportedException("Nested code actions are not supported on this framework.");
#endif
}
foreach (var fix in fixes)
{
context.RegisterCodeFix(fix, diagnostic);
}
}
return Task.CompletedTask;
}
private async Task<Document> CreateChangedDocument(Document document, TextSpan sourceSpan, int replacement, CancellationToken cancellationToken)
{
var tree = await document.GetSyntaxTreeAsync(cancellationToken);
var root = await tree.GetRootAsync(cancellationToken);
var token = root.FindToken(sourceSpan.Start);
var newToken = SyntaxFactory.Literal(token.LeadingTrivia, replacement.ToString(), replacement, token.TrailingTrivia);
return document.WithSyntaxRoot(root.ReplaceToken(token, newToken));
}
}
private class CSharpTest : CodeFixTest<DefaultVerifier>
{
private readonly ImmutableArray<ImmutableArray<int>> _replacementGroups;
private readonly bool _nested;
public CSharpTest(ImmutableArray<ImmutableArray<int>> replacementGroups, bool nested = false)
{
_replacementGroups = replacementGroups;
_nested = nested;
}
public override string Language => LanguageNames.CSharp;
public override Type SyntaxKindType => typeof(SyntaxKind);
protected override string DefaultFileExt => "cs";
protected override CompilationOptions CreateCompilationOptions()
{
return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
}
protected override ParseOptions CreateParseOptions()
{
return new CSharpParseOptions(LanguageVersion.Default, DocumentationMode.Diagnose);
}
protected override IEnumerable<CodeFixProvider> GetCodeFixProviders()
{
foreach (var replacementGroup in _replacementGroups)
{
yield return new ReplaceZeroFix(replacementGroup, _nested);
}
}
protected override IEnumerable<DiagnosticAnalyzer> GetDiagnosticAnalyzers()
{
yield return new LiteralZeroAnalyzer();
}
}
}
}
......@@ -23,6 +23,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="$(MicrosoftCSharpVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing.XUnit" Version="$(MicrosoftCodeAnalysisCSharpCodeFixTestingXUnitVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.CodeFix.Testing.XUnit" Version="$(MicrosoftCodeAnalysisVisualBasicCodeFixTestingXUnitVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Composition" Version="$(MicrosoftVisualStudioCompositionVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="$(MicrosoftVisualStudioValidationVersion)" />
<PackageReference Include="System.Buffers" Version="$(SystemBuffersVersion)" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册