提交 c6c0ed66 编写于 作者: C CyrusNajmabadi

Merge pull request #5573 from CyrusNajmabadi/awaitClassification

Optimistically classify the 'await' keyword

Fixes #2301
......@@ -3605,5 +3605,48 @@ public void LoadDirective()
PPKeyword("load"),
String("\"file.csx\""));
}
[Fact, Trait(Traits.Feature, Traits.Features.Classification)]
public void IncompleteAwaitInNonAsyncContext()
{
var code = @"
void M()
{
var x = await
}";
TestInClass(code,
Keyword("void"),
Identifier("M"),
Punctuation.OpenParen,
Punctuation.CloseParen,
Punctuation.OpenCurly,
Keyword("var"),
Identifier("x"),
Operators.Equals,
Keyword("await"),
Punctuation.CloseCurly);
}
[Fact, Trait(Traits.Feature, Traits.Features.Classification)]
public void CompleteAwaitInNonAsyncContext()
{
var code = @"
void M()
{
var x = await;
}";
TestInClass(code,
Keyword("void"),
Identifier("M"),
Punctuation.OpenParen,
Punctuation.CloseParen,
Punctuation.OpenCurly,
Keyword("var"),
Identifier("x"),
Operators.Equals,
Identifier("await"),
Punctuation.Semicolon,
Punctuation.CloseCurly);
}
}
}
......@@ -518,5 +518,31 @@ End Class
Keyword("My"))
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Classification)>
Public Sub TestAwaitInNonAsyncFunction1()
Dim text =
<code>
dim m = Await
</code>.NormalizedValue()
TestInMethod(text,
Keyword("Await"))
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Classification)>
Public Sub TestAwaitInNonAsyncFunction2()
Dim text =
<code>
sub await()
end sub
sub test()
dim m = Await
end sub
</code>.NormalizedValue()
TestInClass(text)
End Sub
End Class
End Namespace
......@@ -14,6 +14,7 @@ internal static class ClassificationHelpers
private const string FromKeyword = "from";
private const string ValueKeyword = "value";
private const string VarKeyword = "var";
private const string AwaitKeyword = "await";
/// <summary>
/// Determine the classification type for a given token.
......@@ -114,7 +115,7 @@ private static string GetClassificationForIdentifier(SyntaxToken token)
{
return ClassificationTypeNames.TypeParameterName;
}
else if (IsActualContextualKeyword(token) || CouldBeVarKeywordInDeclaration(token))
else if (IsActualContextualKeyword(token))
{
return ClassificationTypeNames.Keyword;
}
......@@ -259,11 +260,20 @@ private static bool IsActualContextualKeyword(SyntaxToken token)
{
switch (token.ValueText)
{
case AwaitKeyword:
return token.GetNextToken(includeZeroWidth: true).IsMissing;
case FromKeyword:
var fromClause = token.Parent.FirstAncestorOrSelf<FromClauseSyntax>();
return fromClause != null && fromClause.FromKeyword == token;
case VarKeyword:
// var
if (token.Parent is IdentifierNameSyntax && token.Parent?.Parent is ExpressionStatementSyntax)
{
return true;
}
// we allow var any time it looks like a variable declaration, and is not in a
// field or event field.
return
......@@ -277,18 +287,6 @@ private static bool IsActualContextualKeyword(SyntaxToken token)
return false;
}
private static bool CouldBeVarKeywordInDeclaration(SyntaxToken token)
{
if (token.ValueText == VarKeyword && token.Parent != null && token.Parent.Parent != null)
{
// cases:
// var
return token.Parent is IdentifierNameSyntax && token.Parent.Parent is ExpressionStatementSyntax;
}
return false;
}
internal static void AddLexicalClassifications(SourceText text, TextSpan textSpan, List<ClassifiedSpan> result, CancellationToken cancellationToken)
{
var text2 = text.ToString(textSpan);
......
......@@ -65,6 +65,7 @@
<Compile Include="CaseCorrection\VisualBasicCaseCorrectionServiceFactory.vb" />
<Compile Include="Classification\ClassificationHelpers.vb" />
<Compile Include="Classification\Classifiers\AbstractSyntaxClassifier.vb" />
<Compile Include="Classification\Classifiers\IdentifierNameSyntaxClassifier.vb" />
<Compile Include="Classification\Classifiers\ImportAliasClauseSyntaxClassifier.vb" />
<Compile Include="Classification\Classifiers\NameSyntaxClassifier.vb" />
<Compile Include="Classification\SyntaxClassifier.vb" />
......
' 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.Classification
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Namespace Microsoft.CodeAnalysis.VisualBasic.Classification.Classifiers
Friend Class IdentifierNameSyntaxClassifier
Inherits AbstractSyntaxClassifier
Private Const AwaitText = "Await"
Public Overrides ReadOnly Property SyntaxNodeTypes As IEnumerable(Of Type)
Get
Return {GetType(IdentifierNameSyntax)}
End Get
End Property
Public Overrides Function ClassifyNode(syntax As SyntaxNode, semanticModel As SemanticModel, cancellationToken As CancellationToken) As IEnumerable(Of ClassifiedSpan)
Dim identifierName = DirectCast(syntax, IdentifierNameSyntax)
Dim identifier = identifierName.Identifier
If CaseInsensitiveComparison.Equals(identifier.ValueText, AwaitText) Then
Dim symbolInfo = semanticModel.GetSymbolInfo(identifier)
If symbolInfo.GetAnySymbol() Is Nothing Then
Return SpecializedCollections.SingletonEnumerable(New ClassifiedSpan(ClassificationTypeNames.Keyword, identifier.Span))
End If
End If
Return MyBase.ClassifyNode(syntax, semanticModel, cancellationToken)
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -9,7 +9,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Classification
Public ReadOnly DefaultSyntaxClassifiers As IEnumerable(Of ISyntaxClassifier) =
ImmutableArray.Create(Of ISyntaxClassifier)(
New NameSyntaxClassifier(),
New ImportAliasClauseSyntaxClassifier()
)
New ImportAliasClauseSyntaxClassifier(),
New IdentifierNameSyntaxClassifier())
End Module
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册