提交 1dd5d8c1 编写于 作者: C Charles Stoner

Avoid re-calculating base types

Conflicts:
	src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/SymbolCompletionProviderTests.vb
上级 4e74318b
...@@ -5871,5 +5871,131 @@ End Module ...@@ -5871,5 +5871,131 @@ End Module
VerifyNoItemsExist(text) VerifyNoItemsExist(text)
End Sub End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub InstanceMembersFromBaseOuterType()
Dim text =
<code><![CDATA[
MustInherit Class Test
Private _field As Integer
NotInheritable Class InnerTest
Inherits Test
Sub SomeTest()
Dim x = $$
End Sub
End Class
End Class
]]></code>.Value
VerifyItemExists(text, "_field")
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub InstanceMembersFromBaseOuterType2()
Dim text =
<code><![CDATA[
Class C(Of T)
Sub M()
End Sub
Class N
Inherits C(Of Integer)
Sub Test()
$$ ' M recommended and accessible
End Sub
Class NN
Sub Test2()
' M inaccessible and not recommended
End Sub
End Class
End Class
End Class
]]></code>.Value
VerifyItemExists(text, "M")
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub InstanceMembersFromBaseOuterType3()
Dim text =
<code><![CDATA[
Class C(Of T)
Sub M()
End Sub
Class N
Inherits C(Of Integer)
Sub Test()
' M recommended and accessible
End Sub
Class NN
Sub Test2()
$$ ' M inaccessible and not recommended
End Sub
End Class
End Class
End Class
]]></code>.Value
VerifyItemIsAbsent(text, "M")
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub InstanceMembersFromBaseOuterType4()
Dim text =
<code><![CDATA[
Class C(Of T)
Sub M()
End Sub
Class N
Inherits C(Of Integer)
Sub Test()
M() ' M recommended and accessible
End Sub
Class NN
Inherits N
Sub Test2()
$$ ' M inaccessible and not recommended
End Sub
End Class
End Class
End Class
]]></code>.Value
VerifyItemExists(text, "M")
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub InstanceMembersFromBaseOuterType5()
Dim text =
<code><![CDATA[
Class D
Public Sub Q()
End Sub
End Class
Class C(Of T)
Inherits D
Class N
Sub Test()
$$
End Sub
End Class
End Class
]]></code>.Value
VerifyItemIsAbsent(text, "Q")
End Sub
<Fact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Sub InstanceMembersFromBaseOuterType6()
Dim text =
<code><![CDATA[
Class Base(Of T)
Public X As Integer
End Class
Class Derived
Inherits C(Of Integer)
Class Nested
Sub Test()
$$
End Sub
End Class
End Class
]]></code>.Value
VerifyItemIsAbsent(text, "X")
End Sub
End Class End Class
End Namespace End Namespace
\ No newline at end of file
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery; using Microsoft.CodeAnalysis.Shared.Extensions.ContextQuery;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Recommendations namespace Microsoft.CodeAnalysis.Recommendations
{ {
...@@ -21,13 +22,26 @@ internal abstract class AbstractRecommendationService : IRecommendationService ...@@ -21,13 +22,26 @@ internal abstract class AbstractRecommendationService : IRecommendationService
var result = GetRecommendedSymbolsAtPositionWorker(workspace, semanticModel, position, options, cancellationToken); var result = GetRecommendedSymbolsAtPositionWorker(workspace, semanticModel, position, options, cancellationToken);
var symbols = result.Item1; var symbols = result.Item1;
var context = result.Item2; var context = new ShouldIncludeSymbolContext(result.Item2, cancellationToken);
symbols = symbols.Where(s => ShouldIncludeSymbol(s, context, cancellationToken)); symbols = symbols.Where(context.ShouldIncludeSymbol);
return symbols; return symbols;
} }
private bool ShouldIncludeSymbol(ISymbol symbol, AbstractSyntaxContext context, CancellationToken cancellationToken) private sealed class ShouldIncludeSymbolContext
{
private readonly AbstractSyntaxContext _context;
private readonly CancellationToken _cancellationToken;
private IEnumerable<INamedTypeSymbol> _lazyOuterTypesAndBases;
private IEnumerable<INamedTypeSymbol> _lazyEnclosingTypeBases;
internal ShouldIncludeSymbolContext(AbstractSyntaxContext context, CancellationToken cancellationToken)
{
_context = context;
_cancellationToken = cancellationToken;
}
internal bool ShouldIncludeSymbol(ISymbol symbol)
{ {
var isMember = false; var isMember = false;
switch (symbol.Kind) switch (symbol.Kind)
...@@ -42,13 +56,13 @@ private bool ShouldIncludeSymbol(ISymbol symbol, AbstractSyntaxContext context, ...@@ -42,13 +56,13 @@ private bool ShouldIncludeSymbol(ISymbol symbol, AbstractSyntaxContext context,
break; break;
case SymbolKind.Method: case SymbolKind.Method:
var methodSymbol = (IMethodSymbol)symbol; switch (((IMethodSymbol)symbol).MethodKind)
if (methodSymbol.MethodKind == MethodKind.EventAdd ||
methodSymbol.MethodKind == MethodKind.EventRemove ||
methodSymbol.MethodKind == MethodKind.EventRaise ||
methodSymbol.MethodKind == MethodKind.PropertyGet ||
methodSymbol.MethodKind == MethodKind.PropertySet)
{ {
case MethodKind.EventAdd:
case MethodKind.EventRemove:
case MethodKind.EventRaise:
case MethodKind.PropertyGet:
case MethodKind.PropertySet:
return false; return false;
} }
...@@ -65,38 +79,60 @@ private bool ShouldIncludeSymbol(ISymbol symbol, AbstractSyntaxContext context, ...@@ -65,38 +79,60 @@ private bool ShouldIncludeSymbol(ISymbol symbol, AbstractSyntaxContext context,
return ((ITypeParameterSymbol)symbol).TypeParameterKind != TypeParameterKind.Cref; return ((ITypeParameterSymbol)symbol).TypeParameterKind != TypeParameterKind.Cref;
} }
if (context.IsAttributeNameContext) if (_context.IsAttributeNameContext)
{ {
var enclosingSymbol = context.SemanticModel.GetEnclosingNamedType(context.LeftToken.SpanStart, cancellationToken); var enclosingSymbol = _context.SemanticModel.GetEnclosingNamedType(_context.LeftToken.SpanStart, _cancellationToken);
return symbol.IsOrContainsAccessibleAttribute(enclosingSymbol, context.SemanticModel.Compilation.Assembly); return symbol.IsOrContainsAccessibleAttribute(enclosingSymbol, _context.SemanticModel.Compilation.Assembly);
} }
if (context.IsEnumTypeMemberAccessContext) if (_context.IsEnumTypeMemberAccessContext)
{ {
return symbol.Kind == SymbolKind.Field; return symbol.Kind == SymbolKind.Field;
} }
// In an expression or statement context, we don't want to display instance members declared in outer containing types. // In an expression or statement context, we don't want to display instance members declared in outer containing types.
if ((context.IsStatementContext || context.IsAnyExpressionContext) && if ((_context.IsStatementContext || _context.IsAnyExpressionContext) &&
!symbol.IsStatic && !symbol.IsStatic &&
isMember) isMember)
{ {
var outerTypesAndBases = context.GetOuterTypes(cancellationToken).SelectMany(o => o.GetBaseTypesAndThis()).Select(t => t.OriginalDefinition);
var containingTypeOriginalDefinition = symbol.ContainingType.OriginalDefinition; var containingTypeOriginalDefinition = symbol.ContainingType.OriginalDefinition;
if (outerTypesAndBases.Contains(containingTypeOriginalDefinition)) if (this.GetOuterTypesAndBases().Contains(containingTypeOriginalDefinition))
{ {
var enclosingType = context.SemanticModel.GetEnclosingNamedType(context.LeftToken.SpanStart, cancellationToken); return this.GetEnclosingTypeBases().Contains(containingTypeOriginalDefinition);
return enclosingType != null && enclosingType.GetBaseTypes().Select(b => b.OriginalDefinition).Contains(containingTypeOriginalDefinition);
} }
} }
var namespaceSymbol = symbol as INamespaceSymbol; var namespaceSymbol = symbol as INamespaceSymbol;
if (namespaceSymbol != null) if (namespaceSymbol != null)
{ {
return namespaceSymbol.ContainsAccessibleTypesOrNamespaces(context.SemanticModel.Compilation.Assembly); return namespaceSymbol.ContainsAccessibleTypesOrNamespaces(_context.SemanticModel.Compilation.Assembly);
} }
return true; return true;
} }
private IEnumerable<INamedTypeSymbol> GetOuterTypesAndBases()
{
if (_lazyOuterTypesAndBases == null)
{
_lazyOuterTypesAndBases = _context.GetOuterTypes(_cancellationToken).SelectMany(o => o.GetBaseTypesAndThis()).Select(t => t.OriginalDefinition);
}
return _lazyOuterTypesAndBases;
}
private IEnumerable<INamedTypeSymbol> GetEnclosingTypeBases()
{
if (_lazyEnclosingTypeBases == null)
{
var enclosingType = _context.SemanticModel.GetEnclosingNamedType(_context.LeftToken.SpanStart, _cancellationToken);
_lazyEnclosingTypeBases = (enclosingType == null) ?
SpecializedCollections.EmptyEnumerable<INamedTypeSymbol>() :
enclosingType.GetBaseTypes().Select(b => b.OriginalDefinition);
}
return _lazyEnclosingTypeBases;
}
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册