提交 970f2e77 编写于 作者: C Cyrus Najmabadi

Don't mutate _node in place. It's far too confusing. Instead, just extract...

Don't mutate _node in place.  It's far too confusing.  Instead, just extract whatever data we need into another node.
上级 0366402f
......@@ -2,8 +2,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
......@@ -11,7 +9,6 @@
using Microsoft.CodeAnalysis.CSharp.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Options;
using Roslyn.Test.Utilities;
......
......@@ -1097,7 +1097,30 @@ NewLines("Imports System.Linq \n Imports System.Runtime.CompilerServices \n Impo
<WpfFact(), Trait(Traits.Feature, Traits.Features.CodeActionsAddImport)>
Public Async Function TestAddUsingWithOtherExtensionsInScope3() As Task
Await TestAsync(
NewLines("Imports System.Runtime.CompilerServices \n Imports X \n Module Program \n Sub Main(args As String()) \n Dim a = 0 \n Dim i = [|a.All|](0) \n End Sub \n End Module \n Namespace X \n Module E \n <Extension> \n Public Function All(a As Integer) As Integer \n Return a \n End Function \n End Module \n End Namespace \n Namespace Y \n Module E \n <Extension> \n Public Function All(a As Integer, v As Integer) As Integer \n Return a \n End Function \n End Module \n End Namespace"),
"Imports System.Runtime.CompilerServices
Imports X
Module Program
Sub Main(args As String())
Dim a = 0
Dim i = [|a.All|](0)
End Sub
End Module
Namespace X
Module E
<Extension>
Public Function All(a As Integer) As Integer
Return a
End Function
End Module
End Namespace
Namespace Y
Module E
<Extension>
Public Function All(a As Integer, v As Integer) As Integer
Return a
End Function
End Module
End Namespace",
NewLines("Imports System.Runtime.CompilerServices \n Imports X \n Imports Y \n Module Program \n Sub Main(args As String()) \n Dim a = 0 \n Dim i = a.All(0) \n End Sub \n End Module \n Namespace X \n Module E \n <Extension> \n Public Function All(a As Integer) As Integer \n Return a \n End Function \n End Module \n End Namespace \n Namespace Y \n Module E \n <Extension> \n Public Function All(a As Integer, v As Integer) As Integer \n Return a \n End Function \n End Module \n End Namespace"))
End Function
......
......@@ -141,8 +141,11 @@ protected override bool CanAddImport(SyntaxNode node, CancellationToken cancella
return node.CanAddUsingDirectives(cancellationToken);
}
protected override bool CanAddImportForMethod(Diagnostic diagnostic, ISyntaxFactsService syntaxFacts, ref SyntaxNode node)
protected override bool CanAddImportForMethod(
Diagnostic diagnostic, ISyntaxFactsService syntaxFacts, SyntaxNode node, out SimpleNameSyntax nameNode)
{
nameNode = null;
switch (diagnostic.Id)
{
case CS1061:
......@@ -202,15 +205,15 @@ protected override bool CanAddImportForMethod(Diagnostic diagnostic, ISyntaxFact
return false;
}
var simpleName = node as SimpleNameSyntax;
if (!simpleName.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) &&
!simpleName.IsParentKind(SyntaxKind.MemberBindingExpression))
nameNode = node as SimpleNameSyntax;
if (!nameNode.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) &&
!nameNode.IsParentKind(SyntaxKind.MemberBindingExpression))
{
return false;
}
var memberAccess = simpleName.Parent as MemberAccessExpressionSyntax;
var memberBinding = simpleName.Parent as MemberBindingExpressionSyntax;
var memberAccess = nameNode.Parent as MemberAccessExpressionSyntax;
var memberBinding = nameNode.Parent as MemberBindingExpressionSyntax;
if (memberAccess.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) ||
memberAccess.IsParentKind(SyntaxKind.ElementAccessExpression) ||
memberBinding.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) ||
......@@ -227,12 +230,13 @@ protected override bool CanAddImportForMethod(Diagnostic diagnostic, ISyntaxFact
return true;
}
protected override bool CanAddImportForNamespace(Diagnostic diagnostic, ref SyntaxNode node)
protected override bool CanAddImportForNamespace(Diagnostic diagnostic, SyntaxNode node, out SimpleNameSyntax nameNode)
{
nameNode = null;
return false;
}
protected override bool CanAddImportForQuery(Diagnostic diagnostic, ref SyntaxNode node)
protected override bool CanAddImportForQuery(Diagnostic diagnostic, SyntaxNode node)
{
if (diagnostic.Id != CS1935)
{
......@@ -242,8 +246,9 @@ protected override bool CanAddImportForQuery(Diagnostic diagnostic, ref SyntaxNo
return node.AncestorsAndSelf().Any(n => n is QueryExpressionSyntax && !(n.Parent is QueryContinuationSyntax));
}
protected override bool CanAddImportForType(Diagnostic diagnostic, ref SyntaxNode node)
protected override bool CanAddImportForType(Diagnostic diagnostic, SyntaxNode node, out SimpleNameSyntax nameNode)
{
nameNode = null;
switch (diagnostic.Id)
{
case CS0103:
......@@ -271,10 +276,10 @@ protected override bool CanAddImportForType(Diagnostic diagnostic, ref SyntaxNod
return false;
}
return TryFindStandaloneType(ref node);
return TryFindStandaloneType(node, out nameNode);
}
private static bool TryFindStandaloneType(ref SyntaxNode node)
private static bool TryFindStandaloneType(SyntaxNode node, out SimpleNameSyntax nameNode)
{
var qn = node as QualifiedNameSyntax;
if (qn != null)
......@@ -282,8 +287,8 @@ private static bool TryFindStandaloneType(ref SyntaxNode node)
node = GetLeftMostSimpleName(qn);
}
var simpleName = node as SimpleNameSyntax;
return simpleName.LooksLikeStandaloneTypeName();
nameNode = node as SimpleNameSyntax;
return nameNode.LooksLikeStandaloneTypeName();
}
private static SimpleNameSyntax GetLeftMostSimpleName(QualifiedNameSyntax qn)
......
......@@ -11,7 +11,7 @@
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
internal abstract partial class AbstractAddImportCodeFixProvider<TIdentifierNameSyntax>
internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSyntax>
{
private abstract class SearchScope
{
......@@ -27,7 +27,7 @@ protected SearchScope(bool exact, CancellationToken cancellationToken)
protected abstract Task<IEnumerable<ISymbol>> FindDeclarationsAsync(string name, SymbolFilter filter, SearchQuery query);
public abstract SymbolReference CreateReference<T>(SearchResult<T> symbol) where T : INamespaceOrTypeSymbol;
public async Task<IEnumerable<SearchResult<ISymbol>>> FindDeclarationsAsync(string name, TIdentifierNameSyntax nameNode, SymbolFilter filter)
public async Task<IEnumerable<SearchResult<ISymbol>>> FindDeclarationsAsync(string name, TSimpleNameSyntax nameNode, SymbolFilter filter)
{
var query = this.Exact ? new SearchQuery(name, ignoreCase: true) : new SearchQuery(GetInexactPredicate(name));
var symbols = await FindDeclarationsAsync(name, filter, query).ConfigureAwait(false);
......
......@@ -5,7 +5,7 @@
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
internal abstract partial class AbstractAddImportCodeFixProvider<TIdentifierNameSyntax>
internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSyntax>
{
private abstract class SymbolReference : IComparable<SymbolReference>, IEquatable<SymbolReference>
{
......
......@@ -16,21 +16,21 @@
namespace Microsoft.CodeAnalysis.CodeFixes.AddImport
{
internal abstract partial class AbstractAddImportCodeFixProvider<TIdentifierNameSyntax> : CodeFixProvider, IEqualityComparer<PortableExecutableReference>
where TIdentifierNameSyntax : SyntaxNode
internal abstract partial class AbstractAddImportCodeFixProvider<TSimpleNameSyntax> : CodeFixProvider, IEqualityComparer<PortableExecutableReference>
where TSimpleNameSyntax : SyntaxNode
{
private const int MaxResults = 3;
protected abstract bool CanAddImport(SyntaxNode node, CancellationToken cancellationToken);
protected abstract bool CanAddImportForMethod(Diagnostic diagnostic, ISyntaxFactsService syntaxFacts, ref SyntaxNode node);
protected abstract bool CanAddImportForNamespace(Diagnostic diagnostic, ref SyntaxNode node);
protected abstract bool CanAddImportForQuery(Diagnostic diagnostic, ref SyntaxNode node);
protected abstract bool CanAddImportForType(Diagnostic diagnostic, ref SyntaxNode node);
protected abstract bool CanAddImportForMethod(Diagnostic diagnostic, ISyntaxFactsService syntaxFacts, SyntaxNode node, out TSimpleNameSyntax nameNode);
protected abstract bool CanAddImportForNamespace(Diagnostic diagnostic, SyntaxNode node, out TSimpleNameSyntax nameNode);
protected abstract bool CanAddImportForQuery(Diagnostic diagnostic, SyntaxNode node);
protected abstract bool CanAddImportForType(Diagnostic diagnostic, SyntaxNode node, out TSimpleNameSyntax nameNode);
protected abstract ISet<INamespaceSymbol> GetNamespacesInScope(SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken);
protected abstract ITypeSymbol GetQueryClauseInfo(SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken);
protected abstract string GetDescription(INamespaceOrTypeSymbol symbol, SemanticModel semanticModel, SyntaxNode root);
protected abstract Task<Document> AddImportAsync(SyntaxNode contextNode, INamespaceOrTypeSymbol symbol, string desiredName, TIdentifierNameSyntax nameNode, Document document, bool specialCaseSystem, CancellationToken cancellationToken);
protected abstract Task<Document> AddImportAsync(SyntaxNode contextNode, INamespaceOrTypeSymbol symbol, string desiredName, TSimpleNameSyntax nameNode, Document document, bool specialCaseSystem, CancellationToken cancellationToken);
protected abstract bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken);
internal abstract bool IsViableField(IFieldSymbol field, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken);
internal abstract bool IsViableProperty(IPropertySymbol property, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken);
......@@ -286,15 +286,14 @@ private void AddRange(List<SymbolReference> allSymbolReferences, List<SymbolRefe
}
private static void CalculateContext(
SyntaxNode node, ISyntaxFactsService syntaxFacts, out string name, out int arity,
out TIdentifierNameSyntax nameNode, out bool inAttributeContext, out bool hasIncompleteParentMember)
TSimpleNameSyntax nameNode, ISyntaxFactsService syntaxFacts, out string name, out int arity,
out bool inAttributeContext, out bool hasIncompleteParentMember)
{
// Has to be a simple identifier or generic name.
syntaxFacts.GetNameAndArityOfSimpleName(node, out name, out arity);
nameNode = name != null ? (TIdentifierNameSyntax)node : null;
syntaxFacts.GetNameAndArityOfSimpleName(nameNode, out name, out arity);
inAttributeContext = syntaxFacts.IsAttributeName(node);
hasIncompleteParentMember = syntaxFacts.HasIncompleteParentMember(node);
inAttributeContext = syntaxFacts.IsAttributeName(nameNode);
hasIncompleteParentMember = syntaxFacts.HasIncompleteParentMember(nameNode);
}
private static bool NotGlobalNamespace(SymbolReference reference)
......@@ -327,12 +326,12 @@ private class SymbolReferenceFinder
private readonly ISymbol _containingTypeOrAssembly;
private readonly ISet<INamespaceSymbol> _namespacesInScope;
private readonly ISyntaxFactsService _syntaxFacts;
private readonly AbstractAddImportCodeFixProvider<TIdentifierNameSyntax> _owner;
private readonly AbstractAddImportCodeFixProvider<TSimpleNameSyntax> _owner;
private SyntaxNode _node;
private readonly SyntaxNode _node;
public SymbolReferenceFinder(
AbstractAddImportCodeFixProvider<TIdentifierNameSyntax> owner,
AbstractAddImportCodeFixProvider<TSimpleNameSyntax> owner,
Document document, SemanticModel semanticModel, Diagnostic diagnostic, SyntaxNode node, CancellationToken cancellationToken)
{
_owner = owner;
......@@ -419,7 +418,8 @@ private List<SymbolReference> DeDupeAndSortReferences(List<SymbolReference> allR
private async Task<IList<SymbolReference>> GetNamespacesForMatchingTypesAsync(SearchScope searchScope)
{
if (!_owner.CanAddImportForType(_diagnostic, ref _node))
TSimpleNameSyntax nameNode;
if (!_owner.CanAddImportForType(_diagnostic, _node, out nameNode))
{
return null;
}
......@@ -427,8 +427,7 @@ private async Task<IList<SymbolReference>> GetNamespacesForMatchingTypesAsync(Se
string name;
int arity;
bool inAttributeContext, hasIncompleteParentMember;
TIdentifierNameSyntax nameNode;
CalculateContext(_node, _syntaxFacts, out name, out arity, out nameNode, out inAttributeContext, out hasIncompleteParentMember);
CalculateContext(nameNode, _syntaxFacts, out name, out arity, out inAttributeContext, out hasIncompleteParentMember);
var symbols = await GetTypeSymbols(searchScope, name, nameNode, inAttributeContext).ConfigureAwait(false);
if (symbols == null)
......@@ -441,7 +440,8 @@ private async Task<IList<SymbolReference>> GetNamespacesForMatchingTypesAsync(Se
private async Task<IList<SymbolReference>> GetMatchingTypesAsync(SearchScope searchScope)
{
if (!_owner.CanAddImportForType(_diagnostic, ref _node))
TSimpleNameSyntax nameNode;
if (!_owner.CanAddImportForType(_diagnostic, _node, out nameNode))
{
return null;
}
......@@ -449,8 +449,7 @@ private async Task<IList<SymbolReference>> GetMatchingTypesAsync(SearchScope sea
string name;
int arity;
bool inAttributeContext, hasIncompleteParentMember;
TIdentifierNameSyntax nameNode;
CalculateContext(_node, _syntaxFacts, out name, out arity, out nameNode, out inAttributeContext, out hasIncompleteParentMember);
CalculateContext(nameNode, _syntaxFacts, out name, out arity, out inAttributeContext, out hasIncompleteParentMember);
var symbols = await GetTypeSymbols(searchScope, name, nameNode, inAttributeContext).ConfigureAwait(false);
if (symbols == null)
......@@ -464,7 +463,7 @@ private async Task<IList<SymbolReference>> GetMatchingTypesAsync(SearchScope sea
private async Task<IEnumerable<SearchResult<ITypeSymbol>>> GetTypeSymbols(
SearchScope searchScope,
string name,
TIdentifierNameSyntax nameNode,
TSimpleNameSyntax nameNode,
bool inAttributeContext)
{
if (_cancellationToken.IsCancellationRequested)
......@@ -472,7 +471,7 @@ private async Task<IList<SymbolReference>> GetMatchingTypesAsync(SearchScope sea
return null;
}
if (ExpressionBinds(checkForExtensionMethods: false))
if (ExpressionBinds(nameNode, checkForExtensionMethods: false))
{
return null;
}
......@@ -491,12 +490,12 @@ private async Task<IList<SymbolReference>> GetMatchingTypesAsync(SearchScope sea
return OfType<ITypeSymbol>(symbols);
}
protected bool ExpressionBinds(bool checkForExtensionMethods)
protected bool ExpressionBinds(TSimpleNameSyntax nameNode, bool checkForExtensionMethods)
{
// See if the name binds to something other then the error type. If it does, there's nothing further we need to do.
// For extension methods, however, we will continue to search if there exists any better matched method.
_cancellationToken.ThrowIfCancellationRequested();
var symbolInfo = _semanticModel.GetSymbolInfo(_node, _cancellationToken);
var symbolInfo = _semanticModel.GetSymbolInfo(nameNode, _cancellationToken);
if (symbolInfo.CandidateReason == CandidateReason.OverloadResolutionFailure && !checkForExtensionMethods)
{
return true;
......@@ -508,22 +507,22 @@ protected bool ExpressionBinds(bool checkForExtensionMethods)
private async Task<IList<SymbolReference>> GetNamespacesForMatchingNamespacesAsync(
SearchScope searchScope)
{
if (!_owner.CanAddImportForNamespace(_diagnostic, ref _node))
TSimpleNameSyntax nameNode;
if (!_owner.CanAddImportForNamespace(_diagnostic, _node, out nameNode))
{
return null;
}
string name;
int arity;
_syntaxFacts.GetNameAndArityOfSimpleName(_node, out name, out arity);
_syntaxFacts.GetNameAndArityOfSimpleName(nameNode, out name, out arity);
var nameNode = (TIdentifierNameSyntax)_node;
if (arity > 0)
{
return null;
}
if (ExpressionBinds(checkForExtensionMethods: false))
if (ExpressionBinds(nameNode, checkForExtensionMethods: false))
{
return null;
}
......@@ -536,20 +535,27 @@ protected bool ExpressionBinds(bool checkForExtensionMethods)
private async Task<IList<SymbolReference>> GetNamespacesForMatchingExtensionMethodsAsync(SearchScope searchScope)
{
if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, ref _node))
TSimpleNameSyntax nameNode;
if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, _node, out nameNode))
{
return null;
}
if (nameNode == null)
{
return null;
}
var symbols = await GetSymbolsAsync(searchScope).ConfigureAwait(false);
var extensionMethods = FilterForExtensionMethods(searchScope, _node.Parent, symbols);
var symbols = await GetSymbolsAsync(searchScope, nameNode).ConfigureAwait(false);
var extensionMethods = FilterForExtensionMethods(searchScope, nameNode.Parent, symbols);
return extensionMethods.ToList();
}
private async Task<IList<SymbolReference>> GetNamespacesForCollectionInitializerMethodsAsync(SearchScope searchScope)
{
if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, ref _node))
TSimpleNameSyntax nameNode;
if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, _node, out nameNode))
{
return null;
}
......@@ -561,18 +567,21 @@ private async Task<IList<SymbolReference>> GetNamespacesForCollectionInitializer
private async Task<IList<SymbolReference>> GetNamespacesForMatchingFieldsAndPropertiesAsync(
SearchScope searchScope)
{
if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, ref _node))
TSimpleNameSyntax nameNode;
if (!_owner.CanAddImportForMethod(_diagnostic, _syntaxFacts, _node, out nameNode))
{
return null;
}
var expression = _node.Parent;
var symbols = await GetSymbolsAsync(searchScope).ConfigureAwait(false);
if (nameNode == null)
{
return null;
}
var symbols = await GetSymbolsAsync(searchScope, nameNode).ConfigureAwait(false);
if (symbols != null)
{
return FilterForFieldsAndProperties(searchScope, expression, symbols);
return FilterForFieldsAndProperties(searchScope, nameNode.Parent, symbols);
}
return null;
......@@ -580,7 +589,7 @@ private async Task<IList<SymbolReference>> GetNamespacesForCollectionInitializer
private async Task<IList<SymbolReference>> GetNamespacesForQueryPatternsAsync(SearchScope searchScope)
{
if (!_owner.CanAddImportForQuery(_diagnostic, ref _node))
if (!_owner.CanAddImportForQuery(_diagnostic, _node))
{
return null;
}
......@@ -662,25 +671,24 @@ private List<SymbolReference> GetProposedTypes(SearchScope searchScope, string n
return result;
}
private Task<IEnumerable<SearchResult<ISymbol>>> GetSymbolsAsync(SearchScope searchScope)
private Task<IEnumerable<SearchResult<ISymbol>>> GetSymbolsAsync(SearchScope searchScope, TSimpleNameSyntax nameNode)
{
_cancellationToken.ThrowIfCancellationRequested();
// See if the name binds. If it does, there's nothing further we need to do.
if (ExpressionBinds(checkForExtensionMethods: true))
if (ExpressionBinds(nameNode, checkForExtensionMethods: true))
{
return SpecializedTasks.EmptyEnumerable<SearchResult<ISymbol>>();
}
string name;
int arity;
_syntaxFacts.GetNameAndArityOfSimpleName(_node, out name, out arity);
_syntaxFacts.GetNameAndArityOfSimpleName(nameNode, out name, out arity);
if (name == null)
{
return SpecializedTasks.EmptyEnumerable<SearchResult<ISymbol>>();
}
var nameNode = (TIdentifierNameSyntax)_node;
return searchScope.FindDeclarationsAsync(name, nameNode, SymbolFilter.Member);
}
......@@ -757,9 +765,9 @@ private struct SearchResult<T> where T : ISymbol
public readonly string DesiredName;
// The node to convert to the desired name
public readonly TIdentifierNameSyntax NameNode;
public readonly TSimpleNameSyntax NameNode;
public SearchResult(string desiredName, TIdentifierNameSyntax nameNode, T symbol, double weight)
public SearchResult(string desiredName, TSimpleNameSyntax nameNode, T symbol, double weight)
{
DesiredName = desiredName;
Symbol = symbol;
......@@ -780,7 +788,7 @@ internal SearchResult<T> WithDesiredName(string desiredName)
private struct SearchResult
{
public static SearchResult<T> Create<T>(string desiredName, TIdentifierNameSyntax nameNode, T symbol, double weight) where T : ISymbol
public static SearchResult<T> Create<T>(string desiredName, TSimpleNameSyntax nameNode, T symbol, double weight) where T : ISymbol
{
return new SearchResult<T>(desiredName, nameNode, symbol, weight);
}
......
......@@ -105,7 +105,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddImport
Return node.CanAddImportsStatements(cancellationToken)
End Function
Protected Overrides Function CanAddImportForMethod(diagnostic As Diagnostic, syntaxFacts As ISyntaxFactsService, ByRef node As SyntaxNode) As Boolean
Protected Overrides Function CanAddImportForMethod(
diagnostic As Diagnostic,
syntaxFacts As ISyntaxFactsService,
node As SyntaxNode,
ByRef nameNode As SimpleNameSyntax) As Boolean
Select Case diagnostic.Id
Case BC30456, BC30390, BC42309, BC30451
Exit Select
......@@ -151,15 +155,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddImport
Return False
End If
Dim simpleName = TryCast(node, SimpleNameSyntax)
If simpleName Is Nothing Then
nameNode = TryCast(node, SimpleNameSyntax)
If nameNode Is Nothing Then
Return False
End If
Return True
End Function
Protected Overrides Function CanAddImportForNamespace(diagnostic As Diagnostic, ByRef node As SyntaxNode) As Boolean
Protected Overrides Function CanAddImportForNamespace(diagnostic As Diagnostic, node As SyntaxNode, ByRef nameNode As SimpleNameSyntax) As Boolean
Select Case diagnostic.Id
Case BC30002, BC30451
Exit Select
......@@ -167,10 +171,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddImport
Return False
End Select
Return CanAddImportForTypeOrNamespaceCore(node)
Return CanAddImportForTypeOrNamespaceCore(node, nameNode)
End Function
Protected Overrides Function CanAddImportForQuery(diagnostic As Diagnostic, ByRef node As SyntaxNode) As Boolean
Protected Overrides Function CanAddImportForQuery(diagnostic As Diagnostic, node As SyntaxNode) As Boolean
If diagnostic.Id <> BC36593 Then
Return False
End If
......@@ -184,7 +188,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddImport
Return True
End Function
Protected Overrides Function CanAddImportForType(diagnostic As Diagnostic, ByRef node As SyntaxNode) As Boolean
Protected Overrides Function CanAddImportForType(
diagnostic As Diagnostic, node As SyntaxNode, ByRef nameNode As SimpleNameSyntax) As Boolean
Select Case diagnostic.Id
Case BC30002, BC30451, BC32042, BC32045, BC30389, BC31504, BC36610, BC30182
Exit Select
......@@ -199,17 +204,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddImport
Return False
End Select
Return CanAddImportForTypeOrNamespaceCore(node)
Return CanAddImportForTypeOrNamespaceCore(node, nameNode)
End Function
Private Shared Function CanAddImportForTypeOrNamespaceCore(ByRef node As SyntaxNode) As Boolean
Private Shared Function CanAddImportForTypeOrNamespaceCore(node As SyntaxNode, nameNode As SimpleNameSyntax) As Boolean
Dim qn = TryCast(node, QualifiedNameSyntax)
If qn IsNot Nothing Then
node = GetLeftMostSimpleName(qn)
End If
Dim simpleName = TryCast(node, SimpleNameSyntax)
Return simpleName.LooksLikeStandaloneTypeName()
nameNode = TryCast(node, SimpleNameSyntax)
Return nameNode.LooksLikeStandaloneTypeName()
End Function
Private Shared Function GetLeftMostSimpleName(qn As QualifiedNameSyntax) As SimpleNameSyntax
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册