提交 8cf0b3ee 编写于 作者: J Julien Couvreur 提交者: GitHub

Classify discards as identifier (#20561)

上级 5f1f1f46
......@@ -40,24 +40,68 @@ internal string GetText(ClassifiedSpan tuple)
actual.Sort((t1, t2) => t1.TextSpan.Start - t2.TextSpan.Start);
var max = Math.Max(expected.Length, actual.Count);
for (int i = 0; i < max; i++)
var actualFormatted = actual.Select(a => new FormattedClassification(a.ClassificationType, allCode.Substring(a.TextSpan.Start, a.TextSpan.Length)));
var expectedFormatted = expected.Select(e => new FormattedClassification(e.Item2, e.Item1));
AssertEx.Equal(expectedFormatted, actualFormatted);
}
private class FormattedClassification
{
private readonly string _classification;
private readonly string _text;
public FormattedClassification(string classification, string text)
{
if (i >= expected.Length)
{
AssertEx.Fail("Unexpected actual classification: {0}", GetText(actual[i]));
}
else if (i >= actual.Count)
_classification = classification;
_text = text;
}
public override bool Equals(object obj)
{
if (obj is FormattedClassification other)
{
AssertEx.Fail("Missing classification for: {0}", GetText(expected[i]));
return this._classification == other._classification && this._text == other._text;
}
var tuple = expected[i];
var classification = actual[i];
return false;
}
public override int GetHashCode()
{
return _classification.GetHashCode() ^ _text.GetHashCode();
}
var text = allCode.Substring(classification.TextSpan.Start, classification.TextSpan.Length);
Assert.Equal(tuple.Item1, text);
Assert.Equal(tuple.Item2, classification.ClassificationType);
public override string ToString()
{
switch(_classification)
{
case "punctuation":
switch (_text)
{
case "(":
return "Punctation.OpenParen";
case ")":
return "Punctation.CloseParen";
case ";":
return "Punctation.Semicolon";
case ":":
return "Punctuation.Colon";
case ",":
return "Punctuation.Comma";
}
goto default;
case "operator":
switch(_text)
{
case "=":
return "Operators.Equals";
}
goto default;
default:
return $"{char.ToUpperInvariant(_classification[0])}{_classification.Substring(1)}(\"{_text}\")";
}
}
}
......
......@@ -67,8 +67,6 @@ public async Task GenericClassDeclaration()
public async Task RefVar()
{
await TestInMethodAsync(
className: "Class",
methodName: "M",
code: @"int i = 0; ref var x = ref i;",
expected: Keyword("var"));
}
......
......@@ -7,6 +7,7 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Classification
{
[Trait(Traits.Feature, Traits.Features.Classification)]
public partial class SyntacticClassifierTests
{
[Fact, Trait(Traits.Feature, Traits.Features.Classification)]
......@@ -925,5 +926,79 @@ public async Task PP_PragmaWarningRestoreThree()
Punctuation.Comma,
Number("102"));
}
[Fact]
public async Task DiscardInOutDeclaration()
{
await TestInMethodAsync(
code: @"M2(out var _);",
expected: Classifications(Identifier("M2"), Punctuation.OpenParen, Keyword("out"), Identifier("var"),
Identifier("_"), Punctuation.CloseParen, Punctuation.Semicolon));
}
[Fact]
public async Task DiscardInCasePattern()
{
await TestInMethodAsync(
code: @"switch (1) { case int _: }",
expected: Classifications(Keyword("switch"), Punctuation.OpenParen, Number("1"), Punctuation.CloseParen,
Punctuation.OpenCurly, Keyword("case"), Keyword("int"), Identifier("_"), Punctuation.Colon, Punctuation.CloseCurly));
}
[Fact]
public async Task DiscardInDeconstruction()
{
await TestInMethodAsync(
code: @"var (x, _) = (1, 2);",
expected: Classifications(Identifier("var"), Punctuation.OpenParen, Identifier("x"), Punctuation.Comma,
Identifier("_"), Punctuation.CloseParen, Operators.Equals, Punctuation.OpenParen, Number("1"),
Punctuation.Comma, Number("2"), Punctuation.CloseParen, Punctuation.Semicolon));
}
[Fact]
public async Task DiscardInDeconstruction2()
{
await TestInMethodAsync(
code: @"(var _, var _) = (1, 2);",
expected: Classifications(Punctuation.OpenParen, Identifier("var"), Identifier("_"), Punctuation.Comma,
Identifier("var"), Identifier("_"), Punctuation.CloseParen, Operators.Equals, Punctuation.OpenParen,
Number("1"), Punctuation.Comma, Number("2"), Punctuation.CloseParen, Punctuation.Semicolon));
}
[Fact]
public async Task ShortDiscardInDeconstruction()
{
await TestInMethodAsync(
code: @"int x; (_, x) = (1, 2);",
expected: Classifications(Keyword("int"), Identifier("x"), Punctuation.Semicolon, Punctuation.OpenParen,
Identifier("_"), Punctuation.Comma, Identifier("x"), Punctuation.CloseParen, Operators.Equals,
Punctuation.OpenParen, Number("1"), Punctuation.Comma, Number("2"), Punctuation.CloseParen,
Punctuation.Semicolon));
}
[Fact]
public async Task ShortDiscardInOutDeclaration()
{
await TestInMethodAsync(
code: @"M2(out _);",
expected: Classifications(Identifier("M2"), Punctuation.OpenParen, Keyword("out"), Identifier("_"), Punctuation.CloseParen,
Punctuation.Semicolon));
}
[Fact]
public async Task ShortDiscardInAssignment()
{
await TestInMethodAsync(
code: @"_ = 1;",
expected: Classifications(Identifier("_"), Operators.Equals, Number("1"), Punctuation.Semicolon));
}
[Fact]
public async Task UnderscoreInAssignment()
{
await TestInMethodAsync(code: @"int _; _ = 1;" ,
expected: Classifications(Keyword("int"), Identifier("_"), Punctuation.Semicolon, Identifier("_"), Operators.Equals,
Number("1"), Punctuation.Semicolon));
}
}
}
// 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.Generic;
using System.Threading;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.CSharp.Extensions;
......@@ -24,6 +23,10 @@ internal static class ClassificationHelpers
/// <returns>The correct syntactic classification for the token.</returns>
public static string GetClassification(SyntaxToken token)
{
if (token.IsKind(SyntaxKind.DiscardDesignation, SyntaxKind.UnderscoreToken))
{
return ClassificationTypeNames.Identifier;
}
if (SyntaxFacts.IsKeywordKind(token.Kind()))
{
return ClassificationTypeNames.Keyword;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册