提交 feb0866a 编写于 作者: C Cyrus Najmabadi

Add faster 'ContainsName' helpers as well.

上级 a6628b50
...@@ -3038,7 +3038,29 @@ public override IEnumerable<ISymbol> GetSymbolsWithName(Func<string, bool> predi ...@@ -3038,7 +3038,29 @@ public override IEnumerable<ISymbol> GetSymbolsWithName(Func<string, bool> predi
} }
/// <summary> /// <summary>
/// Return source declaration symbols whose name matches the provided name /// Return true if there is a source declaration symbol name that matches the provided name.
/// This will be faster than <see cref="ContainsSymbolsWithName(Func{string, bool}, SymbolFilter, CancellationToken)"/>
/// when predicate is just a simple string check.
/// </summary>
internal override bool ContainsSymbolsWithName(string name, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken))
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
if (filter == SymbolFilter.None)
{
throw new ArgumentException(CSharpResources.NoNoneSearchCriteria, nameof(filter));
}
return DeclarationTable.ContainsName(this.MergedRootDeclaration, name, filter, cancellationToken);
}
/// <summary>
/// Return source declaration symbols whose name matches the provided name. This will be
/// faster than <see cref="GetSymbolsWithName(Func{string, bool}, SymbolFilter, CancellationToken)"/>
/// when predicate is just a simple string check.
/// </summary> /// </summary>
internal override IEnumerable<ISymbol> GetSymbolsWithName(string name, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken)) internal override IEnumerable<ISymbol> GetSymbolsWithName(string name, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken))
{ {
......
...@@ -265,9 +265,46 @@ public IEnumerable<ReferenceDirective> ReferenceDirectives ...@@ -265,9 +265,46 @@ public IEnumerable<ReferenceDirective> ReferenceDirectives
} }
public static bool ContainsName( public static bool ContainsName(
MergedNamespaceDeclaration mergedRoot,
string name,
SymbolFilter filter,
CancellationToken cancellationToken)
{
return ContainsNameHelper(
mergedRoot,
n => n == name,
filter,
t => t.MemberNames.Contains(name),
cancellationToken);
}
public static bool ContainsName(
MergedNamespaceDeclaration mergedRoot,
Func<string, bool> predicate,
SymbolFilter filter,
CancellationToken cancellationToken)
{
return ContainsNameHelper(
mergedRoot, predicate, filter,
t =>
{
foreach (var name in t.MemberNames)
{
if (predicate(name))
{
return true;
}
}
return false;
}, cancellationToken);
}
private static bool ContainsNameHelper(
MergedNamespaceDeclaration mergedRoot, MergedNamespaceDeclaration mergedRoot,
Func<string, bool> predicate, Func<string, bool> predicate,
SymbolFilter filter, SymbolFilter filter,
Func<SingleTypeDeclaration, bool> typePredicate,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var includeNamespace = (filter & SymbolFilter.Namespace) == SymbolFilter.Namespace; var includeNamespace = (filter & SymbolFilter.Namespace) == SymbolFilter.Namespace;
...@@ -304,9 +341,9 @@ public IEnumerable<ReferenceDirective> ReferenceDirectives ...@@ -304,9 +341,9 @@ public IEnumerable<ReferenceDirective> ReferenceDirectives
if (includeMember) if (includeMember)
{ {
var mergedType = (MergedTypeDeclaration)current; var mergedType = (MergedTypeDeclaration)current;
foreach (var name in mergedType.MemberNames) foreach (var typeDecl in mergedType.Declarations)
{ {
if (predicate(name)) if (typePredicate(typeDecl))
{ {
return true; return true;
} }
...@@ -314,17 +351,14 @@ public IEnumerable<ReferenceDirective> ReferenceDirectives ...@@ -314,17 +351,14 @@ public IEnumerable<ReferenceDirective> ReferenceDirectives
} }
} }
foreach (var child in current.Children.OfType<MergedNamespaceOrTypeDeclaration>()) foreach (var child in current.Children)
{ {
if (includeMember || includeType) if (child is MergedNamespaceOrTypeDeclaration childNamespaceOrType)
{
stack.Push(child);
continue;
}
if (child.Kind == DeclarationKind.Namespace)
{ {
stack.Push(child); if (includeMember || includeType || childNamespaceOrType.Kind == DeclarationKind.Namespace)
{
stack.Push(childNamespaceOrType);
}
} }
} }
} }
......
...@@ -2908,7 +2908,16 @@ internal string GetMessage(ITypeSymbol source, ITypeSymbol destination) ...@@ -2908,7 +2908,16 @@ internal string GetMessage(ITypeSymbol source, ITypeSymbol destination)
public abstract IEnumerable<ISymbol> GetSymbolsWithName(Func<string, bool> predicate, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken)); public abstract IEnumerable<ISymbol> GetSymbolsWithName(Func<string, bool> predicate, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken));
/// <summary> /// <summary>
/// Return source declaration symbols whose name matches the provided name /// Return true if there is a source declaration symbol name that matches the provided name.
/// This will be faster than <see cref="ContainsSymbolsWithName(Func{string, bool}, SymbolFilter, CancellationToken)"/>
/// when predicate is just a simple string check.
/// </summary>
internal abstract bool ContainsSymbolsWithName(string name, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Return source declaration symbols whose name matches the provided name. This will be
/// faster than <see cref="GetSymbolsWithName(Func{string, bool}, SymbolFilter, CancellationToken)"/>
/// when predicate is just a simple string check.
/// </summary> /// </summary>
internal abstract IEnumerable<ISymbol> GetSymbolsWithName(string name, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken)); internal abstract IEnumerable<ISymbol> GetSymbolsWithName(string name, SymbolFilter filter = SymbolFilter.TypeAndMember, CancellationToken cancellationToken = default(CancellationToken));
......
...@@ -2729,6 +2729,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -2729,6 +2729,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return New PredicateSymbolSearcher(Me, filter, predicate, cancellationToken).GetSymbolsWithName() Return New PredicateSymbolSearcher(Me, filter, predicate, cancellationToken).GetSymbolsWithName()
End Function End Function
Friend Overrides Function ContainsSymbolsWithName(name As String, Optional filter As SymbolFilter = SymbolFilter.TypeAndMember, Optional cancellationToken As CancellationToken = Nothing) As Boolean
If name Is Nothing Then
Throw New ArgumentNullException(NameOf(name))
End If
If filter = SymbolFilter.None Then
Throw New ArgumentException(VBResources.NoNoneSearchCriteria, NameOf(filter))
End If
Return DeclarationTable.ContainsName(MergedRootDeclaration, name, filter, cancellationToken)
End Function
Friend Overrides Function GetSymbolsWithName(name As String, Optional filter As SymbolFilter = SymbolFilter.TypeAndMember, Optional cancellationToken As CancellationToken = Nothing) As IEnumerable(Of ISymbol) Friend Overrides Function GetSymbolsWithName(name As String, Optional filter As SymbolFilter = SymbolFilter.TypeAndMember, Optional cancellationToken As CancellationToken = Nothing) As IEnumerable(Of ISymbol)
If name Is Nothing Then If name Is Nothing Then
Throw New ArgumentNullException(NameOf(name)) Throw New ArgumentNullException(NameOf(name))
......
...@@ -280,9 +280,46 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -280,9 +280,46 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
End Property End Property
Public Shared Function ContainsName( Public Shared Function ContainsName(
mergedRoot As MergedNamespaceDeclaration,
name As String,
filter As SymbolFilter,
cancellationToken As CancellationToken) As Boolean
Return ContainsNameHelper(
mergedRoot,
Function(n) IdentifierComparison.Equals(n, name),
filter,
Function(t) t.MemberNames.Contains(name),
cancellationToken)
End Function
Public Shared Function ContainsName(
mergedRoot As MergedNamespaceDeclaration,
predicate As Func(Of String, Boolean),
filter As SymbolFilter,
cancellationToken As CancellationToken) As Boolean
Return ContainsNameHelper(
mergedRoot,
predicate,
filter,
Function(t)
For Each name In t.MemberNames
If predicate(name) Then
Return True
End If
Next
Return False
End Function,
cancellationToken)
End Function
Private Shared Function ContainsNameHelper(
mergedRoot As MergedNamespaceDeclaration, mergedRoot As MergedNamespaceDeclaration,
predicate As Func(Of String, Boolean), predicate As Func(Of String, Boolean),
filter As SymbolFilter, filter As SymbolFilter,
typePredicate As Func(Of SingleTypeDeclaration, Boolean),
cancellationToken As CancellationToken) As Boolean cancellationToken As CancellationToken) As Boolean
Dim includeNamespace = (filter And SymbolFilter.Namespace) = SymbolFilter.Namespace Dim includeNamespace = (filter And SymbolFilter.Namespace) = SymbolFilter.Namespace
...@@ -311,22 +348,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -311,22 +348,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
If includeMember Then If includeMember Then
Dim mergedType = DirectCast(current, MergedTypeDeclaration) Dim mergedType = DirectCast(current, MergedTypeDeclaration)
For Each name In mergedType.MemberNames For Each childType In mergedType.Declarations
If predicate(name) Then If typePredicate(childType) Then
Return True Return True
End If End If
Next Next
End If End If
End If End If
For Each child In current.Children.OfType(Of MergedNamespaceOrTypeDeclaration)() For Each child In current.Children
If includeMember OrElse includeType Then Dim childNamespaceOrType = DirectCast(child, MergedNamespaceOrTypeDeclaration)
stack.Push(child)
Continue For
End If
If child.Kind = DeclarationKind.Namespace Then If includeMember OrElse includeType OrElse childNamespaceOrType.Kind = DeclarationKind.Namespace Then
stack.Push(child) stack.Push(childNamespaceOrType)
End If End If
Next Next
End While End While
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册