提交 a19fcadb 编写于 作者: B Brett Forsgren

Merge pull request #7675 from brettfo/no-await-on-dynamic-quick-info

don't show `(Awaitable)` for dynamic objects
...@@ -63,7 +63,7 @@ protected static IEnumerable<SymbolDisplayPart> GetSeparatorParts() ...@@ -63,7 +63,7 @@ protected static IEnumerable<SymbolDisplayPart> GetSeparatorParts()
protected IList<SymbolDisplayPart> GetAwaitableUsage(IMethodSymbol method, SemanticModel semanticModel, int position) protected IList<SymbolDisplayPart> GetAwaitableUsage(IMethodSymbol method, SemanticModel semanticModel, int position)
{ {
if (method.IsAwaitable(semanticModel, position)) if (method.IsAwaitableNonDynamic(semanticModel, position))
{ {
return method.ToAwaitableParts(SyntaxFacts.GetText(SyntaxKind.AwaitKeyword), "x", semanticModel, position); return method.ToAwaitableParts(SyntaxFacts.GetText(SyntaxKind.AwaitKeyword), "x", semanticModel, position);
} }
......
...@@ -15,7 +15,7 @@ internal partial class GenericNameSignatureHelpProvider ...@@ -15,7 +15,7 @@ internal partial class GenericNameSignatureHelpProvider
{ {
var result = new List<SymbolDisplayPart>(); var result = new List<SymbolDisplayPart>();
var awaitable = method.GetOriginalUnreducedDefinition().IsAwaitable(semanticModel, position); var awaitable = method.GetOriginalUnreducedDefinition().IsAwaitableNonDynamic(semanticModel, position);
var extension = method.GetOriginalUnreducedDefinition().IsExtensionMethod(); var extension = method.GetOriginalUnreducedDefinition().IsExtensionMethod();
if (awaitable && extension) if (awaitable && extension)
......
...@@ -123,7 +123,7 @@ private bool IsHiddenBy(IMethodSymbol method1, IMethodSymbol method2) ...@@ -123,7 +123,7 @@ private bool IsHiddenBy(IMethodSymbol method1, IMethodSymbol method2)
{ {
var result = new List<SymbolDisplayPart>(); var result = new List<SymbolDisplayPart>();
var awaitable = method.GetOriginalUnreducedDefinition().IsAwaitable(semanticModel, position); var awaitable = method.GetOriginalUnreducedDefinition().IsAwaitableNonDynamic(semanticModel, position);
var extension = method.GetOriginalUnreducedDefinition().IsExtensionMethod(); var extension = method.GetOriginalUnreducedDefinition().IsExtensionMethod();
if (awaitable && extension) if (awaitable && extension)
......
...@@ -1266,6 +1266,23 @@ public void Calc() ...@@ -1266,6 +1266,23 @@ public void Calc()
TypeParameterMap($"\r\nTResult {FeaturesResources.Is} int")); TypeParameterMap($"\r\nTResult {FeaturesResources.Is} int"));
} }
[WorkItem(7100, "https://github.com/dotnet/roslyn/issues/7100")]
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestDynamicIsntAwaitable()
{
var markup = @"
class C
{
dynamic D() { return null; }
void M()
{
D$$();
}
}
";
await TestAsync(markup, MainDescription("dynamic C.D()"));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task TestStringLiteral() public async Task TestStringLiteral()
{ {
......
...@@ -64,7 +64,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.SignatureHelp ...@@ -64,7 +64,7 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.SignatureHelp
End Function End Function
Private Function GetAwaitableDescription(member As ISymbol, semanticModel As SemanticModel, position As Integer) As IList(Of SymbolDisplayPart) Private Function GetAwaitableDescription(member As ISymbol, semanticModel As SemanticModel, position As Integer) As IList(Of SymbolDisplayPart)
If member.IsAwaitable(semanticModel, position) Then If member.IsAwaitableNonDynamic(semanticModel, position) Then
Return member.ToAwaitableParts(SyntaxFacts.GetText(SyntaxKind.AwaitKeyword), "r", semanticModel, position) Return member.ToAwaitableParts(SyntaxFacts.GetText(SyntaxKind.AwaitKeyword), "r", semanticModel, position)
End If End If
......
...@@ -1443,6 +1443,23 @@ End Class ...@@ -1443,6 +1443,23 @@ End Class
MainDescription(description), Usage(doc)) MainDescription(description), Usage(doc))
End Function End Function
<WorkItem(7100, "https://github.com/dotnet/roslyn/issues/7100")>
<Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)>
Public Async Function TestObjectWithOptionStrictOffIsntAwaitable() As Task
Dim markup = "
Option Strict Off
Class C
Function D() As Object
Return Nothing
End Function
Sub M()
D$$()
End Sub
End Class
"
Await TestAsync(markup, MainDescription("Function C.D() As Object"))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)> <Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)>
Public Async Function TestObsoleteItem() As Task Public Async Function TestObsoleteItem() As Task
Await TestAsync(<Text><![CDATA[ Await TestAsync(<Text><![CDATA[
......
...@@ -317,7 +317,7 @@ private void AddDescriptionForDynamicType() ...@@ -317,7 +317,7 @@ private void AddDescriptionForDynamicType()
private void AddDescriptionForNamedType(INamedTypeSymbol symbol) private void AddDescriptionForNamedType(INamedTypeSymbol symbol)
{ {
if (symbol.IsAwaitable(_semanticModel, _position)) if (symbol.IsAwaitableNonDynamic(_semanticModel, _position))
{ {
AddAwaitablePrefix(); AddAwaitablePrefix();
} }
...@@ -480,8 +480,7 @@ private void AddDescriptionForRangeVariable(IRangeVariableSymbol symbol) ...@@ -480,8 +480,7 @@ private void AddDescriptionForRangeVariable(IRangeVariableSymbol symbol)
private void AddDescriptionForMethod(IMethodSymbol method) private void AddDescriptionForMethod(IMethodSymbol method)
{ {
// TODO : show duplicated member case // TODO : show duplicated member case
// TODO : a way to check whether it is a member call off dynamic type? var awaitable = method.IsAwaitableNonDynamic(_semanticModel, _position);
var awaitable = method.IsAwaitable(_semanticModel, _position);
var extension = method.IsExtensionMethod || method.MethodKind == MethodKind.ReducedExtension; var extension = method.IsExtensionMethod || method.MethodKind == MethodKind.ReducedExtension;
if (awaitable && extension) if (awaitable && extension)
{ {
......
...@@ -875,11 +875,11 @@ public static DocumentationComment GetDocumentationComment(this ISymbol symbol, ...@@ -875,11 +875,11 @@ public static DocumentationComment GetDocumentationComment(this ISymbol symbol,
} }
/// <summary> /// <summary>
/// If the <paramref name="symbol"/> is a method symbol, returns True if the method's return type is "awaitable". /// If the <paramref name="symbol"/> is a method symbol, returns <see langword="true"/> if the method's return type is "awaitable", but not if it's <see langword="dynamic"/>.
/// If the <paramref name="symbol"/> is a type symbol, returns True if that type is "awaitable". /// If the <paramref name="symbol"/> is a type symbol, returns <see langword="true"/> if that type is "awaitable".
/// An "awaitable" is any type that exposes a GetAwaiter method which returns a valid "awaiter". This GetAwaiter method may be an instance method or an extension method. /// An "awaitable" is any type that exposes a GetAwaiter method which returns a valid "awaiter". This GetAwaiter method may be an instance method or an extension method.
/// </summary> /// </summary>
public static bool IsAwaitable(this ISymbol symbol, SemanticModel semanticModel, int position) public static bool IsAwaitableNonDynamic(this ISymbol symbol, SemanticModel semanticModel, int position)
{ {
IMethodSymbol methodSymbol = symbol as IMethodSymbol; IMethodSymbol methodSymbol = symbol as IMethodSymbol;
ITypeSymbol typeSymbol = null; ITypeSymbol typeSymbol = null;
...@@ -898,13 +898,6 @@ public static bool IsAwaitable(this ISymbol symbol, SemanticModel semanticModel, ...@@ -898,13 +898,6 @@ public static bool IsAwaitable(this ISymbol symbol, SemanticModel semanticModel,
{ {
return false; return false;
} }
// dynamic
if (methodSymbol.ReturnType.TypeKind == TypeKind.Dynamic &&
methodSymbol.MethodKind != MethodKind.BuiltinOperator)
{
return true;
}
} }
// otherwise: needs valid GetAwaiter // otherwise: needs valid GetAwaiter
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册