Skip to content

Commit c58a3d9

Browse files
authored
Merge branch 'extensions' into 'main' (#78293)
2 parents 43ce29e + c6dfd02 commit c58a3d9

28 files changed

+338
-230
lines changed

src/EditorFeatures/CSharpTest/Classification/AbstractCSharpClassifierTests.cs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5-
#nullable disable
6-
5+
using System.Diagnostics.CodeAnalysis;
76
using System.Threading.Tasks;
87
using Microsoft.CodeAnalysis.Editor.UnitTests;
98
using Microsoft.CodeAnalysis.Editor.UnitTests.Classification;
@@ -14,40 +13,66 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification;
1413

1514
public abstract class AbstractCSharpClassifierTests : AbstractClassifierTests
1615
{
17-
protected static EditorTestWorkspace CreateWorkspace(string code, ParseOptions options, TestHost testHost)
16+
protected static EditorTestWorkspace CreateWorkspace(
17+
string code, ParseOptions? options, TestHost testHost)
1818
{
1919
var composition = EditorTestCompositions.EditorFeatures.WithTestHostParts(testHost);
2020
return EditorTestWorkspace.CreateCSharp(code, parseOptions: options, composition: composition, isMarkup: false);
2121
}
2222

23+
protected new Task TestAsync(
24+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code,
25+
TestHost testHost,
26+
params FormattedClassification[] expected)
27+
{
28+
return base.TestAsync(code, testHost, expected);
29+
}
30+
31+
protected new Task TestAsync(
32+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code,
33+
TestHost testHost,
34+
ParseOptions? parseOptions,
35+
params FormattedClassification[] expected)
36+
{
37+
return base.TestAsync(code, testHost, parseOptions, expected);
38+
}
39+
2340
protected override async Task DefaultTestAsync(string code, string allCode, TestHost testHost, FormattedClassification[] expected)
2441
{
2542
await TestAsync(code, allCode, testHost, parseOptions: null, expected);
2643
await TestAsync(code, allCode, testHost, parseOptions: Options.Script, expected);
2744
}
2845

2946
protected override string WrapInClass(string className, string code)
30-
=> $@"class {className} {{
31-
{code}
32-
}}";
47+
=> $$"""
48+
class {{className}} {
49+
{{code}}
50+
}
51+
""";
3352

3453
protected override string WrapInExpression(string code)
35-
=> $@"class C {{
36-
void M() {{
37-
var q =
38-
{code}
39-
}}
40-
}}";
54+
=> $$"""
55+
class C {
56+
void M() {
57+
var q =
58+
{{code}}
59+
}
60+
}
61+
""";
4162

4263
protected override string WrapInMethod(string className, string methodName, string code)
43-
=> $@"class {className} {{
44-
void {methodName}() {{
45-
{code}
46-
}}
47-
}}";
64+
=> $$"""
65+
class {{className}} {
66+
void {{methodName}}() {
67+
{{code}}
68+
}
69+
}
70+
""";
4871

4972
protected override string WrapInNamespace(string code)
50-
=> $@"namespace N {{
51-
{code}
52-
}}";
73+
=> $$"""
74+
namespace N {
75+
{{code}}
76+
}
77+
""";
5378
}

src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,22 +31,15 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification;
3131
[Trait(Traits.Feature, Traits.Features.Classification)]
3232
public sealed partial class SemanticClassifierTests : AbstractCSharpClassifierTests
3333
{
34-
protected override async Task<ImmutableArray<ClassifiedSpan>> GetClassificationSpansAsync(string code, ImmutableArray<TextSpan> spans, ParseOptions? options, TestHost testHost)
34+
protected override async Task<ImmutableArray<ClassifiedSpan>> GetClassificationSpansAsync(
35+
string code, ImmutableArray<TextSpan> spans, ParseOptions? options, TestHost testHost)
3536
{
3637
using var workspace = CreateWorkspace(code, options, testHost);
3738
var document = workspace.CurrentSolution.GetRequiredDocument(workspace.Documents.First().Id);
3839

3940
return await GetSemanticClassificationsAsync(document, spans);
4041
}
4142

42-
private new Task TestAsync(
43-
[StringSyntax("C#-Test")] string code,
44-
TestHost testHost,
45-
params FormattedClassification[] expected)
46-
{
47-
return base.TestAsync(code, testHost, expected);
48-
}
49-
5043
[Theory, CombinatorialData]
5144
public async Task GenericClassDeclaration(TestHost testHost)
5245
{

src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Threading;
88
using System.Threading.Tasks;
99
using Microsoft.CodeAnalysis.Classification;
10+
using Microsoft.CodeAnalysis.CSharp;
11+
using Microsoft.CodeAnalysis.CSharp.Shared.Extensions;
1012
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
1113
using Microsoft.CodeAnalysis.Editor.Tagging;
1214
using Microsoft.CodeAnalysis.Editor.UnitTests.Classification;
@@ -41,7 +43,7 @@ protected override async Task<ImmutableArray<ClassifiedSpan>> GetClassificationS
4143
public async Task VarAsUsingAliasForNamespace(TestHost testHost)
4244
{
4345
await TestAsync(
44-
@"using var = System;",
46+
@"using var = System;",
4547
testHost,
4648
Keyword("using"),
4749
Namespace("var"),
@@ -3233,4 +3235,64 @@ void M()
32333235
Punctuation.CloseCurly,
32343236
], actualFormatted);
32353237
}
3238+
3239+
[Theory, CombinatorialData]
3240+
public async Task TestModernExtension1(TestHost testHost)
3241+
{
3242+
await TestAsync(
3243+
"""
3244+
static class C
3245+
{
3246+
extension(string s)
3247+
{
3248+
public bool IsNullOrEmpty() => false;
3249+
}
3250+
3251+
void M(string s)
3252+
{
3253+
var v = s.IsNullOrEmpty();
3254+
}
3255+
}
3256+
""",
3257+
testHost,
3258+
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersionExtensions.CSharpNext),
3259+
Keyword("static"),
3260+
Keyword("class"),
3261+
Class("C"),
3262+
Static("C"),
3263+
Punctuation.OpenCurly,
3264+
Keyword("extension"),
3265+
Punctuation.OpenParen,
3266+
Keyword("string"),
3267+
Parameter("s"),
3268+
Punctuation.CloseParen,
3269+
Punctuation.OpenCurly,
3270+
Keyword("public"),
3271+
Keyword("bool"),
3272+
ExtensionMethod("IsNullOrEmpty"),
3273+
Punctuation.OpenParen,
3274+
Punctuation.CloseParen,
3275+
Operators.EqualsGreaterThan,
3276+
Keyword("false"),
3277+
Punctuation.Semicolon,
3278+
Punctuation.CloseCurly,
3279+
Keyword("void"),
3280+
Method("M"),
3281+
Punctuation.OpenParen,
3282+
Keyword("string"),
3283+
Parameter("s"),
3284+
Punctuation.CloseParen,
3285+
Punctuation.OpenCurly,
3286+
Keyword("var"),
3287+
Local("v"),
3288+
Operators.Equals,
3289+
Parameter("s"),
3290+
Operators.Dot,
3291+
ExtensionMethod("IsNullOrEmpty"),
3292+
Punctuation.OpenParen,
3293+
Punctuation.CloseParen,
3294+
Punctuation.Semicolon,
3295+
Punctuation.CloseCurly,
3296+
Punctuation.CloseCurly);
3297+
}
32363298
}

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

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#nullable disable
66

77
using System.Collections.Generic;
8+
using System.Diagnostics.CodeAnalysis;
89
using System.Linq;
910
using System.Threading.Tasks;
1011
using Microsoft.CodeAnalysis.Completion;
@@ -29,7 +30,8 @@ public abstract class AbstractCSharpCompletionProviderTests<TWorkspaceFixture> :
2930
{
3031
protected const string NonBreakingSpaceString = "\x00A0";
3132

32-
protected static string GetMarkup(string source, LanguageVersion languageVersion)
33+
protected static string GetMarkup(
34+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string source, LanguageVersion languageVersion)
3335
=> $@"<Workspace>
3436
<Project Language=""C#"" AssemblyName=""Assembly1"" CommonReferences=""true"" LanguageVersion=""{languageVersion.ToDisplayString()}"">
3537
<Document FilePath=""Test2.cs"">
@@ -40,17 +42,17 @@ protected static string GetMarkup(string source, LanguageVersion languageVersion
4042
</Project>
4143
</Workspace>";
4244

43-
protected override EditorTestWorkspace CreateWorkspace(string fileContents)
45+
protected override EditorTestWorkspace CreateWorkspace([StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string fileContents)
4446
=> EditorTestWorkspace.CreateCSharp(fileContents, composition: GetComposition());
4547

4648
internal override CompletionService GetCompletionService(Project project)
4749
=> Assert.IsType<CSharpCompletionService>(base.GetCompletionService(project));
4850

4951
private protected override Task BaseVerifyWorkerAsync(
50-
string code, int position,
52+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, int position,
5153
string expectedItemOrNull, string expectedDescriptionOrNull,
5254
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, char? deletedCharTrigger, bool checkForAbsence,
53-
int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
55+
Glyph? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
5456
string displayTextPrefix, string inlineDescription = null, bool? isComplexTextEdit = null,
5557
List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null,
5658
CompletionOptions options = null, bool skipSpeculation = false)
@@ -63,7 +65,7 @@ private protected override Task BaseVerifyWorkerAsync(
6365
}
6466

6567
private protected override Task BaseVerifyWorkerAsync(
66-
string code, int position, bool usePreviousCharAsTrigger, char? deletedCharTrigger, bool? hasSuggestionItem,
68+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, int position, bool usePreviousCharAsTrigger, char? deletedCharTrigger, bool? hasSuggestionItem,
6769
SourceCodeKind sourceCodeKind, ItemExpectation[] expectedResults,
6870
List<CompletionFilter> matchingFilters, CompletionItemFlags? flags, CompletionOptions options, bool skipSpeculation = false)
6971
{
@@ -73,10 +75,10 @@ private protected override Task BaseVerifyWorkerAsync(
7375
}
7476

7577
private protected override async Task VerifyWorkerAsync(
76-
string code, int position,
78+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, int position,
7779
string expectedItemOrNull, string expectedDescriptionOrNull,
7880
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
79-
bool checkForAbsence, int? glyph, int? matchPriority,
81+
bool checkForAbsence, Glyph? glyph, int? matchPriority,
8082
bool? hasSuggestionItem, string displayTextSuffix, string displayTextPrefix, string inlineDescription = null,
8183
bool? isComplexTextEdit = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null,
8284
CompletionOptions options = null, bool skipSpeculation = false)
@@ -99,9 +101,9 @@ protected override string ItemPartiallyWritten(string expectedItemOrNull)
99101
=> expectedItemOrNull[0] == '@' ? expectedItemOrNull.Substring(1, 1) : expectedItemOrNull[..1];
100102

101103
private async Task VerifyInFrontOfCommentAsync(
102-
string code, int position, string insertText, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
104+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, int position, string insertText, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
103105
string expectedItemOrNull, string expectedDescriptionOrNull,
104-
SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
106+
SourceCodeKind sourceCodeKind, bool checkForAbsence, Glyph? glyph,
105107
int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
106108
string displayTextPrefix, string inlineDescription, bool? isComplexTextEdit, List<CompletionFilter> matchingFilters,
107109
CompletionOptions options, bool skipSpeculation = false)
@@ -118,9 +120,9 @@ await base.VerifyWorkerAsync(
118120
}
119121

120122
private async Task VerifyInFrontOfCommentAsync(
121-
string code, int position, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
123+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, int position, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
122124
string expectedItemOrNull, string expectedDescriptionOrNull,
123-
SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
125+
SourceCodeKind sourceCodeKind, bool checkForAbsence, Glyph? glyph,
124126
int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
125127
string displayTextPrefix, string inlineDescription, bool? isComplexTextEdit,
126128
List<CompletionFilter> matchingFilters, CompletionOptions options, bool skipSpeculation = false)
@@ -133,9 +135,9 @@ await VerifyInFrontOfCommentAsync(
133135
}
134136

135137
private protected async Task VerifyInFrontOfComment_ItemPartiallyWrittenAsync(
136-
string code, int position, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
138+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string code, int position, bool usePreviousCharAsTrigger, char? deletedCharTrigger,
137139
string expectedItemOrNull, string expectedDescriptionOrNull,
138-
SourceCodeKind sourceCodeKind, bool checkForAbsence, int? glyph,
140+
SourceCodeKind sourceCodeKind, bool checkForAbsence, Glyph? glyph,
139141
int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
140142
string displayTextPrefix, string inlineDescription, bool? isComplexTextEdit,
141143
List<CompletionFilter> matchingFilters, CompletionOptions options, bool skipSpeculation = false)
@@ -147,7 +149,7 @@ await VerifyInFrontOfCommentAsync(
147149
displayTextPrefix, inlineDescription, isComplexTextEdit, matchingFilters, options, skipSpeculation: skipSpeculation);
148150
}
149151

150-
protected static string AddInsideMethod(string text)
152+
protected static string AddInsideMethod([StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string text)
151153
{
152154
return
153155
"""
@@ -162,7 +164,8 @@ void F()
162164
""";
163165
}
164166

165-
protected static string AddUsingDirectives(string usingDirectives, string text)
167+
protected static string AddUsingDirectives(
168+
string usingDirectives, [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string text)
166169
{
167170
return
168171
usingDirectives +
@@ -172,7 +175,9 @@ protected static string AddUsingDirectives(string usingDirectives, string text)
172175
text;
173176
}
174177

175-
protected async Task VerifySendEnterThroughToEnterAsync(string initialMarkup, string textTypedSoFar, EnterKeyRule sendThroughEnterOption, bool expected)
178+
protected async Task VerifySendEnterThroughToEnterAsync(
179+
[StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] string initialMarkup,
180+
string textTypedSoFar, EnterKeyRule sendThroughEnterOption, bool expected)
176181
{
177182
using var workspace = CreateWorkspace(initialMarkup);
178183
var hostDocument = workspace.DocumentWithCursor;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ private async Task VerifyKeywordAsync(
4646
var expectedDescription = dotAwait
4747
? GetDescription(CompletionDisplayTextAwait, FeaturesResources.Await_the_preceding_expression)
4848
: GetDescription(CompletionDisplayTextAwait, FeaturesResources.Asynchronously_waits_for_the_task_to_finish);
49-
await VerifyItemExistsAsync(GetMarkup(code, languageVersion), CompletionDisplayTextAwait, glyph: (int)Glyph.Keyword, expectedDescriptionOrNull: expectedDescription, inlineDescription: inlineDescription);
49+
await VerifyItemExistsAsync(GetMarkup(code, languageVersion), CompletionDisplayTextAwait, glyph: Glyph.Keyword, expectedDescriptionOrNull: expectedDescription, inlineDescription: inlineDescription);
5050

5151
if (dotAwaitf)
5252
{
5353
expectedDescription = string.Format(FeaturesResources.Await_the_preceding_expression_and_add_ConfigureAwait_0, "false");
54-
await VerifyItemExistsAsync(GetMarkup(code, languageVersion), CompletionDisplayTextAwaitAndConfigureAwait, glyph: (int)Glyph.Keyword, expectedDescriptionOrNull: expectedDescription, inlineDescription: inlineDescription);
54+
await VerifyItemExistsAsync(GetMarkup(code, languageVersion), CompletionDisplayTextAwaitAndConfigureAwait, glyph: Glyph.Keyword, expectedDescriptionOrNull: expectedDescription, inlineDescription: inlineDescription);
5555
}
5656
else
5757
{

0 commit comments

Comments
 (0)