提交 dc2020ba 编写于 作者: C CyrusNajmabadi

Merge branch 'master' into extractMethodVar

......@@ -145,8 +145,10 @@
<AssemblyName>Roslyn.Services.Editor.CSharp.UnitTests</AssemblyName>
<RoslynProjectType>UnitTest</RoslynProjectType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
......@@ -336,6 +338,7 @@
<Compile Include="UseCollectionInitializer\UseCollectionInitializerTests.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionForNullableTests.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionTests.cs" />
<Compile Include="UseExplicitTupleName\UseExplicitTupleNameTests.cs" />
<Compile Include="UseNullPropagation\UseNullPropagationTests.cs" />
<Compile Include="UsePatternMatching\CSharpIsAndCastCheckTests_FixAllTests.cs" />
<Compile Include="UsePatternMatching\CSharpIsAndCastCheckTests.cs" />
......@@ -600,4 +603,4 @@
<InternalsVisibleToTest Include="Roslyn.Services.Editor.CSharp.UnitTests2" />
</ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" />
</Project>
</Project>
\ No newline at end of file
// 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.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.UseExplicitTupleName;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseExplicitTupleName
{
public class UseExplicitTupleNameTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
{
internal override Tuple<DiagnosticAnalyzer, CodeFixProvider> CreateDiagnosticProviderAndFixer(Workspace workspace)
{
return Tuple.Create<DiagnosticAnalyzer, CodeFixProvider>(
new UseExplicitTupleNameDiagnosticAnalyzer(),
new UseExplicitTupleNameCodeFixProvider());
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestNamedTuple1()
{
await TestAsync(
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
var v2 = v1.[|Item1|];
}
}",
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
var v2 = v1.i;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestInArgument()
{
await TestAsync(
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
Foo(v1.[|Item1|]);
}
void Foo(int i) { }
}",
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
Foo(v1.i);
}
void Foo(int i) { }
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestNamedTuple2()
{
await TestAsync(
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
var v2 = v1.[|Item2|];
}
}",
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
var v2 = v1.s;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestMissingOnMatchingName1()
{
await TestMissingAsync(
@"
class C
{
void M()
{
(int, string s) v1 = default((int, string));
var v2 = v1.[|Item1|];
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestMissingOnMatchingName2()
{
await TestMissingAsync(
@"
class C
{
void M()
{
(int Item1, string s) v1 = default((int, string));
var v2 = v1.[|Item1|];
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestWrongCasing()
{
await TestAsync(
@"
class C
{
void M()
{
(int item1, string s) v1 = default((int, string));
var v2 = v1.[|Item1|];
}
}",
@"
class C
{
void M()
{
(int item1, string s) v1 = default((int, string));
var v2 = v1.item1;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestFixAll1()
{
await TestAsync(
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
var v2 = v1.{|FixAllInDocument:Item1|};
var v3 = v1.Item2;
}
}",
@"
class C
{
void M()
{
(int i, string s) v1 = default((int, string));
var v2 = v1.i;
var v3 = v1.s;
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)]
public async Task TestFixAll2()
{
await TestAsync(
@"
class C
{
void M()
{
(int i, int s) v1 = default((int, int));
v1.{|FixAllInDocument:Item1|} = v1.Item2;
}
}",
@"
class C
{
void M()
{
(int i, int s) v1 = default((int, int));
v1.i = v1.s;
}
}");
}
}
}
......@@ -88,6 +88,7 @@ public static class Features
public const string CodeActionsUseExpressionBody = "CodeActions.UseExpressionBody";
public const string CodeActionsUseImplicitType = "CodeActions.UseImplicitType";
public const string CodeActionsUseExplicitType = "CodeActions.UseExplicitType";
public const string CodeActionsUseExplicitTupleName = "CodeActions.UseExplicitTupleName";
public const string CodeActionsUseFrameworkType = "CodeActions.UseFrameworkType";
public const string CodeActionsUseNullPropagation = "CodeActions.UseNullPropagation";
public const string CodeActionsUseObjectInitializer = "CodeActions.UseObjectInitializer";
......
......@@ -576,6 +576,7 @@
<Compile Include="TypeInferrer\TypeInferrerTests.vb" />
<Compile Include="UseCollectionInitializer\UseCollectionInitializerTests.vb" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionForNullableTests.vb" />
<Compile Include="UseExplicitTupleName\UseExplicitTupleNameTests.vb" />
<Compile Include="UseObjectInitializer\UseObjectInitializerTests.vb" />
<Compile Include="Utilities\CodeSnippets.vb" />
<Compile Include="Utils.vb" />
......@@ -701,4 +702,4 @@
</Content>
</ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" />
</Project>
</Project>
\ No newline at end of file
' 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.UseExplicitTupleName
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.UseExplicitTupleName
Public Class UseExplicitTupleNameTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As Tuple(Of DiagnosticAnalyzer, CodeFixProvider)
Return Tuple.Create(Of DiagnosticAnalyzer, CodeFixProvider)(
New UseExplicitTupleNameDiagnosticAnalyzer(),
New UseExplicitTupleNameCodeFixProvider())
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestNamedTuple1() As Task
Await TestAsync(
"
class C
Sub M()
dim v1 as (i as integer, s as string)
dim v2 = v1.[|Item1|]
end sub
end class",
"
class C
Sub M()
dim v1 as (i as integer, s as string)
dim v2 = v1.i
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestInArgument() As Task
Await TestAsync(
"
class C
Sub M()
dim v1 as (i as integer, s as string)
Foo(v1.[|Item1|])
end sub
Sub Foo(i as integer)
end sub
end class",
"
class C
Sub M()
dim v1 as (i as integer, s as string)
Foo(v1.i)
end sub
Sub Foo(i as integer)
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestNamedTuple2() As Task
Await TestAsync(
"
class C
Sub M()
dim v1 as (i as integer, s as string)
dim v2 = v1.[|Item2|]
end sub
end class",
"
class C
Sub M()
dim v1 as (i as integer, s as string)
dim v2 = v1.s
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestMissingOnMatchingName1() As Task
Await TestMissingAsync(
"
class C
Sub M()
dim v1 as (integer, s as string)
dim v2 = v1.[|Item1|]
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestMissingOnMatchingName2() As Task
Await TestMissingAsync(
"
class C
Sub M()
dim v1 as (Item1 as integer, s as string)
dim v2 = v1.[|Item1|]
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestWrongCasing() As Task
Await TestMissingAsync(
"
class C
Sub M()
dim v1 as (item1 as integer, s as string)
dim v2 = v1.[|Item1|]
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestFixAll1() As Task
Await TestAsync(
"
class C
Sub M()
dim v1 as (i as integer, s as string)
dim v2 = v1.{|FixAllInDocument:Item1|}
dim v3 = v1.Item2
end sub
end class",
"
class C
Sub M()
dim v1 as (i as integer, s as string)
dim v2 = v1.i
dim v3 = v1.s
end sub
end class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitTupleName)>
Public Async Function TestFixAll2() As Task
Await TestAsync(
"
class C
Sub M()
dim v1 as (i as integer, s as integer)
v1.{|FixAllInDocument:Item1|} = v1.Item2
end sub
end class",
"
class C
Sub M()
dim v1 as (i as integer, s as integer)
v1.i = v1.s
end sub
end class")
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -274,7 +274,9 @@ private static IEnumerable<SyntaxTrivia> MassageTrivia(IEnumerable<SyntaxTrivia>
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Inline_variable_declaration, createChangedDocument)
: base(FeaturesResources.Inline_variable_declaration,
createChangedDocument,
FeaturesResources.Inline_variable_declaration)
{
}
}
......
......@@ -42,6 +42,8 @@ internal static class IDEDiagnosticIds
public const string UseAutoPropertyDiagnosticId = "IDE0031";
public const string UseExplicitTupleNameDiagnosticId = "IDE0032";
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
public const string AnalyzerDependencyConflictId = "IDE1002";
......
......@@ -140,6 +140,7 @@
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionForNullableCodeFixProvider.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionCodeFixProvider.cs" />
<Compile Include="UseCoalesceExpression\AbstractUseCoalesceExpressionDiagnosticAnalyzer.cs" />
<Compile Include="UseExplicitTupleName\UseExplicitTupleNameCodeFixProvider.cs" />
<Compile Include="UseNullPropagation\AbstractUseNullPropagationCodeFixProvider.cs" />
<Compile Include="UseNullPropagation\AbstractUseNullPropagationDiagnosticAnalyzer.cs" />
<Compile Include="UseThrowExpression\AbstractUseThrowExpressionDiagnosticAnalyzer.cs" />
......@@ -684,6 +685,7 @@
<Compile Include="UseAutoProperty\AbstractUseAutoPropertyAnalyzer.cs" />
<Compile Include="UseObjectInitializer\AbstractUseObjectInitializerDiagnosticAnalyzer.cs" />
<Compile Include="UseObjectInitializer\AbstractUseObjectInitializerCodeFixProvider.cs" />
<Compile Include="UseExplicitTupleName\UseExplicitTupleNameDiagnosticAnalyzer.cs" />
<Compile Include="Workspace\BackgroundCompiler.cs" />
<Compile Include="Workspace\BackgroundParser.cs" />
<Compile Include="Workspace\ProjectCacheService.cs" />
......
......@@ -495,15 +495,6 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Camel Case.
/// </summary>
internal static string Camel_Case {
get {
return ResourceManager.GetString("Camel_Case", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to can&apos;t not construct final tree.
/// </summary>
......@@ -2130,6 +2121,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Prefer explicitly provided tuple element name.
/// </summary>
internal static string Prefer_explicitly_provided_tuple_element_name {
get {
return ResourceManager.GetString("Prefer_explicitly_provided_tuple_element_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Project.
/// </summary>
......@@ -3073,6 +3073,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Use explicitly provided tuple name.
/// </summary>
internal static string Use_explicitly_provided_tuple_name {
get {
return ResourceManager.GetString("Use_explicitly_provided_tuple_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use expression body for accessors.
/// </summary>
......
......@@ -1139,9 +1139,6 @@ This version used in: {2}</value>
<data name="All_uppercase" xml:space="preserve">
<value>All uppercase</value>
</data>
<data name="Camel_Case" xml:space="preserve">
<value>Camel Case</value>
</data>
<data name="First_word_capitalized" xml:space="preserve">
<value>First word capitalized</value>
</data>
......@@ -1169,4 +1166,10 @@ This version used in: {2}</value>
<data name="Simplify_object_initialization" xml:space="preserve">
<value>Simplify object initialization</value>
</data>
<data name="Prefer_explicitly_provided_tuple_element_name" xml:space="preserve">
<value>Prefer explicitly provided tuple element name</value>
</data>
<data name="Use_explicitly_provided_tuple_name" xml:space="preserve">
<value>Use explicitly provided tuple name</value>
</data>
</root>
\ No newline at end of file
// 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.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.UseExplicitTupleName
{
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared]
internal partial class UseExplicitTupleNameCodeFixProvider : SyntaxEditorBasedCodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; }
= ImmutableArray.Create(IDEDiagnosticIds.UseExplicitTupleNameDiagnosticId);
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
context.RegisterCodeFix(new MyCodeAction(
c => FixAsync(context.Document, context.Diagnostics[0], c)),
context.Diagnostics);
return SpecializedTasks.EmptyTask;
}
protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var root = editor.OriginalRoot;
var generator = editor.Generator;
foreach (var diagnostic in diagnostics)
{
var oldNameNode = diagnostic.Location.FindNode(
getInnermostNodeForTie: true, cancellationToken: cancellationToken);
var preferredName = diagnostic.Properties[nameof(UseExplicitTupleNameDiagnosticAnalyzer.ElementName)];
var newNameNode = generator.IdentifierName(preferredName).WithTriviaFrom(oldNameNode);
editor.ReplaceNode(oldNameNode, newNameNode);
}
return SpecializedTasks.EmptyTask;
}
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Use_explicitly_provided_tuple_name,
createChangedDocument,
FeaturesResources.Use_explicitly_provided_tuple_name)
{
}
}
}
}
\ No newline at end of file
// 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.Linq;
using System.Reflection;
using System.Threading;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Semantics;
namespace Microsoft.CodeAnalysis.UseExplicitTupleName
{
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
internal class UseExplicitTupleNameDiagnosticAnalyzer : AbstractCodeStyleDiagnosticAnalyzer
{
public const string ElementName = nameof(ElementName);
private static MethodInfo s_registerMethod = typeof(AnalysisContext).GetTypeInfo().GetDeclaredMethod("RegisterOperationActionImmutableArrayInternal");
public UseExplicitTupleNameDiagnosticAnalyzer()
: base(IDEDiagnosticIds.UseExplicitTupleNameDiagnosticId,
new LocalizableResourceString(nameof(FeaturesResources.Use_explicitly_provided_tuple_name), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.Prefer_explicitly_provided_tuple_element_name), FeaturesResources.ResourceManager, typeof(FeaturesResources)))
{
}
protected override void InitializeWorker(AnalysisContext context)
=> s_registerMethod.Invoke(context, new object[]
{
new Action<OperationAnalysisContext>(AnalyzeOperation),
ImmutableArray.Create(OperationKind.FieldReferenceExpression)
});
private void AnalyzeOperation(OperationAnalysisContext context)
{
var optionSet = context.Options.GetOptionSet();
var option = optionSet.GetOption(CodeStyleOptions.PreferExplicitTupleNames, context.Compilation.Language);
var severity = option.Notification.Value;
if (severity == DiagnosticSeverity.Hidden)
{
return;
}
var cancellationToken = context.CancellationToken;
var fieldReferenceOperation = (IFieldReferenceExpression)context.Operation;
var field = fieldReferenceOperation.Field;
if (field.ContainingType.IsTupleType)
{
if (field.CorrespondingTupleField.Equals(field))
{
var namedField = GetNamedField(field.ContainingType, field, cancellationToken);
if (namedField != null)
{
var memberAccessSyntax = fieldReferenceOperation.Syntax;
var nameNode = memberAccessSyntax.ChildNodesAndTokens().Reverse().FirstOrDefault();
if (nameNode != null)
{
var properties = ImmutableDictionary<string, string>.Empty.Add(
nameof(ElementName), namedField.Name);
context.ReportDiagnostic(Diagnostic.Create(
CreateDescriptorWithSeverity(severity),
nameNode.GetLocation(),
properties));
}
}
}
}
}
private IFieldSymbol GetNamedField(
INamedTypeSymbol containingType, IFieldSymbol unnamedField, CancellationToken cancellationToken)
{
foreach (var member in containingType.GetMembers())
{
cancellationToken.ThrowIfCancellationRequested();
if (member.Kind == SymbolKind.Field)
{
var fieldSymbol = (IFieldSymbol)member;
if (unnamedField.Equals(fieldSymbol.CorrespondingTupleField) &&
!fieldSymbol.Name.Equals(unnamedField.Name))
{
return fieldSymbol;
}
}
}
return null;
}
}
}
\ No newline at end of file
......@@ -406,6 +406,26 @@ public Customer()
//]
}
}
";
private static readonly string s_preferExplicitTupleName = @"
class Customer
{
public Customer()
{
//[
// Prefer:
(string name, int age) customer = GetCustomer();
var name = customer.name;
var age = customer.age;
// Over:
(string name, int age) customer = GetCustomer();
var name = customer.Item1;
var age = customer.Item2;
//]
}
}
";
private static readonly string s_preferInlinedVariableDeclaration = @"
......@@ -660,6 +680,7 @@ internal StyleViewModel(OptionSet optionSet, IServiceProvider serviceProvider) :
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferCollectionInitializer, ServicesVSResources.Prefer_collection_initializer, s_preferCollectionInitializer, s_preferCollectionInitializer, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferPatternMatchingOverIsWithCastCheck, CSharpVSResources.Prefer_pattern_matching_over_is_with_cast_check, s_preferPatternMatchingOverIsWithCastCheck, s_preferPatternMatchingOverIsWithCastCheck, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CSharpCodeStyleOptions.PreferPatternMatchingOverAsWithNullCheck, CSharpVSResources.Prefer_pattern_matching_over_as_with_null_check, s_preferPatternMatchingOverAsWithNullCheck, s_preferPatternMatchingOverAsWithNullCheck, this, optionSet, expressionPreferencesGroupTitle));
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferExplicitTupleNames, ServicesVSResources.Prefer_explicit_tuple_name, s_preferExplicitTupleName, s_preferExplicitTupleName, this, optionSet, expressionPreferencesGroupTitle));
// Variable preferences
CodeStyleItems.Add(new SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferInlinedVariableDeclaration, ServicesVSResources.Prefer_inlined_variable_declaration, s_preferInlinedVariableDeclaration, s_preferInlinedVariableDeclaration, this, optionSet, variablePreferencesGroupTitle));
......
......@@ -1401,6 +1401,15 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Prefer explicit tuple name.
/// </summary>
internal static string Prefer_explicit_tuple_name {
get {
return ResourceManager.GetString("Prefer_explicit_tuple_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Prefer framework type.
/// </summary>
......
......@@ -816,6 +816,9 @@ Additional information: {1}</value>
<data name="Prefer_null_propagation" xml:space="preserve">
<value>Prefer null propagation</value>
</data>
<data name="Prefer_explicit_tuple_name" xml:space="preserve">
<value>Prefer explicit tuple name</value>
</data>
<data name="Description" xml:space="preserve">
<value>Description</value>
</data>
......
......@@ -188,6 +188,24 @@ Class Customer
End Sub
End Class"
Private Shared ReadOnly s_preferExplicitTupleName As String = "
Class Customer
Public Sub New()
//[
' Prefer:
Dim customer As (name As String, age As Integer)
Dim name = customer.name
Dim age = customer.age
' Over
Dim customer As (name As String, age As Integer)
Dim name = customer.Item1
Dim age = customer.Item2
//]
End Sub
end class
"
Private Shared ReadOnly s_preferCoalesceExpression As String = "
Imports System
......@@ -262,6 +280,7 @@ End Class"
' expression preferences
Me.CodeStyleItems.Add(New SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferObjectInitializer, ServicesVSResources.Prefer_object_initializer, s_preferObjectInitializer, s_preferObjectInitializer, Me, optionSet, expressionPreferencesGroupTitle))
Me.CodeStyleItems.Add(New SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferCollectionInitializer, ServicesVSResources.Prefer_collection_initializer, s_preferCollectionInitializer, s_preferCollectionInitializer, Me, optionSet, expressionPreferencesGroupTitle))
Me.CodeStyleItems.Add(New SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferExplicitTupleNames, ServicesVSResources.Prefer_explicit_tuple_name, s_preferExplicitTupleName, s_preferExplicitTupleName, Me, optionSet, expressionPreferencesGroupTitle))
' nothing preferences
Me.CodeStyleItems.Add(New SimpleCodeStyleOptionViewModel(CodeStyleOptions.PreferCoalesceExpression, ServicesVSResources.Prefer_coalesce_expression, s_preferCoalesceExpression, s_preferCoalesceExpression, Me, optionSet, nothingPreferencesGroupTitle))
......
......@@ -108,25 +108,7 @@ public SymbolSearchUpdateEngine(ISymbolSearchLogService logService)
return Task.FromResult(result.ToImmutableAndFree());
}
public async Task<ImmutableArray<PackageWithAssemblyResult>> FindPackagesWithAssemblyAsync(
string source, string assemblyName)
{
var result = await FindPackagesWithAssemblyWorkerAsync(source, assemblyName).ConfigureAwait(false);
#if DEBUG
// For testing purposes, we hardcode this in if we're in DEBUG mode.
if (result.Length == 0 &&
source == NugetOrgSource &&
assemblyName == "System.ValueTuple")
{
return ImmutableArray.Create(new PackageWithAssemblyResult("System.ValueTuple", "", rank: 0));
}
#endif
return result;
}
public Task<ImmutableArray<PackageWithAssemblyResult>> FindPackagesWithAssemblyWorkerAsync(
public Task<ImmutableArray<PackageWithAssemblyResult>> FindPackagesWithAssemblyAsync(
string source, string assemblyName)
{
if (!_sourceToDatabase.TryGetValue(source, out var databaseWrapper))
......
......@@ -99,5 +99,11 @@ public class CodeStyleOptions
nameof(PreferInlinedVariableDeclaration),
defaultValue: TrueWithSuggestionEnforcement,
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferInlinedVariableDeclaration"));
internal static readonly PerLanguageOption<CodeStyleOption<bool>> PreferExplicitTupleNames = new PerLanguageOption<CodeStyleOption<bool>>(
nameof(CodeStyleOptions),
nameof(PreferExplicitTupleNames),
defaultValue: TrueWithSuggestionEnforcement,
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferExplicitTupleNames"));
}
}
\ No newline at end of file
......@@ -225,6 +225,7 @@ protected void WriteOptionSetTo(OptionSet options, string language, ObjectWriter
WriteOptionTo(options, language, CodeStyleOptions.PreferCoalesceExpression, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferCollectionInitializer, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferExplicitTupleNames, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferInlinedVariableDeclaration, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferNullPropagation, writer, cancellationToken);
WriteOptionTo(options, language, CodeStyleOptions.PreferObjectInitializer, writer, cancellationToken);
......@@ -244,6 +245,7 @@ protected OptionSet ReadOptionSetFrom(OptionSet options, string language, Object
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferCoalesceExpression, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferCollectionInitializer, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferExplicitTupleNames, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferInlinedVariableDeclaration, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferNullPropagation, reader, cancellationToken);
options = ReadOptionFrom(options, language, CodeStyleOptions.PreferObjectInitializer, reader, cancellationToken);
......
using System.Collections.Generic;
// 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.Immutable;
namespace Microsoft.CodeAnalysis.FindSymbols
{
......@@ -8,6 +10,6 @@ namespace Microsoft.CodeAnalysis.FindSymbols
/// </summary>
internal interface IDeclarationInfo
{
IReadOnlyList<DeclaredSymbolInfo> DeclaredSymbolInfos { get; }
ImmutableArray<DeclaredSymbolInfo> DeclaredSymbolInfos { get; }
}
}
\ No newline at end of file
// 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.Collections.Immutable;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
......@@ -22,9 +22,9 @@ internal class SyntaxTreeDeclarationInfo : AbstractSyntaxTreeInfo, IDeclarationI
private static readonly ConditionalWeakTable<BranchId, ConditionalWeakTable<DocumentId, AbstractSyntaxTreeInfo>> s_cache =
new ConditionalWeakTable<BranchId, ConditionalWeakTable<DocumentId, AbstractSyntaxTreeInfo>>();
public IReadOnlyList<DeclaredSymbolInfo> DeclaredSymbolInfos { get; }
public ImmutableArray<DeclaredSymbolInfo> DeclaredSymbolInfos { get; }
public SyntaxTreeDeclarationInfo(VersionStamp version, IReadOnlyList<DeclaredSymbolInfo> declaredSymbolInfos)
public SyntaxTreeDeclarationInfo(VersionStamp version, ImmutableArray<DeclaredSymbolInfo> declaredSymbolInfos)
: base(version)
{
DeclaredSymbolInfos = declaredSymbolInfos;
......@@ -32,7 +32,7 @@ public SyntaxTreeDeclarationInfo(VersionStamp version, IReadOnlyList<DeclaredSym
public override void WriteTo(ObjectWriter writer)
{
writer.WriteInt32(DeclaredSymbolInfos.Count);
writer.WriteInt32(DeclaredSymbolInfos.Length);
foreach (var declaredSymbolInfo in DeclaredSymbolInfos)
{
declaredSymbolInfo.WriteTo(writer);
......@@ -60,13 +60,14 @@ private static SyntaxTreeDeclarationInfo ReadFrom(ObjectReader reader, VersionSt
try
{
var declaredSymbolCount = reader.ReadInt32();
var declaredSymbols = new DeclaredSymbolInfo[declaredSymbolCount];
var builder = ImmutableArray.CreateBuilder<DeclaredSymbolInfo>(declaredSymbolCount);
for (int i = 0; i < declaredSymbolCount; i++)
{
declaredSymbols[i] = DeclaredSymbolInfo.ReadFrom(reader);
builder.Add(DeclaredSymbolInfo.ReadFrom(reader));
}
return new SyntaxTreeDeclarationInfo(version, declaredSymbols);
return new SyntaxTreeDeclarationInfo(
version, builder.MoveToImmutable());
}
catch (Exception)
{
......@@ -75,4 +76,4 @@ private static SyntaxTreeDeclarationInfo ReadFrom(ObjectReader reader, VersionSt
return null;
}
}
}
}
\ No newline at end of file
......@@ -146,7 +146,7 @@ private static async Task<(SyntaxTreeIdentifierInfo identifierInfo, SyntaxTreeCo
var predefinedTypes = (int)PredefinedType.None;
var predefinedOperators = (int)PredefinedOperator.None;
var declaredSymbolInfos = new List<DeclaredSymbolInfo>();
var declaredSymbolInfos = ArrayBuilder<DeclaredSymbolInfo>.GetInstance();
if (syntaxFacts != null)
{
......@@ -241,7 +241,7 @@ private static async Task<(SyntaxTreeIdentifierInfo identifierInfo, SyntaxTreeCo
containsIndexerMemberCref),
new SyntaxTreeDeclarationInfo(
version,
declaredSymbolInfos));
declaredSymbolInfos.ToImmutableAndFree()));
}
finally
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册