예제 #1
0
        private static ImmutableArray <ISymbol> GetSymbolsForExpressionOrStatementContext(
            CSharpSyntaxContext context,
            bool filterOutOfScopeLocals,
            CancellationToken cancellationToken)
        {
            // Check if we're in an interesting situation like this:
            //
            //     i          // <-- here
            //     I = 0;

            // The problem is that "i I = 0" causes a local to be in scope called "I".  So, later when
            // we look up symbols, it masks any other 'I's in scope (i.e. if there's a field with that
            // name).  If this is the case, we do not want to filter out inaccessible locals.
            if (filterOutOfScopeLocals)
            {
                if (context.LeftToken.Parent.IsFoundUnder <LocalDeclarationStatementSyntax>(d => d.Declaration.Type))
                {
                    filterOutOfScopeLocals = false;
                }
            }

            var symbols = !context.IsNameOfContext && context.LeftToken.Parent.IsInStaticContext()
                ? context.SemanticModel.LookupStaticMembers(context.LeftToken.SpanStart)
                : context.SemanticModel.LookupSymbols(context.LeftToken.SpanStart);

            // Filter out any extension methods that might be imported by a using static directive.
            // But include extension methods declared in the context's type or it's parents
            var contextEnclosingNamedType = context.SemanticModel.GetEnclosingNamedType(context.Position, cancellationToken);
            var contextOuterTypes         = context.GetOuterTypes(cancellationToken);

            symbols = symbols.WhereAsArray(symbol =>
                                           !symbol.IsExtensionMethod() ||
                                           contextEnclosingNamedType.Equals(symbol.ContainingType) ||
                                           contextOuterTypes.Any(outerType => outerType.Equals(symbol.ContainingType)));

            // The symbols may include local variables that are declared later in the method and
            // should not be included in the completion list, so remove those. Filter them away,
            // unless we're in the debugger, where we show all locals in scope.
            if (filterOutOfScopeLocals)
            {
                symbols = symbols.WhereAsArray(symbol => !symbol.IsInaccessibleLocal(context.Position));
            }

            return(symbols);
        }