提交 5c4d5c29 编写于 作者: C Cyrus Najmabadi

Move extension method

上级 ff3d2a75
...@@ -28,35 +28,6 @@ public static async Task<IEnumerable<SyntaxToken>> GetConstructorInitializerToke ...@@ -28,35 +28,6 @@ public static async Task<IEnumerable<SyntaxToken>> GetConstructorInitializerToke
return FindReferenceCache.GetConstructorInitializerTokens(syntaxFacts, model, root, cancellationToken); return FindReferenceCache.GetConstructorInitializerTokens(syntaxFacts, model, root, cancellationToken);
} }
internal static async Task<ImmutableArray<SyntaxToken>> GetIdentifierOrGlobalNamespaceTokensWithTextAsync(
this Document document, SemanticModel model, string identifier, CancellationToken cancellationToken)
{
// It's very costly to walk an entire tree. So if the tree is simple and doesn't contain
// any unicode escapes in it, then we do simple string matching to find the tokens.
var info = await SyntaxTreeIndex.GetIndexAsync(document, cancellationToken).ConfigureAwait(false);
if (!info.ProbablyContainsIdentifier(identifier))
{
return ImmutableArray<SyntaxToken>.Empty;
}
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
if (syntaxFacts == null)
{
return ImmutableArray<SyntaxToken>.Empty;
}
var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
SourceText text = null;
if (!info.ProbablyContainsEscapedIdentifier(identifier))
{
text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
}
return FindReferenceCache.GetIdentifierOrGlobalNamespaceTokensWithText(syntaxFacts, document, version, model, root, text, identifier, cancellationToken);
}
internal static bool TextMatch(this ISyntaxFactsService syntaxFacts, string text1, string text2) internal static bool TextMatch(this ISyntaxFactsService syntaxFacts, string text1, string text2)
=> syntaxFacts.StringComparer.Equals(text1, text2); => syntaxFacts.StringComparer.Equals(text1, text2);
} }
......
...@@ -62,8 +62,14 @@ public static SymbolInfo GetSymbolInfo(SemanticModel model, SyntaxNode node, Can ...@@ -62,8 +62,14 @@ public static SymbolInfo GetSymbolInfo(SemanticModel model, SyntaxNode node, Can
} }
public static ImmutableArray<SyntaxToken> GetIdentifierOrGlobalNamespaceTokensWithText( public static ImmutableArray<SyntaxToken> GetIdentifierOrGlobalNamespaceTokensWithText(
ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SemanticModel model, SyntaxNode root, SourceText sourceText, ISyntaxFactsService syntaxFacts,
string text, CancellationToken cancellationToken) Document document,
VersionStamp version,
SemanticModel model,
SyntaxNode root,
SourceText sourceText,
string text,
CancellationToken cancellationToken)
{ {
var normalized = syntaxFacts.IsCaseSensitive ? text : text.ToLowerInvariant(); var normalized = syntaxFacts.IsCaseSensitive ? text : text.ToLowerInvariant();
...@@ -82,17 +88,17 @@ public static SymbolInfo GetSymbolInfo(SemanticModel model, SyntaxNode node, Can ...@@ -82,17 +88,17 @@ public static SymbolInfo GetSymbolInfo(SemanticModel model, SyntaxNode node, Can
ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SyntaxNode root, SourceText sourceText, ISyntaxFactsService syntaxFacts, Document document, VersionStamp version, SyntaxNode root, SourceText sourceText,
string text, CancellationToken cancellationToken) string text, CancellationToken cancellationToken)
{ {
bool candidate(SyntaxToken t) =>
syntaxFacts.IsGlobalNamespaceKeyword(t) || (syntaxFacts.IsIdentifier(t) && syntaxFacts.TextMatch(t.ValueText, text));
// identifier is not escaped // identifier is not escaped
if (sourceText != null) if (sourceText != null)
{ {
return GetTokensFromText(syntaxFacts, document, version, root, sourceText, text, candidate, cancellationToken); return GetTokensFromText(syntaxFacts, document, version, root, sourceText, text, IsCandidate, cancellationToken);
} }
// identifier is escaped // identifier is escaped
return root.DescendantTokens(descendIntoTrivia: true).Where(candidate).ToImmutableArray(); return root.DescendantTokens(descendIntoTrivia: true).Where(IsCandidate).ToImmutableArray();
bool IsCandidate(SyntaxToken t)
=> syntaxFacts.IsGlobalNamespaceKeyword(t) || (syntaxFacts.IsIdentifier(t) && syntaxFacts.TextMatch(t.ValueText, text));
} }
private static ImmutableArray<SyntaxToken> GetTokensFromText( private static ImmutableArray<SyntaxToken> GetTokensFromText(
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities; using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.FindSymbols.Finders namespace Microsoft.CodeAnalysis.FindSymbols.Finders
...@@ -167,7 +168,7 @@ protected static bool IdentifiersMatch(ISyntaxFactsService syntaxFacts, string n ...@@ -167,7 +168,7 @@ protected static bool IdentifiersMatch(ISyntaxFactsService syntaxFacts, string n
Func<SyntaxToken, SemanticModel, (bool matched, CandidateReason reason)> symbolsMatch, Func<SyntaxToken, SemanticModel, (bool matched, CandidateReason reason)> symbolsMatch,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var tokens = await document.GetIdentifierOrGlobalNamespaceTokensWithTextAsync(semanticModel, identifier, cancellationToken).ConfigureAwait(false); var tokens = await GetIdentifierOrGlobalNamespaceTokensWithTextAsync(document, semanticModel, identifier, cancellationToken).ConfigureAwait(false);
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>(); var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
...@@ -180,6 +181,29 @@ protected static bool IdentifiersMatch(ISyntaxFactsService syntaxFacts, string n ...@@ -180,6 +181,29 @@ protected static bool IdentifiersMatch(ISyntaxFactsService syntaxFacts, string n
cancellationToken); cancellationToken);
} }
protected static async Task<ImmutableArray<SyntaxToken>> GetIdentifierOrGlobalNamespaceTokensWithTextAsync(Document document, SemanticModel semanticModel, string identifier, CancellationToken cancellationToken)
{
// It's very costly to walk an entire tree. So if the tree is simple and doesn't contain
// any unicode escapes in it, then we do simple string matching to find the tokens.
var info = await SyntaxTreeIndex.GetIndexAsync(document, cancellationToken).ConfigureAwait(false);
if (!info.ProbablyContainsIdentifier(identifier))
return ImmutableArray<SyntaxToken>.Empty;
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
if (syntaxFacts == null)
return ImmutableArray<SyntaxToken>.Empty;
var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
var version = await document.GetSyntaxVersionAsync(cancellationToken).ConfigureAwait(false);
SourceText text = null;
if (!info.ProbablyContainsEscapedIdentifier(identifier))
text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
return FindReferenceCache.GetIdentifierOrGlobalNamespaceTokensWithText(
syntaxFacts, document, version, semanticModel, root, text, identifier, cancellationToken);
}
protected static Func<SyntaxToken, SemanticModel, (bool matched, CandidateReason reason)> GetStandardSymbolsMatchFunction( protected static Func<SyntaxToken, SemanticModel, (bool matched, CandidateReason reason)> GetStandardSymbolsMatchFunction(
ISymbol symbol, Func<SyntaxToken, SyntaxNode> findParentNode, Solution solution, CancellationToken cancellationToken) ISymbol symbol, Func<SyntaxToken, SyntaxNode> findParentNode, Solution solution, CancellationToken cancellationToken)
{ {
......
...@@ -62,7 +62,8 @@ protected override bool CanFind(IMethodSymbol symbol) ...@@ -62,7 +62,8 @@ protected override bool CanFind(IMethodSymbol symbol)
var tokens = await document.GetConstructorInitializerTokensAsync(semanticModel, cancellationToken).ConfigureAwait(false); var tokens = await document.GetConstructorInitializerTokensAsync(semanticModel, cancellationToken).ConfigureAwait(false);
if (semanticModel.Language == LanguageNames.VisualBasic) if (semanticModel.Language == LanguageNames.VisualBasic)
{ {
tokens = tokens.Concat(await document.GetIdentifierOrGlobalNamespaceTokensWithTextAsync(semanticModel, "New", cancellationToken).ConfigureAwait(false)).Distinct(); tokens = tokens.Concat(await GetIdentifierOrGlobalNamespaceTokensWithTextAsync(
document, semanticModel, "New", cancellationToken).ConfigureAwait(false)).Distinct();
} }
return FindReferencesInTokens( return FindReferencesInTokens(
......
...@@ -44,11 +44,13 @@ private static string GetNamespaceIdentifierName(INamespaceSymbol symbol) ...@@ -44,11 +44,13 @@ private static string GetNamespaceIdentifierName(INamespaceSymbol symbol)
var identifierName = GetNamespaceIdentifierName(symbol); var identifierName = GetNamespaceIdentifierName(symbol);
var syntaxFactsService = document.GetLanguageService<ISyntaxFactsService>(); var syntaxFactsService = document.GetLanguageService<ISyntaxFactsService>();
var tokens = await GetIdentifierOrGlobalNamespaceTokensWithTextAsync(
document, semanticModel, identifierName, cancellationToken).ConfigureAwait(false);
var nonAliasReferences = FindReferencesInTokens(symbol, var nonAliasReferences = FindReferencesInTokens(symbol,
document, document,
semanticModel, semanticModel,
await document.GetIdentifierOrGlobalNamespaceTokensWithTextAsync(semanticModel, identifierName, cancellationToken).ConfigureAwait(false), tokens,
(SyntaxToken t) => syntaxFactsService.TextMatch(t.ValueText, identifierName), t => syntaxFactsService.TextMatch(t.ValueText, identifierName),
cancellationToken); cancellationToken);
var aliasReferences = await FindAliasReferencesAsync(nonAliasReferences, symbol, document, semanticModel, cancellationToken).ConfigureAwait(false); var aliasReferences = await FindAliasReferencesAsync(nonAliasReferences, symbol, document, semanticModel, cancellationToken).ConfigureAwait(false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册