protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return
         context.IsGlobalStatementContext ||
         context.IsMemberDeclarationContext(
             validModifiers: s_validMemberModifiers,
             validTypeDeclarations: SyntaxKindSet.ClassOnlyTypeDeclarations,
             canBePartial: false,
             cancellationToken: cancellationToken) ||
         context.IsTypeDeclarationContext(
             validModifiers: s_validTypeModifiers,
             validTypeDeclarations: SyntaxKindSet.ClassStructTypeDeclarations,
             canBePartial: false,
             cancellationToken: cancellationToken);
 }
        protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
        {
            // cases:
            //   extern |
            //   extern a|
            var token = context.TargetToken;

            if (token.Kind() == SyntaxKind.ExternKeyword)
            {
                // members can be 'extern' but we don't want
                // 'alias' to show up in a 'type'.
                return token.GetAncestor<TypeDeclarationSyntax>() == null;
            }

            return false;
        }
Exemple #3
0
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return
         (IsInBreakableConstructContext(context) ||
          context.TargetToken.IsAfterYieldKeyword());
 }
        private static ImmutableArray <ISymbol> GetSymbolsOffOfName(
            CSharpSyntaxContext context,
            NameSyntax name,
            CancellationToken cancellationToken)
        {
            // Check if we're in an interesting situation like this:
            //
            //     int i = 5;
            //     i.          // <-- here
            //     List<string> ml = new List<string>();

            // The problem is that "i.List<string>" gets parsed as a type.  In this case we need to
            // try binding again as if "i" is an expression and not a type.  In order to do that, we
            // need to speculate as to what 'i' meant if it wasn't part of a local declaration's
            // type.

            if (name.IsFoundUnder <LocalDeclarationStatementSyntax>(d => d.Declaration.Type))
            {
                var speculativeBinding = context.SemanticModel.GetSpeculativeSymbolInfo(name.SpanStart, name, SpeculativeBindingOption.BindAsExpression);
                var container          = context.SemanticModel.GetSpeculativeTypeInfo(name.SpanStart, name, SpeculativeBindingOption.BindAsExpression).Type;
                return(GetSymbolsOffOfBoundExpression(context, name, name, speculativeBinding, container, cancellationToken));
            }

            // We're in a name-only context, since if we were an expression we'd be a
            // MemberAccessExpressionSyntax. Thus, let's do other namespaces and types.
            var nameBinding = context.SemanticModel.GetSymbolInfo(name, cancellationToken);

            var symbol = nameBinding.Symbol as INamespaceOrTypeSymbol;

            if (symbol != null)
            {
                if (context.IsNameOfContext)
                {
                    return(context.SemanticModel.LookupSymbols(position: name.SpanStart, container: symbol));
                }

                var symbols = context.SemanticModel.LookupNamespacesAndTypes(
                    position: name.SpanStart,
                    container: symbol);

                if (context.IsNamespaceDeclarationNameContext)
                {
                    var declarationSyntax = name.GetAncestorOrThis <NamespaceDeclarationSyntax>();
                    return(symbols.WhereAsArray(s => IsNonIntersectingNamespace(s, declarationSyntax)));
                }

                // Filter the types when in a using directive, but not an alias.
                //
                // Cases:
                //    using | -- Show namespaces
                //    using A.| -- Show namespaces
                //    using static | -- Show namespace and types
                //    using A = B.| -- Show namespace and types
                var usingDirective = name.GetAncestorOrThis <UsingDirectiveSyntax>();
                if (usingDirective != null && usingDirective.Alias == null)
                {
                    if (usingDirective.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                    {
                        return(symbols.WhereAsArray(s => !s.IsDelegateType() && !s.IsInterfaceType()));
                    }
                    else
                    {
                        symbols = symbols.WhereAsArray(s => s.IsNamespace());
                    }
                }

                if (symbols.Any())
                {
                    return(symbols);
                }
            }

            return(ImmutableArray <ISymbol> .Empty);
        }
Exemple #5
0
 private static bool IsUnsafeParameterTypeContext(CSharpSyntaxContext context)
 {
     return
         (context.TargetToken.IsUnsafeContext() &&
          context.IsParameterTypeContext);
 }
Exemple #6
0
 private static bool IsMemberReturnTypeContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 => context.SyntaxTree.IsGlobalMemberDeclarationContext(position, SyntaxKindSet.AllGlobalMemberModifiers, cancellationToken) ||
 context.IsMemberDeclarationContext(validModifiers: s_validClassInterfaceRecordModifiers, validTypeDeclarations: SyntaxKindSet.ClassInterfaceRecordTypeDeclarations, canBePartial: true, cancellationToken) ||
 context.IsMemberDeclarationContext(validModifiers: s_validStructModifiers, validTypeDeclarations: SyntaxKindSet.StructOnlyTypeDeclarations, canBePartial: false, cancellationToken);
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     // cases:
     //    expr |
     return(!context.IsInNonUserCode && context.IsIsOrAsContext);
 }
Exemple #8
0
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 => context.SyntaxTree.IsParamsModifierContext(context.Position, context.LeftToken);
Exemple #9
0
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return(context.ContainingTypeDeclaration == null &&
            context.IsTypeDeclarationContext(s_validModifiers, SyntaxKindSet.AllTypeDeclarations, canBePartial: true, cancellationToken));
 }
 private static bool IsValidNewByRefContext(SyntaxTree syntaxTree, int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return
         (IsValidRefExpressionContext(context) ||
          context.IsDelegateReturnTypeContext ||
          syntaxTree.IsGlobalMemberDeclarationContext(position, RefGlobalMemberModifiers, cancellationToken) ||
          context.IsMemberDeclarationContext(
              validModifiers: RefMemberModifiers,
              validTypeDeclarations: SyntaxKindSet.ClassInterfaceStructTypeDeclarations,
              canBePartial: true,
              cancellationToken: cancellationToken));
 }
 private static bool IsValidContextForType(CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return(context.IsTypeDeclarationContext(validModifiers: SyntaxKindSet.AllTypeModifiers,
                                             validTypeDeclarations: SyntaxKindSet.ClassInterfaceStructTypeDeclarations, canBePartial: true, cancellationToken));
 }
        private static bool IsValidRefExpressionContext(CSharpSyntaxContext context)
        {
            // {
            //     ref var x ...
            //
            if (context.IsStatementContext)
            {
                return(true);
            }

            //
            //  ref Goo(int x, ...
            //
            if (context.IsGlobalStatementContext)
            {
                return(true);
            }

            var token = context.TargetToken;

            switch (token.Kind())
            {
            // {
            //     return ref  ...
            //
            case SyntaxKind.ReturnKeyword:
                return(true);

            // {
            //     () => ref ...
            //
            case SyntaxKind.EqualsGreaterThanToken:
                return(true);

            // {
            //     for (ref var x ...
            //
            //     foreach (ref var x ...
            //
            case SyntaxKind.OpenParenToken:
                var previous = token.GetPreviousToken(includeSkipped: true);
                return(previous.IsKind(SyntaxKind.ForKeyword) ||
                       previous.IsKind(SyntaxKind.ForEachKeyword));

            // {
            //     ref var x = ref
            //
            case SyntaxKind.EqualsToken:
                var parent = token.Parent;
                return(parent?.Kind() == SyntaxKind.SimpleAssignmentExpression ||
                       parent?.Parent?.Kind() == SyntaxKind.VariableDeclarator);

            // {
            //     var x = true ?
            //     var x = true ? ref y :
            case SyntaxKind.QuestionToken:
            case SyntaxKind.ColonToken:
                return(token.Parent?.Kind() == SyntaxKind.ConditionalExpression);
            }

            return(false);
        }
Exemple #13
0
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 => context.IsAnyExpressionContext ||
 context.IsStatementContext ||
 context.IsGlobalStatementContext ||
 context.LeftToken.IsInCastExpressionTypeWhereExpressionIsMissingOrInNextLine();
        public override async Task ProduceCompletionListAsync(CompletionListContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var options           = context.Options;
            var cancellationToken = context.CancellationToken;

            var span          = new TextSpan(position, length: 0);
            var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);

            var syntaxTree = semanticModel.SyntaxTree;

            var syntaxFacts   = document.GetLanguageService <ISyntaxFactsService>();
            var semanticFacts = document.GetLanguageService <ISemanticFactsService>();

            if (syntaxFacts.IsInNonUserCode(syntaxTree, position, cancellationToken) ||
                semanticFacts.IsPreProcessorDirectiveContext(semanticModel, position, cancellationToken))
            {
                return;
            }

            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken))
            {
                return;
            }

            var node = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken)
                       .GetPreviousTokenIfTouchingWord(position)
                       .Parent;

            if (node.Kind() != SyntaxKind.ExplicitInterfaceSpecifier)
            {
                return;
            }

            // Bind the interface name which is to the left of the dot
            var name = ((ExplicitInterfaceSpecifierSyntax)node).Name;

            var symbol = semanticModel.GetSymbolInfo(name, cancellationToken).Symbol as ITypeSymbol;

            if (symbol?.TypeKind != TypeKind.Interface)
            {
                return;
            }

            var members = semanticModel.LookupSymbols(
                position: name.SpanStart,
                container: symbol)
                          .Where(s => !s.IsStatic)
                          .FilterToVisibleAndBrowsableSymbols(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation);

            // We're going to create a entry for each one, including the signature
            var namePosition = name.SpanStart;

            var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, position);

            foreach (var member in members)
            {
                var displayText   = member.ToMinimalDisplayString(semanticModel, namePosition, s_signatureDisplayFormat);
                var insertionText = displayText;

                context.AddItem(new SymbolCompletionItem(
                                    this,
                                    displayText,
                                    insertionText: insertionText,
                                    filterSpan: textChangeSpan,
                                    position: position,
                                    symbols: new List <ISymbol> {
                    member
                },
                                    context: CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken),
                                    rules: ItemRules.Instance));
            }
        }
        private static bool IsAfterCompleteExpressionOrPatternInCaseLabel(CSharpSyntaxContext context,
                                                                          out SyntaxNodeOrToken nodeOrToken)
        {
            nodeOrToken = null;

            var switchLabel = context.TargetToken.GetAncestor <SwitchLabelSyntax>();

            if (switchLabel == null)
            {
                return(false);
            }

            var expressionOrPattern = switchLabel.ChildNodes().FirstOrDefault();

            if (expressionOrPattern == null)
            {
                // It must have been a default label.
                return(false);
            }

            // If the last token is missing, the expression is incomplete - possibly because of missing parentheses,
            // but not necessarily. We don't want to offer 'when' in those cases. Here are some examples that illustrate this:
            // case |
            // case x.|
            // case 1 + |
            // case (1 + 1 |

            // Also note that if there's a missing token inside the expression, that's fine and we do offer 'when':
            // case (1 + ) |

            if (expressionOrPattern.GetLastToken(includeZeroWidth: true).IsMissing)
            {
                return(false);
            }

            // There are zero width tokens that are not "missing" (inserted by the parser) because they are optional,
            // such as the identifier in a recursive pattern. We want to ignore those now, so we exclude all zero width.

            var lastToken = expressionOrPattern.GetLastToken(includeZeroWidth: false);

            if (lastToken == context.TargetToken)
            {
                nodeOrToken = expressionOrPattern;
                return(true);
            }

            if (lastToken == context.LeftToken)
            {
                // The user is typing a new word (might be a partially written 'when' keyword),
                // which is part of the pattern as opposed to appearing outside of it. In a few special cases,
                // this word can actually be replaced with 'when' and the resulting pattern would still be valid.

                if (expressionOrPattern is DeclarationPatternSyntax declarationPattern)
                {
                    // The new token causes this to be parsed as a declaration pattern:
                    // case constant w| ('w' = LeftToken, 'constant' = TargetToken)

                    // However 'constant' itself might end up being a valid constant pattern.
                    // We will pretend as if 'w' didn't exist so that the later check
                    // for whether 'constant' is actually a type can still work properly.
                    nodeOrToken = declarationPattern.Type;
                    return(true);
                }

                if (expressionOrPattern is VarPatternSyntax varPattern)
                {
                    // The new token causes this to be parsed as a var pattern:
                    // case var w| ('w' = LeftToken, 'var' = TargetToken)

                    // However 'var' itself might end up being a valid constant pattern.
                    nodeOrToken = varPattern.VarKeyword;
                    return(true);
                }

                if (expressionOrPattern is RecursivePatternSyntax recursivePattern)
                {
                    // The new token is consumed as the identifier in a recursive pattern:
                    // case { } w| ('w' = LeftToken, '}' = TargetToken)

                    // However the identifier is optional and can be replaced by 'when'.
                    nodeOrToken = recursivePattern.Type;
                    return(true);
                }

                // In other cases, this would not be true because the pattern would be incomplete without this word:
                // case 1 + w|
            }

            return(false);
        }
		static async Task<IEnumerable<ISymbol>> GetPreselectedSymbolsWorker (CSharpSyntaxContext context, ITypeSymbol inferredType, int position, CancellationToken cancellationToken)
		{
			var result = await GetPreselectedSymbolsWorker2 (context, inferredType, cancellationToken).ConfigureAwait (false);
			if (result.Any ()) {
				var type = (ITypeSymbol)result.Single ();
				var alias = await type.FindApplicableAlias (position, context.SemanticModel, cancellationToken).ConfigureAwait (false);
				if (alias != null) {
					return SpecializedCollections.SingletonEnumerable (alias);
				}
			}

			return result;
		}
        public static bool IsMemberDeclarationContext(
            this SyntaxTree syntaxTree,
            int position,
            CSharpSyntaxContext contextOpt,
            ISet<SyntaxKind> validModifiers,
            ISet<SyntaxKind> validTypeDeclarations,
            bool canBePartial,
            CancellationToken cancellationToken)
        {
            var typeDecl = contextOpt != null
                ? contextOpt.ContainingTypeOrEnumDeclaration
                : syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken);

            if (typeDecl == null)
            {
                return false;
            }

            if (!validTypeDeclarations.Contains(typeDecl.Kind()))
            {
                return false;
            }

            validTypeDeclarations = validTypeDeclarations ?? SpecializedCollections.EmptySet<SyntaxKind>();

            // Check many of the simple cases first.
            var leftToken = contextOpt != null
                ? contextOpt.LeftToken
                : syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

            if (syntaxTree.IsMemberDeclarationContext(position, leftToken, cancellationToken))
            {
                return true;
            }

            var token = contextOpt != null
                ? contextOpt.TargetToken
                : leftToken.GetPreviousTokenIfTouchingWord(position);

            // A member can also show up after certain types of modifiers
            if (canBePartial &&
                token.IsKindOrHasMatchingText(SyntaxKind.PartialKeyword))
            {
                return true;
            }

            var modifierTokens = contextOpt != null
                ? contextOpt.PrecedingModifiers
                : syntaxTree.GetPrecedingModifiers(position, leftToken, cancellationToken);

            if (!modifierTokens.Any())
            {
                return false;
            }

            validModifiers = validModifiers ?? SpecializedCollections.EmptySet<SyntaxKind>();

            if (modifierTokens.IsSubsetOf(validModifiers))
            {
                var member = token.Parent;
                if (token.HasMatchingText(SyntaxKind.AsyncKeyword))
                {
                    // second appearance of "async", not followed by modifier: treat it as type
                    if (syntaxTree.GetPrecedingModifiers(token.SpanStart, token, cancellationToken).Any(x => x == SyntaxKind.AsyncKeyword))
                    {
                        return false;
                    }

                    // rule out async lambdas inside a method
                    if (token.GetAncestor<StatementSyntax>() == null)
                    {
                        member = token.GetAncestor<MemberDeclarationSyntax>();
                    }
                }

                // cases:
                // public |
                // async |
                // public async |
                return member != null &&
                    member.Parent is BaseTypeDeclarationSyntax;
            }

            return false;
        }
Exemple #18
0
        protected override async Task <SyntaxContext> CreateContext(Document document, int position, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan(position, 0), cancellationToken).ConfigureAwait(false);

            return(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken));
        }
Exemple #19
0
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return
         (context.IsStatementContext ||
          context.IsGlobalStatementContext);
 }
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return(context.IsCatchFilterContext ||
            (IsAfterCompleteExpressionOrPatternInCaseLabel(context, out var expressionOrPattern) &&
             !IsTypeName(expressionOrPattern, context.SemanticModel, cancellationToken)));
 }
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return(context.IsMemberAttributeContext(s_validTypeDeclarations, cancellationToken));
 }
Exemple #22
0
 private bool IsAttributeArgumentContext(CSharpSyntaxContext context)
 {
     return
         (context.IsAnyExpressionContext &&
          context.LeftToken.GetAncestor <AttributeSyntax>() != null);
 }
Exemple #23
0
 private static bool IsUnsafeDefaultExpressionContext(CSharpSyntaxContext context)
 {
     return
         (context.TargetToken.IsUnsafeContext() &&
          context.SyntaxTree.IsDefaultExpressionContext(context.Position, context.LeftToken));
 }
Exemple #24
0
        protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
        {
            var syntaxTree = context.SyntaxTree;

            // namespaces are illegal in interactive code:
            if (syntaxTree.IsScript())
            {
                return(false);
            }

            // cases:
            // root: |

            // root: n|

            // extern alias a;
            // |

            // extern alias a;
            // n|

            // using Foo;
            // |

            // using Foo;
            // n|

            // using Foo = Bar;
            // |

            // using Foo = Bar;
            // n|

            // namespace N {}
            // |

            // namespace N {}
            // n|

            // class C {}
            // |

            // class C {}
            // n|

            var leftToken = context.LeftToken;
            var token     = context.TargetToken;

            // root: n|

            // ns Foo { n|

            // extern alias a;
            // n|

            // using Foo;
            // n|

            // using Foo = Bar;
            // n|

            // a namespace can't come before usings/externs
            // a child namespace can't come before usings/externs
            if (leftToken.GetNextToken(includeSkipped: true).IsUsingOrExternKeyword())
            {
                return(false);
            }

            // root: |
            if (token.Kind() == SyntaxKind.None)
            {
                // root namespace
                var root = syntaxTree.GetRoot(cancellationToken) as CompilationUnitSyntax;
                if (root.Externs.Count > 0 ||
                    root.Usings.Count > 0)
                {
                    return(false);
                }

                return(true);
            }

            if (token.Kind() == SyntaxKind.OpenBraceToken &&
                token.Parent.IsKind(SyntaxKind.NamespaceDeclaration))
            {
                return(true);
            }

            // extern alias a;
            // |

            // using Foo;
            // |
            if (token.Kind() == SyntaxKind.SemicolonToken)
            {
                if (token.Parent.IsKind(SyntaxKind.ExternAliasDirective, SyntaxKind.UsingDirective))
                {
                    return(true);
                }
            }

            // class C {}
            // |
            if (token.Kind() == SyntaxKind.CloseBraceToken)
            {
                if (token.Parent is TypeDeclarationSyntax &&
                    !(token.Parent.GetParent() is TypeDeclarationSyntax))
                {
                    return(true);
                }
                else if (token.Parent.IsKind(SyntaxKind.NamespaceDeclaration))
                {
                    return(true);
                }
            }

            // delegate void D();
            // |

            if (token.Kind() == SyntaxKind.SemicolonToken)
            {
                if (token.Parent.IsKind(SyntaxKind.DelegateDeclaration) &&
                    !(token.Parent.GetParent() is TypeDeclarationSyntax))
                {
                    return(true);
                }
            }

            // [assembly: foo]
            // |

            if (token.Kind() == SyntaxKind.CloseBracketToken &&
                token.Parent.IsKind(SyntaxKind.AttributeList) &&
                token.Parent.IsParentKind(SyntaxKind.CompilationUnit))
            {
                return(true);
            }

            return(false);
        }
        private static ImmutableArray <ISymbol> GetSymbolsForNamespaceDeclarationNameContext(CSharpSyntaxContext context, CancellationToken cancellationToken)
        {
            var declarationSyntax = context.TargetToken.GetAncestor <NamespaceDeclarationSyntax>();

            if (declarationSyntax == null)
            {
                return(ImmutableArray <ISymbol> .Empty);
            }

            return(GetRecommendedNamespaceNameSymbols(context.SemanticModel, declarationSyntax, cancellationToken));
        }
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return
         (IsUnsafeStatementContext(context) ||
          IsMemberDeclarationContext(context, cancellationToken));
 }
        private static ImmutableArray <ISymbol> GetSymbolsOffOfBoundExpression(
            CSharpSyntaxContext context,
            ExpressionSyntax originalExpression,
            ExpressionSyntax expression,
            SymbolInfo leftHandBinding,
            INamespaceOrTypeSymbol container,
            CancellationToken cancellationToken)
        {
            var useBaseReferenceAccessibility = false;
            var excludeInstance = false;
            var excludeStatic   = false;
            var symbol          = leftHandBinding.GetBestOrAllSymbols().FirstOrDefault();

            if (symbol != null)
            {
                // If the thing on the left is a type, namespace or alias and the original
                // expression was parenthesized, we shouldn't show anything in IntelliSense.
                if (originalExpression.IsKind(SyntaxKind.ParenthesizedExpression) &&
                    symbol.MatchesKind(SymbolKind.NamedType,
                                       SymbolKind.Namespace,
                                       SymbolKind.Alias))
                {
                    return(ImmutableArray <ISymbol> .Empty);
                }

                // If the thing on the left is a lambda expression, we shouldn't show anything.
                if (symbol.Kind == SymbolKind.Method &&
                    ((IMethodSymbol)symbol).MethodKind == MethodKind.AnonymousFunction)
                {
                    return(ImmutableArray <ISymbol> .Empty);
                }

                // If the thing on the left is an event that can't be used as a field, we shouldn't show anything
                if (symbol.Kind == SymbolKind.Event &&
                    !context.SemanticModel.IsEventUsableAsField(originalExpression.SpanStart, (IEventSymbol)symbol))
                {
                    return(ImmutableArray <ISymbol> .Empty);
                }

                // If the thing on the left is a this parameter (e.g. this or base) and we're in a static context,
                // we shouldn't show anything
                if (symbol.IsThisParameter() &&
                    expression.IsInStaticContext())
                {
                    return(ImmutableArray <ISymbol> .Empty);
                }

                // What is the thing on the left?
                switch (symbol.Kind)
                {
                case SymbolKind.NamedType:
                case SymbolKind.Namespace:
                    excludeInstance = true;
                    container       = (INamespaceOrTypeSymbol)symbol;
                    break;

                case SymbolKind.Alias:
                    excludeInstance = true;
                    container       = ((IAliasSymbol)symbol).Target;
                    break;

                case SymbolKind.Parameter:
                    var parameter = (IParameterSymbol)symbol;

                    excludeStatic = true;

                    // case:
                    //    base.|
                    if (parameter.IsThis && !object.Equals(parameter.Type, container))
                    {
                        useBaseReferenceAccessibility = true;
                    }

                    break;

                default:
                    excludeStatic = true;
                    break;
                }
            }
            else if (container != null)
            {
                excludeStatic = true;
            }
            else
            {
                return(ImmutableArray <ISymbol> .Empty);
            }

            Debug.Assert(!excludeInstance || !excludeStatic);
            Debug.Assert(!excludeInstance || !useBaseReferenceAccessibility);

            // nameof(X.|
            // Show static and instance members.
            if (context.IsNameOfContext)
            {
                excludeInstance = false;
                excludeStatic   = false;
            }

            var position = originalExpression.SpanStart;

            var symbols = useBaseReferenceAccessibility
                ? context.SemanticModel.LookupBaseMembers(position)
                : excludeInstance
                    ? context.SemanticModel.LookupStaticMembers(position, container)
                    : SuppressDefaultTupleElements(container,
                                                   context.SemanticModel.LookupSymbols(position, container, includeReducedExtensionMethods: true));

            // If we're showing instance members, don't include nested types
            return(excludeStatic
                ? symbols.WhereAsArray(s => !s.IsStatic && !(s is ITypeSymbol))
                : symbols);
        }
 private static bool IsUnsafeStatementContext(CSharpSyntaxContext context)
 {
     return
         (context.TargetToken.IsUnsafeContext() &&
          context.IsStatementContext);
 }
 protected override bool IsValidContext(
     int position,
     CSharpSyntaxContext context,
     CancellationToken cancellationToken
     ) => context.IsPreProcessorKeywordContext;
Exemple #30
0
            internal async Task <IEnumerable <RecommendedKeyword> > RecommendKeywordsAsync(int position, CSharpSyntaxContext context)
            {
                var syntaxKind = await _recommender.RecommendKeywordAsync(position, context, CancellationToken.None).ConfigureAwait(false);

                if (syntaxKind.HasValue)
                {
                    var matchPriority = _recommender.ShouldPreselect(context, CancellationToken.None) ? SymbolMatchPriority.Keyword : MatchPriority.Default;
                    return(SpecializedCollections.SingletonEnumerable(
                               new RecommendedKeyword(SyntaxFacts.GetText(syntaxKind.Value), matchPriority: matchPriority)));
                }

                return(null);
            }
		static Task<IEnumerable<ISymbol>> GetPreselectedSymbolsWorker2 (CSharpSyntaxContext context, ITypeSymbol type, CancellationToken cancellationToken)
		{
			// Unwrap an array type fully.  We only want to offer the underlying element type in the
			// list of completion items.
			bool isArray = false;
			while (type is IArrayTypeSymbol) {
				isArray = true;
				type = ((IArrayTypeSymbol)type).ElementType;
			}

			if (type == null) {
				return Task.FromResult (Enumerable.Empty<ISymbol> ());
			}

			// Unwrap nullable
			if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) {
				type = type.GetTypeArguments ().FirstOrDefault ();
			}

			if (type.SpecialType == SpecialType.System_Void) {
				return Task.FromResult (Enumerable.Empty<ISymbol> ());
			}

			if (type.ContainsAnonymousType ()) {
				return Task.FromResult (Enumerable.Empty<ISymbol> ());
			}

			if (!type.CanBeReferencedByName) {
				return Task.FromResult (Enumerable.Empty<ISymbol> ());
			}

			// Normally the user can't say things like "new IList".  Except for "IList[] x = new |".
			// In this case we do want to allow them to preselect certain types in the completion
			// list even if they can't new them directly.
			if (!isArray) {
				if (type.TypeKind == TypeKind.Interface ||
				    type.TypeKind == TypeKind.Pointer ||
				    type.TypeKind == TypeKind.Dynamic ||
				    type.IsAbstract) {
					return Task.FromResult (Enumerable.Empty<ISymbol> ());
				}

				if (type.TypeKind == TypeKind.TypeParameter &&
				    !((ITypeParameterSymbol)type).HasConstructorConstraint) {
					return Task.FromResult (Enumerable.Empty<ISymbol> ());
				}
			}

//			if (!type.IsEditorBrowsable(options.GetOption(RecommendationOptions.HideAdvancedMembers, context.SemanticModel.Language), context.SemanticModel.Compilation))
//			{
//				return SpecializedTasks.EmptyEnumerable<ISymbol>();
//			}
//
			return Task.FromResult (SpecializedCollections.SingletonEnumerable ((ISymbol)type));
		}
Exemple #32
0
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 => context.SyntaxTree.IsValidContextForJoinClause(position, context.LeftToken);
        protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
        {
            var syntaxTree = context.SyntaxTree;

            return(syntaxTree.IsCatchOrFinallyContext(position, context.LeftToken, cancellationToken));
        }
 protected override Task <SyntaxContext> CreateSyntaxContextAsync(Document document, SemanticModel semanticModel, int position, CancellationToken cancellationToken)
 {
     return(Task.FromResult <SyntaxContext>(CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken)));
 }
        public static bool IsTypeDeclarationContext(
            this SyntaxTree syntaxTree,
            int position,
            CSharpSyntaxContext contextOpt,
            ISet<SyntaxKind> validModifiers,
            ISet<SyntaxKind> validTypeDeclarations,
            bool canBePartial,
            CancellationToken cancellationToken)
        {
            // We only allow nested types inside a class or struct, not inside a
            // an interface or enum.
            var typeDecl = contextOpt != null
                ? contextOpt.ContainingTypeDeclaration
                : syntaxTree.GetContainingTypeDeclaration(position, cancellationToken);

            validTypeDeclarations = validTypeDeclarations ?? SpecializedCollections.EmptySet<SyntaxKind>();

            if (typeDecl != null)
            {
                if (!validTypeDeclarations.Contains(typeDecl.Kind()))
                {
                    return false;
                }
            }

            // Check many of the simple cases first.
            var leftToken = contextOpt != null
                ? contextOpt.LeftToken
                : syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);

            if (syntaxTree.IsTypeDeclarationContext(position, leftToken, cancellationToken))
            {
                return true;
            }

            // If we're touching the right of an identifier, move back to
            // previous token.
            var token = contextOpt != null
                ? contextOpt.TargetToken
                : leftToken.GetPreviousTokenIfTouchingWord(position);

            // A type can also show up after certain types of modifiers
            if (canBePartial &&
                token.IsKindOrHasMatchingText(SyntaxKind.PartialKeyword))
            {
                return true;
            }

            // using static | is never a type declaration context
            if (token.IsStaticKeywordInUsingDirective())
            {
                return false;
            }

            var modifierTokens = contextOpt != null
                ? contextOpt.PrecedingModifiers
                : syntaxTree.GetPrecedingModifiers(position, leftToken, cancellationToken);

            if (!modifierTokens.Any())
            {
                return false;
            }

            validModifiers = validModifiers ?? SpecializedCollections.EmptySet<SyntaxKind>();

            if (modifierTokens.IsProperSubsetOf(validModifiers))
            {
                // the parent is the member
                // the grandparent is the container of the member
                var container = token.Parent.GetParent();
                if (container.IsKind(SyntaxKind.CompilationUnit) ||
                    container.IsKind(SyntaxKind.NamespaceDeclaration) ||
                    container.IsKind(SyntaxKind.ClassDeclaration) ||
                    container.IsKind(SyntaxKind.StructDeclaration))
                {
                    return true;
                }
            }

            return false;
        }
 protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken)
 {
     return(context.TargetToken.IsOrderByDirectionContext());
 }