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; }
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); }
private static bool IsUnsafeParameterTypeContext(CSharpSyntaxContext context) { return (context.TargetToken.IsUnsafeContext() && context.IsParameterTypeContext); }
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); }
protected override bool IsValidContext(int position, CSharpSyntaxContext context, CancellationToken cancellationToken) => context.SyntaxTree.IsParamsModifierContext(context.Position, context.LeftToken);
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); }
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; }
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)); }
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)); }
private bool IsAttributeArgumentContext(CSharpSyntaxContext context) { return (context.IsAnyExpressionContext && context.LeftToken.GetAncestor <AttributeSyntax>() != null); }
private static bool IsUnsafeDefaultExpressionContext(CSharpSyntaxContext context) { return (context.TargetToken.IsUnsafeContext() && context.SyntaxTree.IsDefaultExpressionContext(context.Position, context.LeftToken)); }
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;
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)); }
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()); }