Skip to content

Commit e3dcf8c

Browse files
authored
Merge pull request #26165 from Neme12/localFunctionNamingStyle
Naming style for local functions
2 parents 21f9fc2 + ed4f34c commit e3dcf8c

File tree

19 files changed

+1111
-129
lines changed

19 files changed

+1111
-129
lines changed

src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs

Lines changed: 162 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
22

3+
using System;
4+
using System.Collections.Immutable;
5+
using System.Linq;
36
using System.Threading.Tasks;
47
using Microsoft.CodeAnalysis.Completion;
58
using Microsoft.CodeAnalysis.CSharp;
69
using Microsoft.CodeAnalysis.CSharp.Completion.Providers;
10+
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
711
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders;
812
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
13+
using Microsoft.CodeAnalysis.NamingStyles;
14+
using Microsoft.CodeAnalysis.Options;
15+
using Microsoft.CodeAnalysis.Simplification;
916
using Microsoft.CodeAnalysis.Test.Utilities;
1017
using Roslyn.Test.Utilities;
1118
using Xunit;
19+
using static Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles.SymbolSpecification;
1220

1321
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionSetSources
1422
{
@@ -32,8 +40,8 @@ public class MyClass
3240
MyClass $$
3341
}
3442
";
35-
await VerifyItemExistsAsync(markup, "MyClass", glyph: (int)Glyph.MethodPublic);
3643
await VerifyItemExistsAsync(markup, "myClass", glyph: (int)Glyph.FieldPublic);
44+
await VerifyItemExistsAsync(markup, "MyClass", glyph: (int)Glyph.PropertyPublic);
3745
await VerifyItemExistsAsync(markup, "GetMyClass", glyph: (int)Glyph.MethodPublic);
3846
}
3947

@@ -544,15 +552,49 @@ void goo()
544552
}
545553

546554
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
547-
public async Task TestDescription()
555+
public async Task TestCorrectOrder()
548556
{
549557
var markup = @"
550558
public class MyClass
551559
{
552560
MyClass $$
553561
}
554562
";
555-
await VerifyItemExistsAsync(markup, "MyClass", glyph: (int)Glyph.MethodPublic, expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
563+
var items = await GetCompletionItemsAsync(markup, SourceCodeKind.Regular);
564+
Assert.Equal(
565+
new[] { "myClass", "my", "@class", "MyClass", "My", "Class", "GetMyClass", "GetMy", "GetClass" },
566+
items.Select(item => item.DisplayText));
567+
}
568+
569+
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
570+
public async Task TestDescriptionInsideClass()
571+
{
572+
var markup = @"
573+
public class MyClass
574+
{
575+
MyClass $$
576+
}
577+
";
578+
await VerifyItemExistsAsync(markup, "myClass", glyph: (int)Glyph.FieldPublic, expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
579+
await VerifyItemExistsAsync(markup, "MyClass", glyph: (int)Glyph.PropertyPublic, expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
580+
await VerifyItemExistsAsync(markup, "GetMyClass", glyph: (int)Glyph.MethodPublic, expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
581+
}
582+
583+
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
584+
public async Task TestDescriptionInsideMethod()
585+
{
586+
var markup = @"
587+
public class MyClass
588+
{
589+
void M()
590+
{
591+
MyClass $$
592+
}
593+
}
594+
";
595+
await VerifyItemExistsAsync(markup, "myClass", glyph: (int)Glyph.Local, expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
596+
await VerifyItemIsAbsentAsync(markup, "MyClass");
597+
await VerifyItemIsAbsentAsync(markup, "GetMyClass");
556598
}
557599

558600
[WorkItem(20273, "https://github.com/dotnet/roslyn/issues/20273")]
@@ -1411,5 +1453,122 @@ public void Method()
14111453
";
14121454
await VerifyItemExistsAsync(markup, "nullables");
14131455
}
1456+
1457+
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
1458+
public async Task CustomNamingStyleInsideClass()
1459+
{
1460+
var workspace = WorkspaceFixture.GetWorkspace();
1461+
var originalOptions = workspace.Options;
1462+
1463+
try
1464+
{
1465+
workspace.Options = workspace.Options.WithChangedOption(
1466+
new OptionKey(SimplificationOptions.NamingPreferences, LanguageNames.CSharp),
1467+
NamesEndWithSuffixPreferences());
1468+
1469+
var markup = @"
1470+
class Configuration
1471+
{
1472+
Configuration $$
1473+
}
1474+
";
1475+
await VerifyItemExistsAsync(markup, "ConfigurationField", glyph: (int)Glyph.FieldPublic,
1476+
expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
1477+
await VerifyItemExistsAsync(markup, "ConfigurationProperty", glyph: (int)Glyph.PropertyPublic,
1478+
expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
1479+
await VerifyItemExistsAsync(markup, "ConfigurationMethod", glyph: (int)Glyph.MethodPublic,
1480+
expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
1481+
await VerifyItemIsAbsentAsync(markup, "ConfigurationLocal");
1482+
await VerifyItemIsAbsentAsync(markup, "ConfigurationLocalFunction");
1483+
}
1484+
finally
1485+
{
1486+
workspace.Options = originalOptions;
1487+
}
1488+
}
1489+
1490+
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
1491+
public async Task CustomNamingStyleInsideMethod()
1492+
{
1493+
var workspace = WorkspaceFixture.GetWorkspace();
1494+
var originalOptions = workspace.Options;
1495+
1496+
try
1497+
{
1498+
workspace.Options = workspace.Options.WithChangedOption(
1499+
new OptionKey(SimplificationOptions.NamingPreferences, LanguageNames.CSharp),
1500+
NamesEndWithSuffixPreferences());
1501+
1502+
var markup = @"
1503+
class Configuration
1504+
{
1505+
void M()
1506+
{
1507+
Configuration $$
1508+
}
1509+
}
1510+
";
1511+
await VerifyItemExistsAsync(markup, "ConfigurationLocal", glyph: (int)Glyph.Local,
1512+
expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
1513+
await VerifyItemExistsAsync(markup, "ConfigurationLocalFunction", glyph: (int)Glyph.MethodPublic,
1514+
expectedDescriptionOrNull: CSharpFeaturesResources.Suggested_name);
1515+
await VerifyItemIsAbsentAsync(markup, "ConfigurationField");
1516+
await VerifyItemIsAbsentAsync(markup, "ConfigurationMethod");
1517+
await VerifyItemIsAbsentAsync(markup, "ConfigurationProperty");
1518+
}
1519+
finally
1520+
{
1521+
workspace.Options = originalOptions;
1522+
}
1523+
}
1524+
1525+
private static NamingStylePreferences NamesEndWithSuffixPreferences()
1526+
{
1527+
var specificationStyles = new[]
1528+
{
1529+
SpecificationStyle(new SymbolKindOrTypeKind(SymbolKind.Field), "Field"),
1530+
SpecificationStyle(new SymbolKindOrTypeKind(SymbolKind.Property), "Property"),
1531+
SpecificationStyle(new SymbolKindOrTypeKind(MethodKind.Ordinary), "Method"),
1532+
SpecificationStyle(new SymbolKindOrTypeKind(SymbolKind.Local), "Local"),
1533+
SpecificationStyle(new SymbolKindOrTypeKind(MethodKind.LocalFunction), "LocalFunction"),
1534+
};
1535+
1536+
return new NamingStylePreferences(
1537+
specificationStyles.Select(t => t.specification).ToImmutableArray(),
1538+
specificationStyles.Select(t => t.style).ToImmutableArray(),
1539+
specificationStyles.Select(t => CreateRule(t.specification, t.style)).ToImmutableArray());
1540+
1541+
// Local functions
1542+
1543+
(SymbolSpecification specification, NamingStyle style) SpecificationStyle(SymbolKindOrTypeKind kind, string suffix)
1544+
{
1545+
var symbolSpecification = new SymbolSpecification(
1546+
id: null,
1547+
symbolSpecName: suffix,
1548+
ImmutableArray.Create(kind),
1549+
ImmutableArray<Accessibility>.Empty,
1550+
ImmutableArray<ModifierKind>.Empty);
1551+
1552+
var namingStyle = new NamingStyle(
1553+
Guid.NewGuid(),
1554+
name: suffix,
1555+
capitalizationScheme: Capitalization.PascalCase,
1556+
prefix: "",
1557+
suffix: suffix,
1558+
wordSeparator: "");
1559+
1560+
return (symbolSpecification, namingStyle);
1561+
}
1562+
1563+
SerializableNamingRule CreateRule(SymbolSpecification specification, NamingStyle style)
1564+
{
1565+
return new SerializableNamingRule()
1566+
{
1567+
SymbolSpecificationID = specification.ID,
1568+
NamingStyleID = style.ID,
1569+
EnforcementLevel = DiagnosticSeverity.Error
1570+
};
1571+
}
1572+
}
14141573
}
14151574
}

0 commit comments

Comments
 (0)