提交 0c3e63a4 编写于 作者: S Srivatsn Narayanan

Merging with upstream/master

......@@ -1032,6 +1032,24 @@ private void TestRoundTripChar(Char ch)
TestRoundTrip(ch, (w, v) => w.WriteChar(v), r => r.ReadChar());
}
[Fact]
public void TestRoundTripGuid()
{
TestRoundTripGuid(Guid.Empty);
TestRoundTripGuid(new Guid(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
TestRoundTripGuid(new Guid(0b10000000000000000000000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
TestRoundTripGuid(new Guid(0b10000000000000000000000000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
for (int i = 0; i < 10; i++)
{
TestRoundTripGuid(Guid.NewGuid());
}
}
private void TestRoundTripGuid(Guid guid)
{
TestRoundTrip(guid, (w, v) => w.WriteGuid(v), r => r.ReadGuid());
}
[Fact]
public void TestRoundTripStringCharacters()
{
......
......@@ -124,6 +124,17 @@ public void Dispose()
public ushort ReadUInt16() => _reader.ReadUInt16();
public string ReadString() => ReadStringValue();
public Guid ReadGuid()
{
var accessor = new ObjectWriter.GuidAccessor
{
Low64 = ReadInt64(),
High64 = ReadInt64()
};
return accessor.Guid;
}
public object ReadValue()
{
var oldDepth = _recursionDepth;
......
......@@ -119,6 +119,28 @@ public void Dispose()
public void WriteUInt16(ushort value) => _writer.Write(value);
public void WriteString(string value) => WriteStringValue(value);
/// <summary>
/// Used so we can easily grab the low/high 64bits of a guid for serialization.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
internal struct GuidAccessor
{
[FieldOffset(0)]
public Guid Guid;
[FieldOffset(0)]
public long Low64;
[FieldOffset(8)]
public long High64;
}
public void WriteGuid(Guid guid)
{
var accessor = new GuidAccessor { Guid = guid };
WriteInt64(accessor.Low64);
WriteInt64(accessor.High64);
}
public void WriteValue(object value)
{
Debug.Assert(value == null || !value.GetType().GetTypeInfo().IsEnum, "Enum should not be written with WriteValue. Write them as ints instead.");
......
......@@ -4077,7 +4077,7 @@ void M()
}
}";
await TestInRegularAndScriptAsync(code, expected, ignoreTrivia: false);
await TestAsync(code, expected, ignoreTrivia: false, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)]
......@@ -4106,7 +4106,7 @@ void M()
}
}";
await TestInRegularAndScriptAsync(code, expected, ignoreTrivia: false);
await TestAsync(code, expected, ignoreTrivia: false, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)]
......@@ -4136,7 +4136,7 @@ void M()
var t2 = (y: y1, x);
}
}";
await TestInRegularAndScriptAsync(code, expected, index: 1, ignoreTrivia: false);
await TestAsync(code, expected, index: 1, ignoreTrivia: false, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)]
......
// 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.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.UseInferredMemberName;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InferredMemberName
{
[Trait(Traits.Feature, Traits.Features.CodeActionsUseInferredMemberName)]
public class UseInferredMemberNameTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
{
internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
=> (new CSharpUseInferredMemberNameDiagnosticAnalyzer(), new CSharpUseInferredMemberNameCodeFixProvider());
private static readonly CSharpParseOptions s_parseOptions =
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest);
[Fact]
public async Task TestInferredTupleName()
{
await TestAsync(
@"
class C
{
void M()
{
int a = 1;
var t = ([||]a: a, 2);
}
}",
@"
class C
{
void M()
{
int a = 1;
var t = (a, 2);
}
}", parseOptions: s_parseOptions);
}
[Fact]
public async Task TestInferredTupleNameAfterCommaWithCSharp6()
{
await TestActionCountAsync(
@"
class C
{
void M()
{
int a = 2;
var t = (1, [||]a: a);
}
}", count: 0, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6)));
}
[Fact]
public async Task TestInferredTupleNameAfterCommaWithCSharp7()
{
await TestActionCountAsync(
@"
class C
{
void M()
{
int a = 2;
var t = (1, [||]a: a);
}
}", count: 0, parameters: new TestParameters(CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7)));
}
[Fact]
public async Task TestFixAllInferredTupleNameWithTrivia()
{
await TestAsync(
@"
class C
{
void M()
{
int a = 1;
int b = 2;
var t = ( /*before*/ {|FixAllInDocument:a:|} /*middle*/ a /*after*/, /*before*/ b: /*middle*/ b /*after*/);
}
}",
@"
class C
{
void M()
{
int a = 1;
int b = 2;
var t = ( /*before*/ /*middle*/ a /*after*/, /*before*/ /*middle*/ b /*after*/);
}
}", parseOptions: s_parseOptions, ignoreTrivia: false);
}
[Fact]
public async Task TestInferredAnonymousTypeMemberName()
{
await TestAsync(
@"
class C
{
void M()
{
int a = 1;
var t = new { [||]a=a, 2 };
}
}",
@"
class C
{
void M()
{
int a = 1;
var t = new { a, 2 };
}
}", parseOptions: s_parseOptions);
}
[Fact]
public async Task TestFixAllInferredAnonymousTypeMemberNameWithTrivia()
{
await TestAsync(
@"
class C
{
void M()
{
int a = 1;
int b = 2;
var t = new { /*before*/ {|FixAllInDocument:a =|} /*middle*/ a /*after*/, /*before*/ b = /*middle*/ b /*after*/ };
}
}",
@"
class C
{
void M()
{
int a = 1;
int b = 2;
var t = new { /*before*/ /*middle*/ a /*after*/, /*before*/ /*middle*/ b /*after*/ };
}
}", parseOptions: s_parseOptions, ignoreTrivia: false);
}
}
}
......@@ -100,6 +100,7 @@ public static class Features
public const string CodeActionsUseCoalesceExpression = "CodeActions.UseCoalesceExpression";
public const string CodeActionsUseCollectionInitializer = "CodeActions.UseCollectionInitializer";
public const string CodeActionsUseDefaultLiteral = "CodeActions.UseDefaultLiteral";
public const string CodeActionsUseInferredMemberName = "CodeActions.UseInferredMemberName";
public const string CodeActionsUseExpressionBody = "CodeActions.UseExpressionBody";
public const string CodeActionsUseImplicitType = "CodeActions.UseImplicitType";
public const string CodeActionsUseExplicitType = "CodeActions.UseExplicitType";
......
......@@ -9,8 +9,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings
Public MustInherit Class AbstractVisualBasicCodeActionTest
Inherits AbstractCodeActionTest
Private ReadOnly _compilationOptions As CompilationOptions =
New VisualBasicCompilationOptions(OutputKind.ConsoleApplication).WithOptionInfer(True)
Private ReadOnly _compilationOptions As VisualBasicCompilationOptions =
New VisualBasicCompilationOptions(OutputKind.ConsoleApplication).WithOptionInfer(True).WithParseOptions(New VisualBasicParseOptions(LanguageVersion.Latest))
Protected Overrides Function GetScriptOptions() As ParseOptions
Return TestOptions.Script
......@@ -31,7 +31,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings
Dim initialMarkupStr = initialMarkup.ConvertTestSourceTag()
Dim expectedStr = expected.ConvertTestSourceTag()
Await MyBase.TestAsync(initialMarkupStr, expectedStr, parseOptions:=Nothing, compilationOptions:=_compilationOptions, index:=index, ignoreTrivia:=ignoreTrivia)
Await MyBase.TestAsync(initialMarkupStr, expectedStr, parseOptions:=_compilationOptions.ParseOptions, compilationOptions:=_compilationOptions, index:=index, ignoreTrivia:=ignoreTrivia)
End Function
Protected Overloads Async Function TestMissingAsync(initialMarkup As XElement) As Threading.Tasks.Task
......
......@@ -2766,7 +2766,7 @@ Class C
End Sub
End Class
"
Await TestInRegularAndScriptAsync(code, expected, ignoreTrivia:=False)
Await TestAsync(code, expected, ignoreTrivia:=False, parseOptions:=TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)>
......@@ -2790,7 +2790,7 @@ Class C
End Sub
End Class
"
Await TestInRegularAndScriptAsync(code, expected, ignoreTrivia:=False)
Await TestAsync(code, expected, ignoreTrivia:=False, parseOptions:=TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)>
......@@ -2816,7 +2816,8 @@ Class C
End Sub
End Class
"
Await TestInRegularAndScriptAsync(code, expected, index:=1, ignoreTrivia:=False)
Await TestAsync(code, expected, index:=1, ignoreTrivia:=False,
parseOptions:=TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)>
......@@ -2862,7 +2863,7 @@ Class C
End Sub
End Class
"
Await TestInRegularAndScriptAsync(code, expected, ignoreTrivia:=False)
Await TestAsync(code, expected, ignoreTrivia:=False, parseOptions:=TestOptions.Regular.WithLanguageVersion(LanguageVersion.Latest))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)>
......
......@@ -10,8 +10,8 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
Public MustInherit Class AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
Inherits AbstractDiagnosticProviderBasedUserDiagnosticTest
Private ReadOnly _compilationOptions As CompilationOptions =
New VisualBasicCompilationOptions(OutputKind.ConsoleApplication).WithOptionInfer(True)
Private ReadOnly _compilationOptions As VisualBasicCompilationOptions =
New VisualBasicCompilationOptions(OutputKind.ConsoleApplication).WithOptionInfer(True).WithParseOptions(New VisualBasicParseOptions(LanguageVersion.Latest))
Protected Overrides Function GetScriptOptions() As ParseOptions
Return TestOptions.Script
......@@ -31,7 +31,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
Dim expectedStr = expected.ConvertTestSourceTag()
Await MyBase.TestAsync(initialMarkupStr, expectedStr,
parseOptions:=Nothing, compilationOptions:=_compilationOptions,
parseOptions:=_compilationOptions.ParseOptions, compilationOptions:=_compilationOptions,
index:=index, ignoreTrivia:=ignoreTrivia,
priority:=priority)
End Function
......
' 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.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.UseInferredMemberName
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.UseInferredMemberName
<Trait(Traits.Feature, Traits.Features.CodeActionsUseInferredMemberName)>
Public Class UseInferredMemberNameTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As (DiagnosticAnalyzer, CodeFixProvider)
Return (New VisualBasicUseInferredMemberNameDiagnosticAnalyzer(),
New VisualBasicUseInferredMemberNameCodeFixProvider())
End Function
Private Shared ReadOnly s_parseOptions As VisualBasicParseOptions =
VisualBasicParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)
<Fact>
Public Async Function TestInferredTupleName() As Task
Await TestAsync(
"
Class C
Sub M()
Dim a As Integer = 1
Dim t = ([||]a:=a, 2)
End Sub
End Class
",
"
Class C
Sub M()
Dim a As Integer = 1
Dim t = (a, 2)
End Sub
End Class
", parseOptions:=s_parseOptions)
End Function
<Fact>
Public Async Function TestInferredTupleName2() As Task
Await TestAsync(
"
Class C
Sub M()
Dim a As Integer = 2
Dim t = (1, [||]a:=a)
End Sub
End Class
",
"
Class C
Sub M()
Dim a As Integer = 2
Dim t = (1, a)
End Sub
End Class
", parseOptions:=s_parseOptions)
End Function
<Fact>
Public Async Function TestFixAllInferredTupleName() As Task
Await TestAsync(
"
Class C
Sub M()
Dim a As Integer = 1
Dim b As Integer = 2
Dim t = ({|FixAllInDocument:a:=|}a, b:=b)
End Sub
End Class
",
"
Class C
Sub M()
Dim a As Integer = 1
Dim b As Integer = 2
Dim t = (a, b)
End Sub
End Class
", parseOptions:=s_parseOptions)
End Function
<Fact>
Public Async Function TestInferredAnonymousTypeMemberName() As Task
Await TestAsync(
"
Class C
Sub M()
Dim a As Integer = 1
Dim t = New With {[|.a =|] a, .b = 2}
End Sub
End Class
",
"
Class C
Sub M()
Dim a As Integer = 1
Dim t = New With {a, .b = 2}
End Sub
End Class
", parseOptions:=s_parseOptions)
End Function
<Fact>
Public Async Function TestFixAllInferredAnonymousTypeMemberName() As Task
Await TestAsync(
"
Class C
Sub M()
Dim a As Integer = 1
Dim b As Integer = 2
Dim t = New With {{|FixAllInDocument:.a =|} a, .b = b}
End Sub
End Class
",
"
Class C
Sub M()
Dim a As Integer = 1
Dim b As Integer = 2
Dim t = New With { a, b }
End Sub
End Class
", parseOptions:=s_parseOptions)
End Function
End Class
End Namespace
......@@ -99,7 +99,7 @@ private static SyntaxNode GetSemanticBoundary(DefaultExpressionSyntax node)
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Simplify_default_expression, createChangedDocument)
: base(FeaturesResources.Simplify_default_expression, createChangedDocument, FeaturesResources.Simplify_default_expression)
{
}
}
......
// 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.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UseInferredMemberName
{
[ExportCodeFixProvider(LanguageNames.CSharp), Shared]
internal sealed class CSharpUseInferredMemberNameCodeFixProvider : SyntaxEditorBasedCodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; }
= ImmutableArray.Create(IDEDiagnosticIds.UseInferredMemberNameDiagnosticId);
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
context.RegisterCodeFix(new MyCodeAction(
c => FixAsync(context.Document, context.Diagnostics.First(), c)),
context.Diagnostics);
return SpecializedTasks.EmptyTask;
}
protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var root = editor.OriginalRoot;
foreach (var diagnostic in diagnostics)
{
var node = root.FindNode(diagnostic.Location.SourceSpan);
editor.RemoveNode(node, SyntaxRemoveOptions.KeepExteriorTrivia);
}
return SpecializedTasks.EmptyTask;
}
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Use_inferred_member_name, createChangedDocument, FeaturesResources.Use_inferred_member_name)
{
}
}
}
}
// 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.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Simplification;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.UseInferredMemberName
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal sealed class CSharpUseInferredMemberNameDiagnosticAnalyzer : AbstractCodeStyleDiagnosticAnalyzer
{
public CSharpUseInferredMemberNameDiagnosticAnalyzer()
: base(IDEDiagnosticIds.UseInferredMemberNameDiagnosticId,
new LocalizableResourceString(nameof(FeaturesResources.Use_inferred_member_name), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.Member_name_can_be_simplified), FeaturesResources.ResourceManager, typeof(FeaturesResources)))
{
}
public override DiagnosticAnalyzerCategory GetAnalyzerCategory()
=> DiagnosticAnalyzerCategory.SemanticSpanAnalysis;
public override bool OpenFileOnly(Workspace workspace)
=> false;
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.NameColon, SyntaxKind.NameEquals);
private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
{
var cancellationToken = context.CancellationToken;
var syntaxTree = context.Node.SyntaxTree;
var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();
if (optionSet == null)
{
return;
}
var parseOptions = (CSharpParseOptions)syntaxTree.Options;
switch (context.Node.Kind())
{
case SyntaxKind.NameColon:
ReportDiagnosticsIfNeeded((NameColonSyntax)context.Node, context, optionSet, syntaxTree);
break;
case SyntaxKind.NameEquals:
ReportDiagnosticsIfNeeded((NameEqualsSyntax)context.Node, context, optionSet, syntaxTree);
break;
}
}
private void ReportDiagnosticsIfNeeded(NameColonSyntax nameColon, SyntaxNodeAnalysisContext context, OptionSet optionSet, SyntaxTree syntaxTree)
{
if (!nameColon.IsParentKind(SyntaxKind.Argument))
{
return;
}
var argument = (ArgumentSyntax)nameColon.Parent;
var parseOptions = (CSharpParseOptions)syntaxTree.Options;
if (!optionSet.GetOption(CSharpCodeStyleOptions.PreferInferredTupleNames).Value ||
!CSharpInferredMemberNameReducer.CanSimplifyTupleElementName(argument, parseOptions))
{
return;
}
// Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CSharpCodeStyleOptions.PreferInferredTupleNames).Notification.Value),
nameColon.GetLocation()));
// Also fade out the part of the name-colon syntax
var fadeSpan = TextSpan.FromBounds(nameColon.Name.SpanStart, nameColon.ColonToken.Span.End);
context.ReportDiagnostic(
Diagnostic.Create(
UnnecessaryWithoutSuggestionDescriptor,
syntaxTree.GetLocation(fadeSpan)));
}
private void ReportDiagnosticsIfNeeded(NameEqualsSyntax nameEquals, SyntaxNodeAnalysisContext context, OptionSet optionSet, SyntaxTree syntaxTree)
{
if (!nameEquals.IsParentKind(SyntaxKind.AnonymousObjectMemberDeclarator))
{
return;
}
var anonCtor = (AnonymousObjectMemberDeclaratorSyntax)nameEquals.Parent;
if (!optionSet.GetOption(CSharpCodeStyleOptions.PreferInferredAnonymousTypeMemberNames).Value ||
!CSharpInferredMemberNameReducer.CanSimplifyAnonymousTypeMemberName(anonCtor))
{
return;
}
// Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CSharpCodeStyleOptions.PreferInferredAnonymousTypeMemberNames).Notification.Value),
nameEquals.GetLocation()));
// Also fade out the part of the name-equals syntax
var fadeSpan = TextSpan.FromBounds(nameEquals.Name.SpanStart, nameEquals.EqualsToken.Span.End);
context.ReportDiagnostic(
Diagnostic.Create(
UnnecessaryWithoutSuggestionDescriptor,
syntaxTree.GetLocation(fadeSpan)));
}
}
}
......@@ -50,6 +50,8 @@ internal static class IDEDiagnosticIds
public const string OrderModifiers = "IDE0036";
public const string UseInferredMemberNameDiagnosticId = "IDE0037";
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
public const string AnalyzerDependencyConflictId = "IDE1002";
......
......@@ -1908,6 +1908,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Member name can be simplified.
/// </summary>
internal static string Member_name_can_be_simplified {
get {
return ResourceManager.GetString("Member_name_can_be_simplified", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to method.
/// </summary>
......@@ -3426,6 +3435,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Use inferred member name.
/// </summary>
internal static string Use_inferred_member_name {
get {
return ResourceManager.GetString("Use_inferred_member_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use local version &apos;{0}&apos;.
/// </summary>
......
......@@ -1243,6 +1243,12 @@ This version used in: {2}</value>
</data>
<data name="default_expression_can_be_simplified" xml:space="preserve">
<value>'default' expression can be simplified</value>
</data>
<data name="Use_inferred_member_name" xml:space="preserve">
<value>Use inferred member name</value>
</data>
<data name="Member_name_can_be_simplified" xml:space="preserve">
<value>Member name can be simplified</value>
</data>
<data name="Reported_diagnostic_0_has_a_source_location_in_file_1_which_is_not_part_of_the_compilation_being_analyzed" xml:space="preserve">
<value>Reported diagnostic '{0}' has a source location in file '{1}', which is not part of the compilation being analyzed.</value>
......
' 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 System.Composition
Imports System.Threading
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editing
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.UseInferredMemberName
<ExportCodeFixProvider(LanguageNames.VisualBasic), [Shared]>
Friend Class VisualBasicUseInferredMemberNameCodeFixProvider
Inherits SyntaxEditorBasedCodeFixProvider
Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) =
ImmutableArray.Create(IDEDiagnosticIds.UseInferredMemberNameDiagnosticId)
Public Overrides Function RegisterCodeFixesAsync(context As CodeFixContext) As Task
context.RegisterCodeFix(New MyCodeAction(
Function(c) FixAsync(context.Document, context.Diagnostics.First(), c)),
context.Diagnostics)
Return SpecializedTasks.EmptyTask
End Function
Protected Overrides Function FixAllAsync(document As Document, diagnostics As ImmutableArray(Of Diagnostic),
editor As SyntaxEditor, cancellationToken As CancellationToken) As Task
Dim root = editor.OriginalRoot
For Each diagnostic In diagnostics
Dim node = root.FindNode(diagnostic.Location.SourceSpan)
Select Case node.Kind
Case SyntaxKind.NameColonEquals
editor.RemoveNode(node, SyntaxRemoveOptions.KeepExteriorTrivia)
Exit Select
Case SyntaxKind.NamedFieldInitializer
Dim namedFieldInitializer = DirectCast(node, NamedFieldInitializerSyntax)
Dim inferredFieldInitializer = SyntaxFactory.InferredFieldInitializer(namedFieldInitializer.Expression).
WithTriviaFrom(namedFieldInitializer)
editor.ReplaceNode(namedFieldInitializer, inferredFieldInitializer)
Exit Select
End Select
Next
Return SpecializedTasks.EmptyTask
End Function
Private Class MyCodeAction
Inherits CodeAction.DocumentChangeAction
Public Sub New(createChangedDocument As Func(Of CancellationToken, Task(Of Document)))
MyBase.New(FeaturesResources.Use_inferred_member_name, createChangedDocument, FeaturesResources.Use_inferred_member_name)
End Sub
End Class
End Class
End Namespace
' 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.CodeStyle
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.CodeStyle
Imports Microsoft.CodeAnalysis.VisualBasic.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.UseInferredMemberName
''' <summary>
''' Offers to simplify tuple expressions and anonymous types with redundant names, such as `(a:=a, b:=b)` or `New With {.a = a, .b = b}`
''' </summary>
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
Friend Class VisualBasicUseInferredMemberNameDiagnosticAnalyzer
Inherits AbstractCodeStyleDiagnosticAnalyzer
Public Sub New()
MyBase.New(IDEDiagnosticIds.UseInferredMemberNameDiagnosticId,
New LocalizableResourceString(NameOf(FeaturesResources.Use_inferred_member_name), FeaturesResources.ResourceManager, GetType(FeaturesResources)),
New LocalizableResourceString(NameOf(FeaturesResources.Member_name_can_be_simplified), FeaturesResources.ResourceManager, GetType(FeaturesResources)))
End Sub
Public Overrides Function GetAnalyzerCategory() As DiagnosticAnalyzerCategory
Return DiagnosticAnalyzerCategory.SemanticSpanAnalysis
End Function
Public Overrides Function OpenFileOnly(workspace As Workspace) As Boolean
Return False
End Function
Protected Overrides Sub InitializeWorker(context As AnalysisContext)
context.RegisterSyntaxNodeAction(Sub(c As SyntaxNodeAnalysisContext) AnalyzeSyntax(c),
SyntaxKind.NameColonEquals, SyntaxKind.NamedFieldInitializer)
End Sub
Private Sub AnalyzeSyntax(context As SyntaxNodeAnalysisContext)
Dim cancellationToken = context.CancellationToken
Dim syntaxTree = context.Node.SyntaxTree
Dim optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult()
If optionSet Is Nothing Then
Return
End If
Dim parseOptions = DirectCast(syntaxTree.Options, VisualBasicParseOptions)
Select Case context.Node.Kind()
Case SyntaxKind.NameColonEquals
ReportDiagnosticsIfNeeded(DirectCast(context.Node, NameColonEqualsSyntax), context, optionSet, syntaxTree, parseOptions)
Exit Select
Case SyntaxKind.NamedFieldInitializer
ReportDiagnosticsIfNeeded(DirectCast(context.Node, NamedFieldInitializerSyntax), context, optionSet, syntaxTree)
Exit Select
End Select
End Sub
Private Sub ReportDiagnosticsIfNeeded(nameColonEquals As NameColonEqualsSyntax, context As SyntaxNodeAnalysisContext,
optionSet As OptionSet, syntaxTree As SyntaxTree, parseOptions As VisualBasicParseOptions)
If Not nameColonEquals.IsParentKind(SyntaxKind.SimpleArgument) Then
Return
End If
Dim argument = DirectCast(nameColonEquals.Parent, SimpleArgumentSyntax)
If Not optionSet.GetOption(VisualBasicCodeStyleOptions.PreferInferredTupleNames).Value OrElse
Not VisualBasicInferredMemberNameReducer.CanSimplifyTupleName(argument, parseOptions) Then
Return
End If
' Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(VisualBasicCodeStyleOptions.PreferInferredTupleNames).Notification.Value),
nameColonEquals.GetLocation()))
' Also fade out the part of the name-colon-equals syntax
Dim fadeSpan = TextSpan.FromBounds(nameColonEquals.Name.SpanStart, nameColonEquals.ColonEqualsToken.Span.End)
context.ReportDiagnostic(
Diagnostic.Create(
UnnecessaryWithoutSuggestionDescriptor,
syntaxTree.GetLocation(fadeSpan)))
End Sub
Private Sub ReportDiagnosticsIfNeeded(fieldInitializer As NamedFieldInitializerSyntax, context As SyntaxNodeAnalysisContext,
optionSet As OptionSet, syntaxTree As SyntaxTree)
If Not optionSet.GetOption(VisualBasicCodeStyleOptions.PreferInferredAnonymousTypeMemberNames).Value OrElse
Not VisualBasicInferredMemberNameReducer.CanSimplifyNamedFieldInitializer(fieldInitializer) Then
Return
End If
Dim fadeSpan = TextSpan.FromBounds(fieldInitializer.Name.SpanStart, fieldInitializer.EqualsToken.Span.End)
' Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(VisualBasicCodeStyleOptions.PreferInferredAnonymousTypeMemberNames).Notification.Value),
syntaxTree.GetLocation(fadeSpan)))
' Also fade out the part of the name-equals syntax
context.ReportDiagnostic(
Diagnostic.Create(
UnnecessaryWithoutSuggestionDescriptor,
syntaxTree.GetLocation(fadeSpan)))
End Sub
End Class
End Namespace
......@@ -440,6 +440,42 @@ class Customer
void DoWork(CancellationToken cancellationToken = default(CancellationToken)) {{ }}
//]
}}
";
private static readonly string s_preferInferredTupleName = $@"
using System.Threading;
class Customer
{{
public Customer(int age, string name)
{{
//[
// {ServicesVSResources.Prefer_colon}
var tuple = (age, name);
// {ServicesVSResources.Over_colon}
var tuple = (age: age, name: name);
//]
}}
}}
";
private static readonly string s_preferInferredAnonymousTypeMemberName = $@"
using System.Threading;
class Customer
{{
public Customer(int age, string name)
{{
//[
// {ServicesVSResources.Prefer_colon}
var anon = new {{ age, name }};
// {ServicesVSResources.Over_colon}
var anon = new {{ age = age, name = name }};
//]
}}
}}
";
private static readonly string s_preferInlinedVariableDeclaration = $@"
......@@ -709,6 +745,8 @@ internal StyleViewModel(OptionSet optionSet, IServiceProvider serviceProvider) :
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck, CSharpVSResources.Prefer_pattern_matching_over_as_with_null_check, s_preferPatternMatchingOverAsWithNullCheck, s_preferPatternMatchingOverAsWithNullCheck, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferExplicitTupleNames, ServicesVSResources.Prefer_explicit_tuple_name, s_preferExplicitTupleName, s_preferExplicitTupleName, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferSimpleDefaultExpression, ServicesVSResources.Prefer_simple_default_expression, s_preferSimpleDefaultExpression, s_preferSimpleDefaultExpression, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferInferredTupleNames, ServicesVSResources.Prefer_inferred_tuple_names, s_preferInferredTupleName, s_preferInferredTupleName, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new BooleanCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferInferredAnonymousTypeMemberNames, ServicesVSResources.Prefer_inferred_anonymous_type_member_names, s_preferInferredAnonymousTypeMemberName, s_preferInferredAnonymousTypeMemberName, this, optionSet, expressionPreferencesGroupTitle));
AddExpressionBodyOptions(optionSet, expressionPreferencesGroupTitle);
......
......@@ -1612,6 +1612,24 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Prefer inferred anonymous type member names.
/// </summary>
internal static string Prefer_inferred_anonymous_type_member_names {
get {
return ResourceManager.GetString("Prefer_inferred_anonymous_type_member_names", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Prefer inferred tuple element names.
/// </summary>
internal static string Prefer_inferred_tuple_names {
get {
return ResourceManager.GetString("Prefer_inferred_tuple_names", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Prefer inlined variable declaration.
/// </summary>
......
......@@ -921,6 +921,12 @@ Additional information: {1}</value>
<data name="Prefer_simple_default_expression" xml:space="preserve">
<value>Prefer simple 'default' expression</value>
</data>
<data name="Prefer_inferred_tuple_names" xml:space="preserve">
<value>Prefer inferred tuple element names</value>
</data>
<data name="Prefer_inferred_anonymous_type_member_names" xml:space="preserve">
<value>Prefer inferred anonymous type member names</value>
</data>
<data name="Preview_pane" xml:space="preserve">
<value>Preview pane</value>
</data>
......
......@@ -5,6 +5,7 @@ Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.CodeStyle
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic.CodeStyle
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Options
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.Options
......@@ -204,6 +205,34 @@ Class Customer
//]
End Sub
end class
"
Private Shared ReadOnly s_preferInferredTupleName As String = $"
Class Customer
Public Sub New(name as String, age As Integer)
//[
' {ServicesVSResources.Prefer_colon}
Dim tuple = (name, age)
' {ServicesVSResources.Over_colon}
Dim tuple = (name:=name, age:=age)
//]
End Sub
end class
"
Private Shared ReadOnly s_preferInferredAnonymousTypeMemberName As String = $"
Class Customer
Public Sub New(name as String, age As Integer)
//[
' {ServicesVSResources.Prefer_colon}
Dim anon = New With {{ name, age }}
' {ServicesVSResources.Over_colon}
Dim anon = New With {{ .name = name, .age = age }}
//]
End Sub
end class
"
Private Shared ReadOnly s_preferCoalesceExpression As String = $"
......@@ -281,6 +310,8 @@ End Class"
Me.CodeStyleItems.Add(New BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferObjectInitializer, ServicesVSResources.Prefer_object_initializer, s_preferObjectInitializer, s_preferObjectInitializer, Me, optionSet, expressionPreferencesGroupTitle))
Me.CodeStyleItems.Add(New BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferCollectionInitializer, ServicesVSResources.Prefer_collection_initializer, s_preferCollectionInitializer, s_preferCollectionInitializer, Me, optionSet, expressionPreferencesGroupTitle))
Me.CodeStyleItems.Add(New BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferExplicitTupleNames, ServicesVSResources.Prefer_explicit_tuple_name, s_preferExplicitTupleName, s_preferExplicitTupleName, Me, optionSet, expressionPreferencesGroupTitle))
Me.CodeStyleItems.Add(New BooleanCodeStyleOptionViewModel(VisualBasicCodeStyleOptions.PreferInferredTupleNames, ServicesVSResources.Prefer_inferred_tuple_names, s_preferInferredTupleName, s_preferInferredTupleName, Me, optionSet, expressionPreferencesGroupTitle))
Me.CodeStyleItems.Add(New BooleanCodeStyleOptionViewModel(VisualBasicCodeStyleOptions.PreferInferredAnonymousTypeMemberNames, ServicesVSResources.Prefer_inferred_anonymous_type_member_names, s_preferInferredAnonymousTypeMemberName, s_preferInferredAnonymousTypeMemberName, Me, optionSet, expressionPreferencesGroupTitle))
' nothing preferences
Me.CodeStyleItems.Add(New BooleanCodeStyleOptionViewModel(CodeStyleOptions.PreferCoalesceExpression, ServicesVSResources.Prefer_coalesce_expression, s_preferCoalesceExpression, s_preferCoalesceExpression, Me, optionSet, nothingPreferencesGroupTitle))
......
......@@ -142,6 +142,18 @@ internal static class CSharpCodeStyleOptions
EditorConfigStorageLocation.ForBoolCodeStyleOption("csharp_prefer_simple_default_expression"),
new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferSimpleDefaultExpression)}")});
public static readonly Option<CodeStyleOption<bool>> PreferInferredTupleNames = new Option<CodeStyleOption<bool>>(
nameof(CodeStyleOptions), nameof(PreferInferredTupleNames), defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement,
storageLocations: new OptionStorageLocation[] {
EditorConfigStorageLocation.ForBoolCodeStyleOption("csharp_prefer_inferred_tuple_names"),
new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferInferredTupleNames)}")});
public static readonly Option<CodeStyleOption<bool>> PreferInferredAnonymousTypeMemberNames = new Option<CodeStyleOption<bool>>(
nameof(CodeStyleOptions), nameof(PreferInferredAnonymousTypeMemberNames), defaultValue: CodeStyleOptions.TrueWithSuggestionEnforcement,
storageLocations: new OptionStorageLocation[] {
EditorConfigStorageLocation.ForBoolCodeStyleOption("csharp_prefer_inferred_anonymous_type_member_names"),
new RoamingProfileStorageLocation($"TextEditor.CSharp.Specific.{nameof(PreferInferredAnonymousTypeMemberNames)}")});
private static readonly SyntaxKind[] s_preferredModifierOrderDefault =
{
SyntaxKind.PublicKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword,
......@@ -172,6 +184,8 @@ public static IEnumerable<Option<CodeStyleOption<bool>>> GetCodeStyleOptions()
yield return PreferPatternMatchingOverIsWithCastCheck;
yield return PreferBraces;
yield return PreferSimpleDefaultExpression;
yield return PreferInferredTupleNames;
yield return PreferInferredAnonymousTypeMemberNames;
}
public static IEnumerable<Option<CodeStyleOption<ExpressionBodyPreference>>> GetExpressionBodyOptions()
......
// 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 Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Simplification
{
......@@ -13,6 +15,32 @@ private class Rewriter : AbstractReductionRewriter
public Rewriter(ObjectPool<IReductionRewriter> pool)
: base(pool)
{
s_simplifyTupleName = SimplifyTupleName;
}
private readonly Func<ArgumentSyntax, SemanticModel, OptionSet, CancellationToken, ArgumentSyntax> s_simplifyTupleName;
private ArgumentSyntax SimplifyTupleName(ArgumentSyntax node, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken)
{
if (CanSimplifyTupleElementName(node, this.ParseOptions))
{
return node.WithNameColon(null).WithTriviaFrom(node);
}
return node;
}
private static readonly Func<AnonymousObjectMemberDeclaratorSyntax, SemanticModel, OptionSet, CancellationToken, SyntaxNode> s_simplifyAnonymousTypeMemberName = SimplifyAnonymousTypeMemberName;
private static SyntaxNode SimplifyAnonymousTypeMemberName(AnonymousObjectMemberDeclaratorSyntax node, SemanticModel semanticModel, OptionSet optionSet, CancellationToken canellationToken)
{
if (CanSimplifyAnonymousTypeMemberName(node))
{
return node.WithNameEquals(null).WithTriviaFrom(node);
}
return node;
}
public override SyntaxNode VisitArgument(ArgumentSyntax node)
......
// 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 Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Simplification
{
......@@ -24,43 +20,42 @@ public CSharpInferredMemberNameReducer() : base(s_pool)
{
}
private static readonly Func<ArgumentSyntax, SemanticModel, OptionSet, CancellationToken, ArgumentSyntax> s_simplifyTupleName = SimplifyTupleName;
private static ArgumentSyntax SimplifyTupleName(ArgumentSyntax node, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken)
internal static bool CanSimplifyTupleElementName(ArgumentSyntax node, CSharpParseOptions parseOptions)
{
// Tuple elements are arguments in a tuple expression
if (node.NameColon == null || !node.IsParentKind(SyntaxKind.TupleExpression))
{
return node;
return false;
}
var inferredName = node.Expression.TryGetInferredMemberName();
if (parseOptions.LanguageVersion < LanguageVersion.CSharp7_1)
{
return false;
}
var inferredName = node.Expression.TryGetInferredMemberName();
if (inferredName == null || inferredName != node.NameColon.Name.Identifier.ValueText)
{
return node;
return false;
}
return node.WithNameColon(null).WithTriviaFrom(node);
return true;
}
private static readonly Func<AnonymousObjectMemberDeclaratorSyntax, SemanticModel, OptionSet, CancellationToken, SyntaxNode> s_simplifyAnonymousTypeMemberName = SimplifyAnonymousTypeMemberName;
private static SyntaxNode SimplifyAnonymousTypeMemberName(AnonymousObjectMemberDeclaratorSyntax node, SemanticModel semanticModel, OptionSet optionSet, CancellationToken canellationToken)
internal static bool CanSimplifyAnonymousTypeMemberName(AnonymousObjectMemberDeclaratorSyntax node)
{
if (node.NameEquals == null)
{
return node;
return false;
}
var inferredName = node.Expression.TryGetInferredMemberName();
if (inferredName == null || inferredName != node.NameEquals.Name.Identifier.ValueText)
{
return node;
return false;
}
return node.WithNameEquals(null).WithTriviaFrom(node);
return true;
}
}
}
......@@ -234,7 +234,7 @@ private void WriteAnalyzerFileReferenceMvid(AnalyzerFileReference reference, Obj
var mvidHandle = metadataReader.GetModuleDefinition().Mvid;
var guid = metadataReader.GetGuid(mvidHandle);
writer.WriteValue(guid.ToByteArray());
writer.WriteGuid(guid);
}
}
catch
......@@ -312,7 +312,7 @@ private void WriteMvidTo(ModuleMetadata metadata, ObjectWriter writer, Cancellat
var mvidHandle = metadataReader.GetModuleDefinition().Mvid;
var guid = metadataReader.GetGuid(mvidHandle);
writer.WriteValue(guid.ToByteArray());
writer.WriteGuid(guid);
}
private void WritePortableExecutableReferenceTo(
......
......@@ -102,7 +102,7 @@ void IObjectWritable.WriteTo(ObjectWriter writer)
{
ProjectId.WriteTo(writer);
writer.WriteValue(Id.ToByteArray());
writer.WriteGuid(Id);
writer.WriteString(DebugName);
}
......@@ -110,7 +110,7 @@ internal static DocumentId ReadFrom(ObjectReader reader)
{
var projectId = ProjectId.ReadFrom(reader);
var guid = new Guid((byte[])reader.ReadValue());
var guid = reader.ReadGuid();
var debugName = reader.ReadString();
return CreateFromSerialized(projectId, guid, debugName);
......
......@@ -86,13 +86,13 @@ public override int GetHashCode()
void IObjectWritable.WriteTo(ObjectWriter writer)
{
writer.WriteValue(Id.ToByteArray());
writer.WriteGuid(Id);
writer.WriteString(DebugName);
}
internal static ProjectId ReadFrom(ObjectReader reader)
{
var guid = new Guid((byte[])reader.ReadValue());
var guid = reader.ReadGuid();
var debugName = reader.ReadString();
return CreateFromSerialized(guid, debugName);
......
......@@ -83,13 +83,13 @@ public override int GetHashCode()
void IObjectWritable.WriteTo(ObjectWriter writer)
{
writer.WriteValue(Id.ToByteArray());
writer.WriteGuid(Id);
writer.WriteString(DebugName);
}
internal static SolutionId ReadFrom(ObjectReader reader)
{
var guid = new Guid((byte[])reader.ReadValue());
var guid = reader.ReadGuid();
var debugName = reader.ReadString();
return CreateFromSerialized(guid, debugName);
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' 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.Generic
imports System.Collections.Immutable
......@@ -23,5 +23,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeStyle
New CodeStyleOption(Of String)(String.Join(",", PreferredModifierOrderDefault.Select(AddressOf SyntaxFacts.GetText)), NotificationOption.None),
EditorConfigStorageLocation.ForStringCodeStyleOption("visual_basic_preferred_modifier_order"),
New RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.{NameOf(PreferredModifierOrder)}"))
Public ReadOnly PreferInferredTupleNames As [Option](Of CodeStyleOption(Of Boolean)) = New [Option](Of CodeStyleOption(Of Boolean))(
NameOf(CodeStyleOptions), NameOf(PreferInferredTupleNames),
CodeStyleOptions.TrueWithSuggestionEnforcement,
EditorConfigStorageLocation.ForStringCodeStyleOption("visual_basic_prefer_inferred_tuple_names"),
New RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.{NameOf(PreferInferredTupleNames)}"))
Public ReadOnly PreferInferredAnonymousTypeMemberNames As [Option](Of CodeStyleOption(Of Boolean)) = New [Option](Of CodeStyleOption(Of Boolean))(
NameOf(CodeStyleOptions), NameOf(PreferInferredAnonymousTypeMemberNames),
CodeStyleOptions.TrueWithSuggestionEnforcement,
EditorConfigStorageLocation.ForStringCodeStyleOption("visual_basic_prefer_inferred_anonymous_type_member_names"),
New RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.{NameOf(PreferInferredAnonymousTypeMemberNames)}"))
End Module
End Namespace
\ No newline at end of file
End Namespace
......@@ -51,6 +51,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Execution
Public Overrides Sub WriteTo(options As OptionSet, writer As ObjectWriter, cancellationToken As CancellationToken)
WriteOptionSetTo(options, LanguageNames.VisualBasic, writer, cancellationToken)
WriteOptionTo(options, VisualBasicCodeStyleOptions.PreferredModifierOrder, writer, cancellationToken)
WriteOptionTo(options, VisualBasicCodeStyleOptions.PreferInferredTupleNames, writer, cancellationToken)
WriteOptionTo(options, VisualBasicCodeStyleOptions.PreferInferredAnonymousTypeMemberNames, writer, cancellationToken)
End Sub
Public Overrides Function ReadCompilationOptionsFrom(reader As ObjectReader, cancellationToken As CancellationToken) As CompilationOptions
......@@ -129,6 +131,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Execution
options = ReadOptionSetFrom(options, LanguageNames.VisualBasic, reader, cancellationToken)
options = ReadOptionFrom(options, VisualBasicCodeStyleOptions.PreferredModifierOrder, reader, cancellationToken)
options = ReadOptionFrom(options, VisualBasicCodeStyleOptions.PreferInferredTupleNames, reader, cancellationToken)
options = ReadOptionFrom(options, VisualBasicCodeStyleOptions.PreferInferredAnonymousTypeMemberNames, reader, cancellationToken)
Return options
End Function
......
......@@ -15,7 +15,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification
Private ReadOnly _pool As ObjectPool(Of IReductionRewriter)
Protected CancellationToken As CancellationToken
Private _parseOptions As ParseOptions
Protected Property ParseOptions As VisualBasicParseOptions
Private _simplificationOptions As OptionSet
Private ReadOnly _processedParentNodes As HashSet(Of SyntaxNode) = New HashSet(Of SyntaxNode)()
......@@ -29,13 +29,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification
End Sub
Public Sub Initialize(parseOptions As ParseOptions, optionSet As OptionSet, cancellationToken As CancellationToken) Implements IReductionRewriter.Initialize
_parseOptions = parseOptions
Me.ParseOptions = DirectCast(parseOptions, VisualBasicParseOptions)
_simplificationOptions = optionSet
cancellationToken = cancellationToken
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
_parseOptions = Nothing
ParseOptions = Nothing
_simplificationOptions = Nothing
CancellationToken = CancellationToken.None
_processedParentNodes.Clear()
......
' 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.Threading
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -14,6 +15,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification
MyBase.New(pool)
End Sub
Private ReadOnly s_simplifyTupleName As Func(Of SimpleArgumentSyntax, SemanticModel, OptionSet, CancellationToken, SimpleArgumentSyntax) = AddressOf SimplifyTupleName
Private Function SimplifyTupleName(
node As SimpleArgumentSyntax,
semanticModel As SemanticModel,
optionSet As OptionSet,
cancellationToken As CancellationToken
) As SimpleArgumentSyntax
If CanSimplifyTupleName(node, ParseOptions) Then
Return node.WithNameColonEquals(Nothing).WithTriviaFrom(node)
End If
Return node
End Function
Public Overrides Function VisitSimpleArgument(node As SimpleArgumentSyntax) As SyntaxNode
CancellationToken.ThrowIfCancellationRequested()
......
......@@ -4,6 +4,7 @@ Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic.CodeStyle
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification
......@@ -22,42 +23,44 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification
MyBase.New(s_pool)
End Sub
Private Shared ReadOnly s_simplifyTupleName As Func(Of SimpleArgumentSyntax, SemanticModel, OptionSet, CancellationToken, SimpleArgumentSyntax) = AddressOf SimplifyTupleName
Private Shared Function SimplifyTupleName(
node As SimpleArgumentSyntax,
semanticModel As SemanticModel,
optionSet As OptionSet,
cancellationToken As CancellationToken
) As SimpleArgumentSyntax
Friend Shared Function CanSimplifyTupleName(node As SimpleArgumentSyntax, parseOptions As VisualBasicParseOptions) As Boolean
' Tuple elements are arguments in a tuple expression
If node.NameColonEquals Is Nothing OrElse Not node.IsParentKind(SyntaxKind.TupleExpression) Then
Return node
Return False
End If
Dim inferredName = node.Expression.TryGetInferredMemberName()
If parseOptions.LanguageVersion < LanguageVersion.VisualBasic15_3 Then
Return False
End If
Dim inferredName = node.Expression.TryGetInferredMemberName()
If inferredName Is Nothing OrElse
Not CaseInsensitiveComparison.Equals(inferredName, node.NameColonEquals.Name.Identifier.ValueText) Then
Return node
Return False
End If
Return node.WithNameColonEquals(Nothing).WithTriviaFrom(node)
Return True
End Function
Private Shared ReadOnly s_simplifyNamedFieldInitializer As Func(Of NamedFieldInitializerSyntax, SemanticModel, OptionSet, CancellationToken, SyntaxNode) = AddressOf SimplifyNamedFieldInitializer
Private Shared Function SimplifyNamedFieldInitializer(node As NamedFieldInitializerSyntax, arg2 As SemanticModel, arg3 As OptionSet, arg4 As CancellationToken) As SyntaxNode
Dim inferredName = node.Expression.TryGetInferredMemberName()
Private Shared Function SimplifyNamedFieldInitializer(node As NamedFieldInitializerSyntax, arg2 As SemanticModel, optionSet As OptionSet, arg4 As CancellationToken) As SyntaxNode
If CanSimplifyNamedFieldInitializer(node) Then
Return SyntaxFactory.InferredFieldInitializer(node.Expression).WithTriviaFrom(node)
End If
Return node
End Function
Friend Shared Function CanSimplifyNamedFieldInitializer(node As NamedFieldInitializerSyntax) As Boolean
Dim inferredName = node.Expression.TryGetInferredMemberName()
If inferredName Is Nothing OrElse
Not CaseInsensitiveComparison.Equals(inferredName, node.Name.Identifier.ValueText) Then
Return node
Return False
End If
Return SyntaxFactory.InferredFieldInitializer(node.Expression).WithTriviaFrom(node)
Return True
End Function
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册