protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) return Task.FromResult (Enumerable.Empty<CompletionData> ()); if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax; if (ma == null) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var model = ctx.CSharpSyntaxContext.SemanticModel; var symbolInfo = model.GetSymbolInfo (ma.Expression); if (symbolInfo.Symbol == null || symbolInfo.Symbol.Kind != SymbolKind.Parameter) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var list = new List<CompletionData> (); var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); var addedSymbols = new HashSet<string> (); foreach (var ano in ma.AncestorsAndSelf ().OfType<AnonymousMethodExpressionSyntax> ()) { Analyze (engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken); } foreach (var ano in ma.AncestorsAndSelf ().OfType<ParenthesizedLambdaExpressionSyntax> ()) { Analyze (engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken); } return Task.FromResult ((IEnumerable<CompletionData>)list); }
protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; var model = ctx.SemanticModel; if (tree.IsInNonUserCode (position, cancellationToken)) return Task.FromResult (Enumerable.Empty<CompletionData> ()); if (!ctx.CSharpSyntaxContext.IsAnyExpressionContext) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var enclosingType = model.GetEnclosingNamedType (position, cancellationToken); var memberMethods = enclosingType.GetMembers ().OfType<IMethodSymbol> ().Where (m => m.MethodKind == MethodKind.Ordinary).ToArray (); var list = new List<CompletionData> (); foreach (var type in ctx.InferredTypes) { if (type.TypeKind != TypeKind.Delegate) continue; AddCompatibleMethods (engine, list, type, memberMethods, cancellationToken); string delegateName = null; if (ctx.TargetToken.IsKind (SyntaxKind.PlusEqualsToken)) { delegateName = GuessEventHandlerBaseName (ctx.LeftToken.Parent, ctx.ContainingTypeDeclaration); } AddDelegateHandlers (list, ctx.TargetToken.Parent, model, engine, result, type, position, delegateName, cancellationToken); } if (list.Count > 0) { result.AutoSelect = false; } return Task.FromResult ((IEnumerable<CompletionData>)list); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(position, cancellationToken)) return Enumerable.Empty<CompletionData> (); var targetToken = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position); if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective)) { var compilation = await document.GetCSharpCompilationAsync(cancellationToken).ConfigureAwait(false); var aliases = compilation.ExternalReferences.Where(r => r.Properties.Aliases != null).SelectMany(r => r.Properties.Aliases).ToSet(); if (aliases.Any()) { var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); var usedAliases = root.ChildNodes().OfType<ExternAliasDirectiveSyntax>().Where(e => !e.Identifier.IsMissing).Select(e => e.Identifier.ValueText); foreach (var used in usedAliases) { aliases.Remove (used); } aliases.Remove(MetadataReferenceProperties.GlobalAlias); return aliases.Select (e => engine.Factory.CreateGenericData (this, e, GenericDataType.Undefined)); } } return Enumerable.Empty<CompletionData> (); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var span = new TextSpan(position, 0); var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false); var syntaxTree = semanticModel.SyntaxTree; // var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false); if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return Enumerable.Empty<CompletionData> (); } if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) { return Enumerable.Empty<CompletionData> (); } var node = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken) .GetPreviousTokenIfTouchingWord(position) .Parent; if (node.Kind() == SyntaxKind.ExplicitInterfaceSpecifier) { return await GetCompletionsOffOfExplicitInterfaceAsync( engine, document, semanticModel, position, ((ExplicitInterfaceSpecifierSyntax)node).Name, cancellationToken).ConfigureAwait(false); } return Enumerable.Empty<CompletionData> (); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var semanticModel = ctx.SemanticModel; if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument)) { SourceText text; if (!completionContext.Document.TryGetText (out text)) { text = await completionContext.Document.GetTextAsync (); } var currentChar = text [completionContext.Position - 1]; if (ctx.TargetToken.Parent == null || !ctx.TargetToken.Parent.IsKind(SyntaxKind.StringLiteralExpression) || ctx.TargetToken.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument) || ctx.TargetToken.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.IsKind(SyntaxKind.ArgumentList) || ctx.TargetToken.Parent.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.Parent.IsKind(SyntaxKind.InvocationExpression)) { return Enumerable.Empty<CompletionData> (); } var formatArgument = GetFormatItemNumber(document, position); var invocationExpression = ctx.TargetToken.Parent.Parent.Parent.Parent as InvocationExpressionSyntax; return GetFormatCompletionData(engine, semanticModel, invocationExpression, formatArgument, currentChar); } return Enumerable.Empty<CompletionData> (); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode (completionContext.Position, cancellationToken)) return Enumerable.Empty<CompletionData> (); var token = tree.FindTokenOnLeftOfPosition (completionContext.Position, cancellationToken); if (token.IsMandatoryNamedParameterPosition ()) return Enumerable.Empty<CompletionData> (); var result = new List<CompletionData> (); // check if it's the first parameter and set autoselect == false if a parameterless version exists. if (token.IsKind (SyntaxKind.OpenParenToken)) { var parent = token.Parent?.Parent; if (parent == null) return Enumerable.Empty<CompletionData> (); var symbolInfo = model.GetSymbolInfo (parent); foreach (var symbol in new [] { symbolInfo.Symbol }.Concat (symbolInfo.CandidateSymbols)) { if (symbol != null && symbol.IsKind (SymbolKind.Method)) { if (symbol.GetParameters ().Length == 0) { completionResult.AutoSelect = false; break; } } } } foreach (var _type in ctx.InferredTypes) { var type = _type; if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments ().FirstOrDefault (); if (type == null) continue; } if (type.TypeKind != TypeKind.Enum) continue; if (!type.IsEditorBrowsable ()) continue; // Does type have any aliases? ISymbol alias = await type.FindApplicableAlias (completionContext.Position, model, cancellationToken).ConfigureAwait (false); var displayString = RoslynCompletionData.SafeMinimalDisplayString (type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat); if (string.IsNullOrEmpty (completionResult.DefaultCompletionString)) { completionResult.DefaultCompletionString = displayString; completionResult.AutoCompleteEmptyMatch = true; } if (!IsReachable (model, type, token.Parent)) result.Add (engine.Factory.CreateSymbolCompletionData (this, type, displayString)); foreach (IFieldSymbol field in type.GetMembers ().OfType<IFieldSymbol> ()) { if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) { result.Add (engine.Factory.CreateEnumMemberCompletionData (this, alias, field)); } } } return result; }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; //DeclarationModifiers modifiers; SyntaxToken token; var semanticModel = ctx.SemanticModel; var enclosingSymbol = semanticModel.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol; // Only inside classes and structs if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class)) { return Enumerable.Empty<CompletionData> (); } if (!IsPartialCompletionContext (tree, position, cancellationToken/*, out modifiers*/, out token)) { if (enclosingSymbol != null && (token.IsKind (SyntaxKind.OpenBraceToken) || token.IsKind (SyntaxKind.CloseBraceToken) || token.IsKind (SyntaxKind.SemicolonToken))) { return CreateCompletionData (engine, semanticModel, position, enclosingSymbol, token, false, cancellationToken); } return Enumerable.Empty<CompletionData> (); } return CreateCompletionData (engine, semanticModel, position, enclosingSymbol, token, true, cancellationToken); }
public override async Task<bool> IsExclusiveAsync (CompletionContext completionContext, SyntaxContext syntaxContext, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { // We're exclusive if this context could only be an object initializer and not also a // collection initializer. If we're initializing something that could be initialized as // an object or as a collection, say we're not exclusive. That way the rest of // intellisense can be used in the collection intitializer. // // Consider this case: // class c : IEnumerable<int> // { // public void Add(int addend) { } // public int foo; // } // void foo() // { // var b = new c {| // } // There we could initialize b using either an object initializer or a collection // initializer. Since we don't know which the user will use, we'll be non-exclusive, so // the other providers can help the user write the collection initializer, if they want // to. var document = completionContext.Document; var position = completionContext.Position; var tree = await document.GetCSharpSyntaxTreeAsync (cancellationToken).ConfigureAwait (false); if (tree.IsInNonUserCode (position, cancellationToken)) { return false; } var token = tree.FindTokenOnLeftOfPosition (position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord (position); if (token.Parent == null) { return false; } var expression = token.Parent.Parent as ExpressionSyntax; if (expression == null) { return false; } var semanticModel = await document.GetCSharpSemanticModelForNodeAsync (expression, cancellationToken).ConfigureAwait (false); var initializedType = semanticModel.GetTypeInfo (expression, cancellationToken).Type; if (initializedType == null) { return false; } // Non-exclusive if initializedType can be initialized as a collection. if (initializedType.CanSupportCollectionInitializer ()) { return false; } // By default, only our member names will show up. return true; }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; return await document.GetUnionResultsFromDocumentAndLinks( UnionCompletionItemComparer.Instance, async (doc, ct) => await GetSpeculativeTCompletions(engine, doc, position, ct).ConfigureAwait(false), cancellationToken).ConfigureAwait(false); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken) || syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken) is EnumDeclarationSyntax) { return Enumerable.Empty<CompletionData>(); } // var span = new TextSpan(position, 0); // var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false); if (syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { var directive = syntaxTree.GetRoot(cancellationToken).FindTokenOnLeftOfPosition(position, includeDirectives: true).GetAncestor<DirectiveTriviaSyntax>(); if (directive.DirectiveNameToken.IsKind( SyntaxKind.IfKeyword, SyntaxKind.RegionKeyword, SyntaxKind.ElseKeyword, SyntaxKind.ElifKeyword, SyntaxKind.ErrorKeyword, SyntaxKind.LineKeyword, SyntaxKind.PragmaKeyword, SyntaxKind.EndIfKeyword, SyntaxKind.UndefKeyword, SyntaxKind.EndRegionKeyword, SyntaxKind.WarningKeyword)) { return Enumerable.Empty<CompletionData>(); } return await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false); } var tokenLeftOfPosition = syntaxTree.FindTokenOnLeftOfPosition (position, cancellationToken); if (syntaxTree.IsGlobalStatementContext(position, cancellationToken) || syntaxTree.IsExpressionContext(position, tokenLeftOfPosition, true, cancellationToken) || syntaxTree.IsStatementContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsTypeContext(position, cancellationToken) || syntaxTree.IsTypeDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsNamespaceContext(position, cancellationToken) || syntaxTree.IsMemberDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsLabelContext(position, cancellationToken)) { return await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false); } return Enumerable.Empty<CompletionData>(); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var result = new List<CompletionData> (); if (ctx.IsPreProcessorExpressionContext) { var parseOptions = model.SyntaxTree.Options as CSharpParseOptions; foreach (var define in parseOptions.PreprocessorSymbolNames) { result.Add(engine.Factory.CreateGenericData (this, define, GenericDataType.PreprocessorSymbol)); } } return result; }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { // var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false); var document = completionContext.Document; var semanticModel = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) return Enumerable.Empty<CompletionData> (); var text = await document.GetTextAsync (cancellationToken).ConfigureAwait (false); var startLineNumber = text.Lines.IndexOf (completionContext.Position); // modifiers* override modifiers* type? | Accessibility seenAccessibility; //DeclarationModifiers modifiers; var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.Parent == null) return Enumerable.Empty<CompletionData> (); var parentMember = token.Parent.AncestorsAndSelf ().OfType<MemberDeclarationSyntax> ().FirstOrDefault (m => !m.IsKind (SyntaxKind.IncompleteMember)); if (!(parentMember is BaseTypeDeclarationSyntax) && /* May happen in case: * * override $ * public override string Foo () {} */ !(token.IsKind (SyntaxKind.OverrideKeyword) && token.Span.Start <= parentMember.Span.Start)) return Enumerable.Empty<CompletionData> (); var position = completionContext.Position; var startToken = token.GetPreviousTokenIfTouchingWord(position); ITypeSymbol returnType; SyntaxToken tokenBeforeReturnType; TryDetermineReturnType (startToken, semanticModel, cancellationToken, out returnType, out tokenBeforeReturnType); if (returnType == null) { var enclosingType = semanticModel.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol; if (enclosingType != null && (startToken.IsKind (SyntaxKind.OpenBraceToken) || startToken.IsKind (SyntaxKind.CloseBraceToken) || startToken.IsKind (SyntaxKind.SemicolonToken))) { return CreateCompletionData (engine, semanticModel, position, returnType, Accessibility.NotApplicable, startToken, tokenBeforeReturnType, false, cancellationToken); } } if (!TryDetermineModifiers(ref tokenBeforeReturnType, text, startLineNumber, out seenAccessibility/*, out modifiers*/) || !TryCheckForTrailingTokens (tree, text, startLineNumber, position, cancellationToken)) { return Enumerable.Empty<CompletionData> (); } return CreateCompletionData (engine, semanticModel, position, returnType, seenAccessibility, startToken, tokenBeforeReturnType, true, cancellationToken); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return null; } var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord(position); if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.CommaToken) { return null; } var attributeArgumentList = token.Parent as AttributeArgumentListSyntax; var attributeSyntax = token.Parent.Parent as AttributeSyntax; if (attributeSyntax == null || attributeArgumentList == null) { return null; } // We actually want to collect two sets of named parameters to present the user. The // normal named parameters that come from the attribute constructors. These will be // presented like "foo:". And also the named parameters that come from the writable // fields/properties in the attribute. These will be presented like "bar =". var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position); var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false); var nameColonItems = await GetNameColonItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); var nameEqualsItems = await GetNameEqualsItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); // If we're after a name= parameter, then we only want to show name= parameters. if (IsAfterNameEqualsArgument(token)) { return nameEqualsItems; } return nameColonItems.Concat(nameEqualsItems); }
protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var semanticModel = ctx.SemanticModel; if (info.TriggerCharacter == '\\') { if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind (SyntaxKind.Argument)) { var argument = ctx.TargetToken.Parent.Parent as ArgumentSyntax; var symbolInfo = semanticModel.GetSymbolInfo (ctx.TargetToken.Parent.Parent.Parent.Parent); if (symbolInfo.Symbol == null) return TaskUtil.EmptyEnumerable<CompletionData> (); if (SemanticHighlightingVisitor<int>.IsRegexMatchMethod (symbolInfo)) { if (((ArgumentListSyntax)argument.Parent).Arguments [1] != argument) return TaskUtil.EmptyEnumerable<CompletionData> (); completionResult.AutoSelect = false; return Task.FromResult (GetFormatCompletionData (engine, argument.Expression.ToString () [0] == '@')); } if (SemanticHighlightingVisitor<int>.IsRegexConstructor (symbolInfo)) { if (((ArgumentListSyntax)argument.Parent).Arguments [0] != argument) return TaskUtil.EmptyEnumerable<CompletionData> (); completionResult.AutoSelect = false; return Task.FromResult (GetFormatCompletionData (engine, argument.Expression.ToString () [0] == '@')); } } } else { var ma = ctx.TargetToken.Parent as MemberAccessExpressionSyntax; if (ma != null) { var symbolInfo = semanticModel.GetSymbolInfo (ma.Expression); var typeInfo = semanticModel.GetTypeInfo (ma.Expression); var type = typeInfo.Type; if (type != null && type.Name == "Match" && type.ContainingNamespace.GetFullName () == "System.Text.RegularExpressions" ) { var items = new List<CompletionData>(); foreach (var grp in GetGroups (ctx, symbolInfo.Symbol)) { items.Add (engine.Factory.CreateGenericData (this, "Groups[\"" + grp + "\"]", GenericDataType.Undefined)); } return Task.FromResult ((IEnumerable<CompletionData>)items); } } } return TaskUtil.EmptyEnumerable<CompletionData> (); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var list = new List<CompletionData> (); var newExpression = GetObjectCreationNewExpression (ctx.SyntaxTree, completionContext.Position, cancellationToken); if (newExpression == null) { if (ctx.SyntaxTree.IsInNonUserCode(completionContext.Position, cancellationToken) || ctx.SyntaxTree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken)) return Enumerable.Empty<CompletionData> (); // if (!nkr.IsValid (completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken)) // return Enumerable.Empty<ICompletionData> (); var tokenOnLeftOfPosition = ctx.SyntaxTree.FindTokenOnLeftOfPosition (completionContext.Position, cancellationToken); if (!tokenOnLeftOfPosition.IsKind (SyntaxKind.EqualsToken) && !tokenOnLeftOfPosition.Parent.IsKind (SyntaxKind.EqualsValueClause)) return Enumerable.Empty<CompletionData> (); foreach (var inferredType in SyntaxContext.InferenceService.InferTypes (ctx.CSharpSyntaxContext.SemanticModel, completionContext.Position, cancellationToken)) { if (inferredType.IsEnumType () || inferredType.IsInterfaceType () || inferredType.IsAbstract) continue; foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, inferredType, completionContext.Position - 1, cancellationToken)) { var symbolCompletionData = engine.Factory.CreateObjectCreation (this, inferredType, symbol, completionContext.Position, false); list.Add (symbolCompletionData); } } return list; } var type = SyntaxContext.InferenceService.InferType (ctx.CSharpSyntaxContext.SemanticModel, newExpression, objectAsDefault: false, cancellationToken: cancellationToken); foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, type, completionContext.Position, cancellationToken)) { var symbolCompletionData = engine.Factory.CreateObjectCreation (this, type, symbol, newExpression.SpanStart, true); list.Add (symbolCompletionData); if (string.IsNullOrEmpty (result.DefaultCompletionString)) result.DefaultCompletionString = symbolCompletionData.DisplayText; } foreach (var keyword in primitiveTypesKeywords) { list.Add (engine.Factory.CreateGenericData (this, keyword, GenericDataType.Keyword)); } return list; }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) return Enumerable.Empty<CompletionData> (); if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) return Enumerable.Empty<CompletionData> (); var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax; if (ma == null) return Enumerable.Empty<CompletionData> (); var model = ctx.CSharpSyntaxContext.SemanticModel; var symbolInfo = model.GetSymbolInfo (ma.Expression); if (symbolInfo.Symbol == null) return Enumerable.Empty<CompletionData> (); var list = new List<CompletionData> (); var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); var addedSymbols = new HashSet<string> (); foreach (var ifStmSyntax in ma.Expression.AncestorsAndSelf ().OfType<IfStatementSyntax> ()) { var condition = ifStmSyntax.Condition.SkipParens (); if (condition == null || !condition.IsKind (SyntaxKind.IsExpression)) continue; var isExpr = ((BinaryExpressionSyntax)condition); var leftSymbol = model.GetSymbolInfo (isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo (isExpr.Right).Type; if (type != null) { Analyze (engine, ma.Expression, type, within, list, addedSymbols, cancellationToken); } } } return list; }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) return Enumerable.Empty<CompletionData> (); var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.IsMandatoryNamedParameterPosition()) return Enumerable.Empty<CompletionData> (); var result = new List<CompletionData> (); foreach (var _type in ctx.InferredTypes) { var type = _type; if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments().FirstOrDefault(); if (type == null) continue; } if (type.TypeKind != TypeKind.Enum) continue; if (!type.IsEditorBrowsable ()) continue; // Does type have any aliases? ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(completionResult.DefaultCompletionString)) completionResult.DefaultCompletionString = type.Name; result.Add (engine.Factory.CreateSymbolCompletionData(this, type, RoslynCompletionData.SafeMinimalDisplayString (type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat))); foreach (IFieldSymbol field in type.GetMembers().OfType<IFieldSymbol>()) { if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) { result.Add (engine.Factory.CreateEnumMemberCompletionData(this, alias, field)); } } } return result; }
public override async Task<bool> IsExclusiveAsync (CompletionContext completionContext, SyntaxContext ctx, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; //DeclarationModifiers modifiers; SyntaxToken token; var semanticModel = ctx.SemanticModel; var enclosingSymbol = semanticModel.GetEnclosingSymbol (position, cancellationToken) as INamedTypeSymbol; // Only inside classes and structs if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class)) { return false; } if (!IsPartialCompletionContext (tree, position, cancellationToken/*, out modifiers*/, out token)) { return false; } return true; }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var list = new List <CompletionData> (); var newExpression = GetObjectCreationNewExpression(ctx.SyntaxTree, completionContext.Position, cancellationToken); if (newExpression == null) { if (ctx.SyntaxTree.IsInNonUserCode(completionContext.Position, cancellationToken) || ctx.SyntaxTree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } // if (!nkr.IsValid (completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken)) // return Enumerable.Empty<ICompletionData> (); var tokenOnLeftOfPosition = ctx.SyntaxTree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (!tokenOnLeftOfPosition.IsKind(SyntaxKind.EqualsToken) && !tokenOnLeftOfPosition.Parent.IsKind(SyntaxKind.EqualsValueClause)) { return(Enumerable.Empty <CompletionData> ()); } foreach (var inferredType in SyntaxContext.InferenceService.InferTypes(ctx.CSharpSyntaxContext.SemanticModel, completionContext.Position, cancellationToken)) { if (inferredType.IsEnumType() || inferredType.IsInterfaceType() || inferredType.IsAbstract) { continue; } foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, inferredType, completionContext.Position - 1, cancellationToken)) { var symbolCompletionData = engine.Factory.CreateObjectCreation(this, inferredType, symbol, completionContext.Position, false); list.Add(symbolCompletionData); } } return(list); } var expr = newExpression; var assignmentParent = expr.Parent as AssignmentExpressionSyntax; // HACK: Work around for a little bug in InferTypes see #41388 - may be obsolete in future roslyn versions. (after 1.2) bool skipInference = false; if (assignmentParent?.Left == expr) { skipInference = true; } if (!skipInference) { var type = SyntaxContext.InferenceService.InferType(ctx.CSharpSyntaxContext.SemanticModel, expr, objectAsDefault: false, cancellationToken: cancellationToken); foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, type, completionContext.Position, cancellationToken)) { var symbolCompletionData = engine.Factory.CreateObjectCreation(this, type, symbol, newExpression.SpanStart, true); list.Add(symbolCompletionData); if (string.IsNullOrEmpty(result.DefaultCompletionString)) { result.DefaultCompletionString = symbolCompletionData.DisplayText; result.AutoCompleteEmptyMatch = true; } } } for (int i = 0; i < primitiveTypesKeywords.Length; i++) { var keyword = primitiveTypesKeywords [i]; list.Add(engine.Factory.CreateKeywordCompletion(this, keyword)); } return(list); }
public async Task <CompletionResult> GetCompletionDataAsync(CompletionContext completionContext, CompletionTriggerInfo info, CancellationToken cancellationToken = default(CancellationToken)) { if (completionContext == null) { throw new ArgumentNullException("completionContext"); } var document = completionContext.Document; var semanticModel = await completionContext.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var position = completionContext.Position; var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var ctx = await completionContext.GetSyntaxContextAsync(workspace, cancellationToken); ctx.SemanticModel = semanticModel; // case lambda parameter (n1, $ if (ctx.TargetToken.IsKind(SyntaxKind.CommaToken) && ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.ParenthesizedLambdaExpression)) { return(CompletionResult.Empty); } var result = new CompletionResult { SyntaxContext = ctx }; if (position > 0) { var nonExclusiveHandlers = new List <CompletionContextHandler> (); var exclusiveHandlers = new List <CompletionContextHandler> (); var toRetriggerHandlers = new List <CompletionContextHandler> (); IEnumerable <CompletionContextHandler> handlerList; if (completionContext.UseDefaultContextHandlers) { handlerList = handlers.Concat(completionContext.AdditionalContextHandlers); } else { handlerList = completionContext.AdditionalContextHandlers; } foreach (var handler in handlerList) { if (info.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand || info.CompletionTriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand || handler.IsTriggerCharacter(text, position - 1)) { if (await handler.IsExclusiveAsync(completionContext, ctx, info, cancellationToken)) { exclusiveHandlers.Add(handler); } else { nonExclusiveHandlers.Add(handler); } } else { toRetriggerHandlers.Add(handler); } } foreach (var handler in exclusiveHandlers) { var handlerResult = await handler.GetCompletionDataAsync(result, this, completionContext, info, ctx, cancellationToken); //if (handlerResult != null) { // Console.WriteLine ("-----" + handler); // foreach (var item in handlerResult) { // Console.WriteLine (item.DisplayText); // } //} else { // Console.WriteLine ("-----" + handler + " == NULL"); //} if (handlerResult != null) { result.AddRange(handlerResult); } } if (result.Count == 0) { foreach (var handler in nonExclusiveHandlers) { var handlerResult = await handler.GetCompletionDataAsync(result, this, completionContext, info, ctx, cancellationToken); //if (handlerResult != null) { // Console.WriteLine ("-----" + handler); // foreach (var item in handlerResult) { // Console.WriteLine (item.DisplayText); // } //} else { // Console.WriteLine ("-----" + handler + " == NULL"); //} if (handlerResult != null && handlerResult.Any()) { result.AddRange(handlerResult); } else { toRetriggerHandlers.Add(handler); } } if (result.Count > 0) { info = info.WithCompletionTriggerReason(CompletionTriggerReason.RetriggerCommand); foreach (var handler in toRetriggerHandlers) { var handlerResult = await handler.GetCompletionDataAsync(result, this, completionContext, info, ctx, cancellationToken); if (handlerResult != null) { result.AddRange(handlerResult); } } } } } // prevent auto selection for "<number>." case if (ctx.TargetToken.IsKind(SyntaxKind.DotToken)) { var accessExpr = ctx.TargetToken.Parent as MemberAccessExpressionSyntax; if (accessExpr != null && accessExpr.Expression != null && accessExpr.Expression.IsKind(SyntaxKind.NumericLiteralExpression)) { result.AutoSelect = false; } } if (ctx.LeftToken.Parent != null && ctx.LeftToken.Parent.Parent != null && ctx.TargetToken.Parent != null && !ctx.TargetToken.Parent.IsKind(SyntaxKind.NameEquals) && ctx.LeftToken.Parent.Parent.IsKind(SyntaxKind.AnonymousObjectMemberDeclarator)) { result.AutoSelect = false; } if (ctx.TargetToken.IsKind(SyntaxKind.OpenParenToken) && ctx.TargetToken.GetPreviousToken().IsKind(SyntaxKind.OpenParenToken)) { var validTypes = TypeGuessing.GetValidTypes(semanticModel, ctx.TargetToken.Parent, cancellationToken); result.AutoSelect = !validTypes.Any(t => t.IsDelegateType()); } foreach (var type in ctx.InferredTypes) { if (type.TypeKind == TypeKind.Delegate) { result.AutoSelect = false; break; } } if (ctx.CSharpSyntaxContext.IsPossibleTupleContext) { result.AutoSelect = false; } return(result); }
protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; //DeclarationModifiers modifiers; SyntaxToken token; var semanticModel = ctx.SemanticModel; var enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol; // Only inside classes and structs if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } if (!IsPartialCompletionContext(tree, position, cancellationToken /*, out modifiers*/, out token)) { if (enclosingSymbol != null && (token.IsKind(SyntaxKind.OpenBraceToken) || token.IsKind(SyntaxKind.CloseBraceToken) || token.IsKind(SyntaxKind.SemicolonToken))) { return(Task.FromResult(CreateCompletionData(engine, semanticModel, position, enclosingSymbol, token, false, cancellationToken))); } return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } return(Task.FromResult(CreateCompletionData(engine, semanticModel, position, enclosingSymbol, token, true, cancellationToken))); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var result = new List <CompletionData> (); if (ctx.IsPreProcessorExpressionContext) { var parseOptions = model.SyntaxTree.Options as CSharpParseOptions; foreach (var define in parseOptions.PreprocessorSymbolNames) { result.Add(engine.Factory.CreateGenericData(this, define, GenericDataType.PreprocessorSymbol)); } } return(result); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false); var typeAndLocation = GetInitializedType(document, semanticModel, position, cancellationToken); if (typeAndLocation == null) { return(Enumerable.Empty <CompletionData> ()); } var initializedType = typeAndLocation.Item1 as INamedTypeSymbol; var initializerLocation = typeAndLocation.Item2; if (initializedType == null) { return(Enumerable.Empty <CompletionData> ()); } // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members. IEnumerable <ISymbol> members = semanticModel.LookupSymbols(position, initializedType); members = members.Where(m => IsInitializable(m, initializedType) && m.CanBeReferencedByName && IsLegalFieldOrProperty(m) && !m.IsImplicitlyDeclared); // Filter out those members that have already been typed var alreadyTypedMembers = GetInitializedMembers(semanticModel.SyntaxTree, position, cancellationToken); var uninitializedMembers = members.Where(m => !alreadyTypedMembers.Contains(m.Name)); uninitializedMembers = uninitializedMembers.Where(m => m.IsEditorBrowsable()); // var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); // var changes = GetTextChangeSpan(text, position); var list = new List <CompletionData> (); // Return the members foreach (var member in uninitializedMembers) { list.Add(engine.Factory.CreateSymbolCompletionData(this, member)); } return(list); }
protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; if (ctx.CSharpSyntaxContext.IsInNonUserCode) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } if (ctx.TargetToken.IsKind(SyntaxKind.OverrideKeyword)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } if (info.CompletionTriggerReason == CompletionTriggerReason.CharTyped && info.TriggerCharacter == ' ') { if (!ctx.CSharpSyntaxContext.IsEnumBaseListContext && !ctx.LeftToken.IsKind(SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind(SyntaxKind.EqualsEqualsToken)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } // completionResult.AutoCompleteEmptyMatch = false; } var result = new List <CompletionData> (); foreach (var r in recommender) { var recommended = r.RecommendKeywords(completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken); if (recommended == null) { continue; } foreach (var kw in recommended) { result.Add(engine.Factory.CreateKeywordCompletion(this, kw.Keyword, kw.Kind)); } } // if (ctx.IsPreProcessorKeywordContext) { // foreach (var kw in preprocessorKeywords) // result.Add(factory.CreateGenericData (this, kw, GenericDataType.PreprocessorKeyword)); // } // // if (parent.IsKind(SyntaxKind.TypeParameterConstraintClause)) { // result.Add(factory.CreateGenericData (this, "new()", GenericDataType.PreprocessorKeyword)); // } return(Task.FromResult((IEnumerable <CompletionData>)result)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { if (info.IsDebugger) { return(null); } if (info.CompletionTriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand) { return(null); } var document = completionContext.Document; var position = completionContext.Position; var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken); var parentTrivia = token.GetAncestor <DocumentationCommentTriviaSyntax>(); if (parentTrivia == null) { return(null); } var items = new List <CompletionData>(); var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var span = GetTextChangeSpan(text, position); var attachedToken = parentTrivia.ParentTrivia.Token; if (attachedToken.Kind() == SyntaxKind.None) { return(null); } var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attachedToken.Parent, cancellationToken).ConfigureAwait(false); ISymbol declaredSymbol = null; var memberDeclaration = attachedToken.GetAncestor <MemberDeclarationSyntax>(); if (memberDeclaration != null) { declaredSymbol = semanticModel.GetDeclaredSymbol(memberDeclaration, cancellationToken); } else { var typeDeclaration = attachedToken.GetAncestor <TypeDeclarationSyntax>(); if (typeDeclaration != null) { declaredSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken); } } if (declaredSymbol != null) { items.AddRange(GetTagsForSymbol(engine, declaredSymbol, span, parentTrivia, token)); } if (token.Parent.Kind() == SyntaxKind.XmlEmptyElement || token.Parent.Kind() == SyntaxKind.XmlText || (token.Parent.IsKind(SyntaxKind.XmlElementEndTag) && token.IsKind(SyntaxKind.GreaterThanToken)) || (token.Parent.IsKind(SyntaxKind.XmlName) && token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement))) { if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement) { items.AddRange(GetNestedTags(engine, span)); } if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "list") { items.AddRange(GetListItems(engine, span)); } if (token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement) & token.Parent.Parent.IsParentKind(SyntaxKind.XmlElement)) { var element = (XmlElementSyntax)token.Parent.Parent.Parent; if (element.StartTag.Name.LocalName.ValueText == "list") { items.AddRange(GetListItems(engine, span)); } } if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "listheader") { items.AddRange(GetListHeaderItems(engine, span)); } if (token.Parent.Parent is DocumentationCommentTriviaSyntax) { items.AddRange(GetTopLevelSingleUseNames(engine, parentTrivia, span)); items.AddRange(GetTopLevelRepeatableItems(engine, span)); } } if (token.Parent.Kind() == SyntaxKind.XmlElementStartTag) { var startTag = (XmlElementStartTagSyntax)token.Parent; if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "list") { items.AddRange(GetListItems(engine, span)); } if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "listheader") { items.AddRange(GetListHeaderItems(engine, span)); } } items.AddRange(GetAlwaysVisibleItems(engine, span)); return(items); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; return(await document.GetUnionResultsFromDocumentAndLinks( UnionCompletionItemComparer.Instance, async (doc, ct) => await GetSpeculativeTCompletions(engine, doc, position, ct).ConfigureAwait(false), cancellationToken).ConfigureAwait(false)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return(null); } var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord(position); if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.OpenBracketToken && token.Kind() != SyntaxKind.CommaToken) { return(null); } var argumentList = token.Parent as BaseArgumentListSyntax; if (argumentList == null) { return(null); } var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(argumentList, cancellationToken).ConfigureAwait(false); var parameterLists = GetParameterLists(semanticModel, position, argumentList.Parent, cancellationToken); if (parameterLists == null) { return(null); } var existingNamedParameters = GetExistingNamedParameters(argumentList, position); parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters)); var unspecifiedParameters = parameterLists.SelectMany(pl => pl) .Where(p => !existingNamedParameters.Contains(p.Name)) .Distinct(this); // var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); return(unspecifiedParameters .Select(p => engine.Factory.CreateGenericData(this, p.Name + ":", GenericDataType.NamedParameter))); }
protected async Task<bool> IsExclusiveAsync(Document document, int caretPosition, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = syntaxTree.FindTokenOnLeftOfPosition(caretPosition, cancellationToken) .GetPreviousTokenIfTouchingWord(caretPosition); return IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { if (info.IsDebugger) { return null; } var document = completionContext.Document; var position = completionContext.Position; var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken); var parentTrivia = token.GetAncestor<DocumentationCommentTriviaSyntax>(); if (parentTrivia == null) { return null; } var items = new List<CompletionData>(); var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var span = GetTextChangeSpan(text, position); var attachedToken = parentTrivia.ParentTrivia.Token; if (attachedToken.Kind() == SyntaxKind.None) { return null; } var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attachedToken.Parent, cancellationToken).ConfigureAwait(false); ISymbol declaredSymbol = null; var memberDeclaration = attachedToken.GetAncestor<MemberDeclarationSyntax>(); if (memberDeclaration != null) { declaredSymbol = semanticModel.GetDeclaredSymbol(memberDeclaration, cancellationToken); } else { var typeDeclaration = attachedToken.GetAncestor<TypeDeclarationSyntax>(); if (typeDeclaration != null) { declaredSymbol = semanticModel.GetDeclaredSymbol(typeDeclaration, cancellationToken); } } if (declaredSymbol != null) { items.AddRange(GetTagsForSymbol(engine, declaredSymbol, span, parentTrivia, token)); } if (token.Parent.Kind() == SyntaxKind.XmlEmptyElement || token.Parent.Kind() == SyntaxKind.XmlText || (token.Parent.IsKind(SyntaxKind.XmlElementEndTag) && token.IsKind(SyntaxKind.GreaterThanToken)) || (token.Parent.IsKind(SyntaxKind.XmlName) && token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement))) { if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement) { items.AddRange(GetNestedTags(engine, span)); } if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "list") { items.AddRange(GetListItems(engine, span)); } if (token.Parent.IsParentKind(SyntaxKind.XmlEmptyElement) & token.Parent.Parent.IsParentKind(SyntaxKind.XmlElement)) { var element = (XmlElementSyntax)token.Parent.Parent.Parent; if (element.StartTag.Name.LocalName.ValueText == "list") { items.AddRange(GetListItems(engine, span)); } } if (token.Parent.Parent.Kind() == SyntaxKind.XmlElement && ((XmlElementSyntax)token.Parent.Parent).StartTag.Name.LocalName.ValueText == "listheader") { items.AddRange(GetListHeaderItems(engine, span)); } if (token.Parent.Parent is DocumentationCommentTriviaSyntax) { items.AddRange(GetTopLevelSingleUseNames(engine, parentTrivia, span)); items.AddRange(GetTopLevelRepeatableItems(engine, span)); } } if (token.Parent.Kind() == SyntaxKind.XmlElementStartTag) { var startTag = (XmlElementStartTagSyntax)token.Parent; if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "list") { items.AddRange(GetListItems(engine, span)); } if (token == startTag.GreaterThanToken && startTag.Name.LocalName.ValueText == "listheader") { items.AddRange(GetListHeaderItems(engine, span)); } } items.AddRange(GetAlwaysVisibleItems(engine, span)); return items; }
public override async Task<bool> IsExclusiveAsync(CompletionContext completionContext, SyntaxContext syntaxContext, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var syntaxTree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = syntaxTree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken) .GetPreviousTokenIfTouchingWord(completionContext.Position); return IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token); }
protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax; if (ma == null) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var model = ctx.CSharpSyntaxContext.SemanticModel; var symbolInfo = model.GetSymbolInfo(ma.Expression); if (symbolInfo.Symbol == null || symbolInfo.Symbol.Kind != SymbolKind.Parameter) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var list = new List <CompletionData> (); var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); var addedSymbols = new HashSet <string> (); foreach (var ano in ma.AncestorsAndSelf().OfType <AnonymousMethodExpressionSyntax> ()) { Analyze(engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken); } foreach (var ano in ma.AncestorsAndSelf().OfType <ParenthesizedLambdaExpressionSyntax> ()) { Analyze(engine, model, ma.Expression, within, list, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken); } return(Task.FromResult((IEnumerable <CompletionData>)list)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken)) { return(null); } var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord(position); if (token.Kind() != SyntaxKind.OpenParenToken && token.Kind() != SyntaxKind.CommaToken) { return(null); } var attributeArgumentList = token.Parent as AttributeArgumentListSyntax; var attributeSyntax = token.Parent.Parent as AttributeSyntax; if (attributeSyntax == null || attributeArgumentList == null) { return(null); } // We actually want to collect two sets of named parameters to present the user. The // normal named parameters that come from the attribute constructors. These will be // presented like "foo:". And also the named parameters that come from the writable // fields/properties in the attribute. These will be presented like "bar =". var existingNamedParameters = GetExistingNamedParameters(attributeArgumentList, position); var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false); var nameColonItems = await GetNameColonItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); var nameEqualsItems = await GetNameEqualsItemsAsync(engine, workspace, semanticModel, position, token, attributeSyntax, existingNamedParameters, cancellationToken).ConfigureAwait(false); // If we're after a name= parameter, then we only want to show name= parameters. if (IsAfterNameEqualsArgument(token)) { return(nameEqualsItems); } return(nameColonItems.Concat(nameEqualsItems)); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var list = new List<CompletionData> (); var newExpression = GetObjectCreationNewExpression (ctx.SyntaxTree, completionContext.Position, cancellationToken); if (newExpression == null) { if (ctx.SyntaxTree.IsInNonUserCode(completionContext.Position, cancellationToken) || ctx.SyntaxTree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken)) return Enumerable.Empty<CompletionData> (); // if (!nkr.IsValid (completionContext.Position, ctx.CSharpSyntaxContext, cancellationToken)) // return Enumerable.Empty<ICompletionData> (); var tokenOnLeftOfPosition = ctx.SyntaxTree.FindTokenOnLeftOfPosition (completionContext.Position, cancellationToken); if (!tokenOnLeftOfPosition.IsKind (SyntaxKind.EqualsToken) && !tokenOnLeftOfPosition.Parent.IsKind (SyntaxKind.EqualsValueClause)) return Enumerable.Empty<CompletionData> (); foreach (var inferredType in SyntaxContext.InferenceService.InferTypes (ctx.CSharpSyntaxContext.SemanticModel, completionContext.Position, cancellationToken)) { if (inferredType.IsEnumType () || inferredType.IsInterfaceType () || inferredType.IsAbstract) continue; foreach (var symbol in await GetPreselectedSymbolsWorker(ctx.CSharpSyntaxContext, inferredType, completionContext.Position - 1, cancellationToken)) { var symbolCompletionData = engine.Factory.CreateObjectCreation (this, inferredType, symbol, completionContext.Position, false); list.Add (symbolCompletionData); } } return list; } var expr = newExpression; var assignmentParent = expr.Parent as AssignmentExpressionSyntax; // HACK: Work around for a little bug in InferTypes see #41388 - may be obsolete in future roslyn versions. (after 1.2) bool skipInference = false; if (assignmentParent?.Left == expr) { skipInference = true; } if (!skipInference) { var type = SyntaxContext.InferenceService.InferType (ctx.CSharpSyntaxContext.SemanticModel, expr, objectAsDefault: false, cancellationToken: cancellationToken); foreach (var symbol in await GetPreselectedSymbolsWorker (ctx.CSharpSyntaxContext, type, completionContext.Position, cancellationToken)) { var symbolCompletionData = engine.Factory.CreateObjectCreation (this, type, symbol, newExpression.SpanStart, true); list.Add (symbolCompletionData); if (string.IsNullOrEmpty (result.DefaultCompletionString)) { result.DefaultCompletionString = symbolCompletionData.DisplayText; result.AutoCompleteEmptyMatch = true; } } } for (int i = 0; i < primitiveTypesKeywords.Length; i++) { var keyword = primitiveTypesKeywords [i]; list.Add (engine.Factory.CreateKeywordCompletion (this, keyword, primitiveTypesKeywordKinds[i])); } return list; }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { // var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false); var document = completionContext.Document; var semanticModel = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var startLineNumber = text.Lines.IndexOf(completionContext.Position); // modifiers* override modifiers* type? | Accessibility seenAccessibility; //DeclarationModifiers modifiers; var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.Parent == null) { return(Enumerable.Empty <CompletionData> ()); } var parentMember = token.Parent.AncestorsAndSelf().OfType <MemberDeclarationSyntax> ().FirstOrDefault(m => !m.IsKind(SyntaxKind.IncompleteMember)); if (!(parentMember is BaseTypeDeclarationSyntax) && /* May happen in case: * * override $ * public override string Foo () {} */ !(token.IsKind(SyntaxKind.OverrideKeyword) && token.Span.Start <= parentMember.Span.Start)) { return(Enumerable.Empty <CompletionData> ()); } var position = completionContext.Position; var startToken = token.GetPreviousTokenIfTouchingWord(position); ITypeSymbol returnType; SyntaxToken tokenBeforeReturnType; TryDetermineReturnType(startToken, semanticModel, cancellationToken, out returnType, out tokenBeforeReturnType); if (returnType == null) { var enclosingType = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol; if (enclosingType != null && (startToken.IsKind(SyntaxKind.OpenBraceToken) || startToken.IsKind(SyntaxKind.CloseBraceToken) || startToken.IsKind(SyntaxKind.SemicolonToken))) { return(CreateCompletionData(engine, semanticModel, position, returnType, Accessibility.NotApplicable, startToken, tokenBeforeReturnType, false, cancellationToken)); } } if (!TryDetermineModifiers(ref tokenBeforeReturnType, text, startLineNumber, out seenAccessibility /*, out modifiers*/) || !TryCheckForTrailingTokens(tree, text, startLineNumber, position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } return(CreateCompletionData(engine, semanticModel, position, returnType, seenAccessibility, startToken, tokenBeforeReturnType, true, cancellationToken)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var span = new TextSpan(position, 0); var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false); var syntaxTree = semanticModel.SyntaxTree; // var ctx = await completionContext.GetSyntaxContextAsync (engine.Workspace, cancellationToken).ConfigureAwait (false); if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var node = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken) .GetPreviousTokenIfTouchingWord(position) .Parent; if (node.Kind() == SyntaxKind.ExplicitInterfaceSpecifier) { return(await GetCompletionsOffOfExplicitInterfaceAsync( engine, document, semanticModel, position, ((ExplicitInterfaceSpecifierSyntax)node).Name, cancellationToken).ConfigureAwait(false)); } return(Enumerable.Empty <CompletionData> ()); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var tree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree.IsInNonUserCode(completionContext.Position, cancellationToken) || tree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken) || info.CompletionTriggerReason != CompletionTriggerReason.CompletionCommand) { return(Enumerable.Empty <CompletionData>()); } var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.Span.End == completionContext.Position) { return(Enumerable.Empty <CompletionData>()); } var parent = token.Parent.AncestorsAndSelf().OfType <GenericNameSyntax> ().FirstOrDefault() ?? token.Parent; if (!parent.Parent.IsKind(SyntaxKind.IncompleteMember) && !IsLocal(parent) && !parent.Parent.IsKind(SyntaxKind.Parameter) && !parent.Parent.IsKind(SyntaxKind.ForEachStatement)) { return(Enumerable.Empty <CompletionData>()); } if (info.TriggerCharacter != ' ' && parent.Parent.IsKind(SyntaxKind.ExpressionStatement)) { return(Enumerable.Empty <CompletionData>()); } var list = new List <CompletionData> (); if (parent.IsKind(SyntaxKind.PredefinedType)) { switch (token.Kind()) { case SyntaxKind.ObjectKeyword: list.Add(engine.Factory.CreateGenericData(this, "o", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "obj", GenericDataType.NameProposal)); return(list); case SyntaxKind.BoolKeyword: list.Add(engine.Factory.CreateGenericData(this, "b", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "pred", GenericDataType.NameProposal)); return(list); case SyntaxKind.CharKeyword: list.Add(engine.Factory.CreateGenericData(this, "c", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "ch", GenericDataType.NameProposal)); return(list); case SyntaxKind.StringKeyword: list.Add(engine.Factory.CreateGenericData(this, "str", GenericDataType.NameProposal)); return(list); case SyntaxKind.DoubleKeyword: case SyntaxKind.FloatKeyword: case SyntaxKind.DecimalKeyword: list.Add(engine.Factory.CreateGenericData(this, "d", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "f", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "m", GenericDataType.NameProposal)); return(list); default: list.Add(engine.Factory.CreateGenericData(this, "i", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "j", GenericDataType.NameProposal)); list.Add(engine.Factory.CreateGenericData(this, "k", GenericDataType.NameProposal)); return(list); } } else { var incompleteMember = parent.Parent as IncompleteMemberSyntax; if (incompleteMember != null) { return(list); } var gns = parent as GenericNameSyntax; var names = WordParser.BreakWords(gns != null ? gns.Identifier.ToString() : token.ToString().Trim()); var possibleName = new StringBuilder(); for (int i = 0; i < names.Count; i++) { possibleName.Length = 0; for (int j = i; j < names.Count; j++) { if (string.IsNullOrEmpty(names [j])) { continue; } if (j == i) { names [j] = Char.ToLower(names [j] [0]) + names [j].Substring(1); } possibleName.Append(names [j]); } list.Add(engine.Factory.CreateGenericData(this, possibleName.ToString(), GenericDataType.NameProposal)); } } return(list); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var targetToken = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position); if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective)) { var compilation = await document.GetCSharpCompilationAsync(cancellationToken).ConfigureAwait(false); var aliases = compilation.ExternalReferences.Where(r => r.Properties.Aliases != null).SelectMany(r => r.Properties.Aliases).ToSet(); if (aliases.Any()) { var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false); var usedAliases = root.ChildNodes().OfType <ExternAliasDirectiveSyntax>().Where(e => !e.Identifier.IsMissing).Select(e => e.Identifier.ValueText); foreach (var used in usedAliases) { aliases.Remove(used); } aliases.Remove(MetadataReferenceProperties.GlobalAlias); return(aliases.Select(e => engine.Factory.CreateGenericData(this, e, GenericDataType.Undefined))); } } return(Enumerable.Empty <CompletionData> ()); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken) || syntaxTree.GetContainingTypeOrEnumDeclaration(position, cancellationToken) is EnumDeclarationSyntax) { return(Enumerable.Empty <CompletionData>()); } // var span = new TextSpan(position, 0); // var semanticModel = await document.GetCSharpSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false); if (syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { var directive = syntaxTree.GetRoot(cancellationToken).FindTokenOnLeftOfPosition(position, includeDirectives: true).GetAncestor <DirectiveTriviaSyntax>(); if (directive.DirectiveNameToken.IsKind( SyntaxKind.IfKeyword, SyntaxKind.RegionKeyword, SyntaxKind.ElseKeyword, SyntaxKind.ElifKeyword, SyntaxKind.ErrorKeyword, SyntaxKind.LineKeyword, SyntaxKind.PragmaKeyword, SyntaxKind.EndIfKeyword, SyntaxKind.UndefKeyword, SyntaxKind.EndRegionKeyword, SyntaxKind.WarningKeyword)) { return(Enumerable.Empty <CompletionData>()); } return(await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false)); } var tokenLeftOfPosition = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken); if (syntaxTree.IsGlobalStatementContext(position, cancellationToken) || syntaxTree.IsExpressionContext(position, tokenLeftOfPosition, true, cancellationToken) || syntaxTree.IsStatementContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsTypeContext(position, cancellationToken) || syntaxTree.IsTypeDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsNamespaceContext(position, cancellationToken) || syntaxTree.IsMemberDeclarationContext(position, tokenLeftOfPosition, cancellationToken) || syntaxTree.IsLabelContext(position, cancellationToken)) { return(await GetSnippetCompletionItemsAsync(cancellationToken).ConfigureAwait(false)); } return(Enumerable.Empty <CompletionData>()); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.IsMandatoryNamedParameterPosition()) { return(Enumerable.Empty <CompletionData> ()); } var result = new List <CompletionData> (); foreach (var _type in ctx.InferredTypes) { var type = _type; if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments().FirstOrDefault(); if (type == null) { continue; } } if (type.TypeKind != TypeKind.Enum) { continue; } if (!type.IsEditorBrowsable()) { continue; } // Does type have any aliases? ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false); if (string.IsNullOrEmpty(completionResult.DefaultCompletionString)) { completionResult.DefaultCompletionString = type.Name; } result.Add(engine.Factory.CreateSymbolCompletionData(this, type, RoslynCompletionData.SafeMinimalDisplayString(type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat))); foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol>()) { if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) { result.Add(engine.Factory.CreateEnumMemberCompletionData(this, alias, field)); } } } return(result); }
public override async Task <bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { // We're exclusive if this context could only be an object initializer and not also a // collection initializer. If we're initializing something that could be initialized as // an object or as a collection, say we're not exclusive. That way the rest of // intellisense can be used in the collection intitializer. // // Consider this case: // class c : IEnumerable<int> // { // public void Add(int addend) { } // public int foo; // } // void foo() // { // var b = new c {| // } // There we could initialize b using either an object initializer or a collection // initializer. Since we don't know which the user will use, we'll be non-exclusive, so // the other providers can help the user write the collection initializer, if they want // to. var tree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree.IsInNonUserCode(position, cancellationToken)) { return(false); } var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken); token = token.GetPreviousTokenIfTouchingWord(position); if (token.Parent == null) { return(false); } var expression = token.Parent.Parent as ExpressionSyntax; if (expression == null) { return(false); } var semanticModel = await document.GetCSharpSemanticModelForNodeAsync(expression, cancellationToken).ConfigureAwait(false); var initializedType = semanticModel.GetTypeInfo(expression, cancellationToken).Type; if (initializedType == null) { return(false); } // Non-exclusive if initializedType can be initialized as a collection. if (initializedType.CanSupportCollectionInitializer()) { return(false); } // By default, only our member names will show up. return(true); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var semanticModel = ctx.SemanticModel; if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument)) { SourceText text; if (!completionContext.Document.TryGetText(out text)) { text = await completionContext.Document.GetTextAsync(); } var currentChar = text [completionContext.Position - 1]; if (ctx.TargetToken.Parent == null || !ctx.TargetToken.Parent.IsKind(SyntaxKind.StringLiteralExpression) || ctx.TargetToken.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument) || ctx.TargetToken.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.IsKind(SyntaxKind.ArgumentList) || ctx.TargetToken.Parent.Parent.Parent.Parent == null || !ctx.TargetToken.Parent.Parent.Parent.Parent.IsKind(SyntaxKind.InvocationExpression)) { return(Enumerable.Empty <CompletionData> ()); } var formatArgument = GetFormatItemNumber(document, position); var invocationExpression = ctx.TargetToken.Parent.Parent.Parent.Parent as InvocationExpressionSyntax; return(GetFormatCompletionData(engine, semanticModel, invocationExpression, formatArgument, currentChar)); } return(Enumerable.Empty <CompletionData> ()); }
public override Task <bool> IsExclusiveAsync(CompletionContext completionContext, SyntaxContext ctx, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; //DeclarationModifiers modifiers; SyntaxToken token; var semanticModel = ctx.SemanticModel; var enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol; // Only inside classes and structs if (enclosingSymbol == null || !(enclosingSymbol.TypeKind == TypeKind.Struct || enclosingSymbol.TypeKind == TypeKind.Class)) { return(Task.FromResult(false)); } if (!IsPartialCompletionContext(tree, position, cancellationToken /*, out modifiers*/, out token)) { return(Task.FromResult(false)); } return(Task.FromResult(true)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax; if (ma == null) { return(Enumerable.Empty <CompletionData> ()); } var model = ctx.CSharpSyntaxContext.SemanticModel; var symbolInfo = model.GetSymbolInfo(ma.Expression); if (symbolInfo.Symbol == null) { return(Enumerable.Empty <CompletionData> ()); } var list = new List <CompletionData> (); var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); var addedSymbols = new HashSet <string> (); foreach (var ifStmSyntax in ma.Expression.AncestorsAndSelf().OfType <IfStatementSyntax> ()) { var condition = ifStmSyntax.Condition.SkipParens(); if (condition == null || !condition.IsKind(SyntaxKind.IsExpression)) { continue; } var isExpr = ((BinaryExpressionSyntax)condition); var leftSymbol = model.GetSymbolInfo(isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo(isExpr.Right).Type; if (type != null) { Analyze(engine, ma.Expression, type, within, list, addedSymbols, cancellationToken); } } } return(list); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var workspace = document.Project.Solution.Workspace; var semanticModel = await document.GetSemanticModelForSpanAsync (new TextSpan (position, 0), cancellationToken).ConfigureAwait (false); var typeAndLocation = GetInitializedType (document, semanticModel, position, cancellationToken); if (typeAndLocation == null) return Enumerable.Empty<CompletionData> (); var initializedType = typeAndLocation.Item1 as INamedTypeSymbol; var initializerLocation = typeAndLocation.Item2; if (initializedType == null) return Enumerable.Empty<CompletionData> (); // Find the members that can be initialized. If we have a NamedTypeSymbol, also get the overridden members. IEnumerable<ISymbol> members = semanticModel.LookupSymbols (position, initializedType); members = members.Where (m => IsInitializable (m, initializedType) && m.CanBeReferencedByName && IsLegalFieldOrProperty (m) && !m.IsImplicitlyDeclared); // Filter out those members that have already been typed var alreadyTypedMembers = GetInitializedMembers (semanticModel.SyntaxTree, position, cancellationToken); var uninitializedMembers = members.Where (m => !alreadyTypedMembers.Contains (m.Name)); uninitializedMembers = uninitializedMembers.Where (m => m.IsEditorBrowsable ()); // var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); // var changes = GetTextChangeSpan(text, position); var list = new List<CompletionData> (); // Return the members foreach (var member in uninitializedMembers) { list.Add (engine.Factory.CreateSymbolCompletionData (this, member)); } return list; }
public async Task<CompletionResult> GetCompletionDataAsync(CompletionContext completionContext, CompletionTriggerInfo info, CancellationToken cancellationToken = default(CancellationToken)) { if (completionContext == null) throw new ArgumentNullException ("completionContext"); var document = completionContext.Document; var semanticModel = await completionContext.GetSemanticModelAsync (cancellationToken).ConfigureAwait(false); var position = completionContext.Position; var text = await document.GetTextAsync (cancellationToken).ConfigureAwait (false); var ctx = await completionContext.GetSyntaxContextAsync (workspace, cancellationToken); ctx.SemanticModel = semanticModel; // case lambda parameter (n1, $ if (ctx.TargetToken.IsKind (SyntaxKind.CommaToken) && ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null && ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.ParenthesizedLambdaExpression)) return CompletionResult.Empty; var result = new CompletionResult { SyntaxContext = ctx }; if (position > 0) { var nonExclusiveHandlers = new List<CompletionContextHandler> (); var exclusiveHandlers = new List<CompletionContextHandler> (); var toRetriggerHandlers = new List<CompletionContextHandler> (); IEnumerable<CompletionContextHandler> handlerList; if (completionContext.UseDefaultContextHandlers) { handlerList = handlers.Concat (completionContext.AdditionalContextHandlers); } else { handlerList = completionContext.AdditionalContextHandlers; } foreach (var handler in handlerList) { if (info.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand || handler.IsTriggerCharacter (text, position - 1)) { if (await handler.IsExclusiveAsync (completionContext, ctx, info, cancellationToken)) { exclusiveHandlers.Add (handler); } else { nonExclusiveHandlers.Add (handler); } } else { toRetriggerHandlers.Add (handler); } } foreach (var handler in exclusiveHandlers) { var handlerResult = handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken).Result; //if (handlerResult != null) { // Console.WriteLine ("-----" + handler); // foreach (var item in handlerResult) { // Console.WriteLine (item.DisplayText); // } //} else { // Console.WriteLine ("-----" + handler + " == NULL"); //} if (handlerResult != null) result.AddRange (handlerResult); } if (result.Count == 0) { foreach (var handler in nonExclusiveHandlers) { var handlerResult = await handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken); //if (handlerResult != null) { // Console.WriteLine ("-----" + handler); // foreach (var item in handlerResult) { // Console.WriteLine (item.DisplayText); // } //} else { // Console.WriteLine ("-----" + handler + " == NULL"); //} if (handlerResult != null && handlerResult.Any ()) { result.AddRange (handlerResult); } else { toRetriggerHandlers.Add (handler); } } if (result.Count > 0) { info = info.WithCompletionTriggerReason (CompletionTriggerReason.RetriggerCommand); foreach (var handler in toRetriggerHandlers) { var handlerResult = await handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken); if (handlerResult != null) result.AddRange (handlerResult); } } } } // prevent auto selection for "<number>." case if (ctx.TargetToken.IsKind(SyntaxKind.DotToken)) { var accessExpr = ctx.TargetToken.Parent as MemberAccessExpressionSyntax; if (accessExpr != null && accessExpr.Expression != null && accessExpr.Expression.IsKind(SyntaxKind.NumericLiteralExpression)) { result.AutoSelect = false; } } if (ctx.LeftToken.Parent != null && ctx.LeftToken.Parent.Parent != null && ctx.TargetToken.Parent != null && !ctx.TargetToken.Parent.IsKind(SyntaxKind.NameEquals) && ctx.LeftToken.Parent.Parent.IsKind(SyntaxKind.AnonymousObjectMemberDeclarator)) result.AutoSelect = false; if (ctx.TargetToken.IsKind (SyntaxKind.OpenParenToken) && ctx.TargetToken.GetPreviousToken ().IsKind (SyntaxKind.OpenParenToken)) { var validTypes = TypeGuessing.GetValidTypes (semanticModel, ctx.TargetToken.Parent, cancellationToken); result.AutoSelect = !validTypes.Any (t => t.IsDelegateType ()); } foreach (var type in ctx.InferredTypes) { if (type.TypeKind == TypeKind.Delegate) { result.AutoSelect = false; break; } } return result; }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var model = ctx.SemanticModel; var tree = ctx.SyntaxTree; if (tree.IsInNonUserCode(completionContext.Position, cancellationToken)) { return(Enumerable.Empty <CompletionData> ()); } var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.IsKind(SyntaxKind.DotToken) || token.IsMandatoryNamedParameterPosition()) { return(Enumerable.Empty <CompletionData> ()); } var result = new List <CompletionData> (); // check if it's the first parameter and set autoselect == false if a parameterless version exists. if (token.IsKind(SyntaxKind.OpenParenToken)) { var parent = token.Parent?.Parent; if (parent == null) { return(Enumerable.Empty <CompletionData> ()); } var symbolInfo = model.GetSymbolInfo(parent); foreach (var symbol in new [] { symbolInfo.Symbol }.Concat(symbolInfo.CandidateSymbols)) { if (symbol != null && symbol.IsKind(SymbolKind.Method)) { if (symbol.GetParameters().Length == 0) { completionResult.AutoSelect = false; break; } } } } foreach (var _type in ctx.InferredTypes) { var type = _type; if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { type = type.GetTypeArguments().FirstOrDefault(); if (type == null) { continue; } } if (type.TypeKind != TypeKind.Enum) { continue; } if (!type.IsEditorBrowsable()) { continue; } // Does type have any aliases? ISymbol alias = await type.FindApplicableAlias(completionContext.Position, model, cancellationToken).ConfigureAwait(false); var displayString = RoslynCompletionData.SafeMinimalDisplayString(type, model, completionContext.Position, SymbolDisplayFormat.CSharpErrorMessageFormat); if (string.IsNullOrEmpty(completionResult.DefaultCompletionString)) { completionResult.DefaultCompletionString = displayString; completionResult.AutoCompleteEmptyMatch = true; } if (!IsReachable(model, type, token.Parent)) { result.Add(engine.Factory.CreateSymbolCompletionData(this, type, displayString)); } foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol> ()) { if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic)) { result.Add(engine.Factory.CreateEnumMemberCompletionData(this, alias, field)); } } } return(result); }
public async Task <IEnumerable <CompletionData> > GetCompletionDataAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken = default(CancellationToken)) { // If we were triggered by typign a character, then do a semantic check to make sure // we're still applicable. If not, then return immediately. if (info.CompletionTriggerReason == CompletionTriggerReason.CharTyped) { var isSemanticTriggerCharacter = await IsSemanticTriggerCharacterAsync(completionContext.Document, completionContext.Position - 1, cancellationToken).ConfigureAwait(false); if (!isSemanticTriggerCharacter) { return(null); } } return(await GetItemsWorkerAsync(result, engine, completionContext, info, ctx, cancellationToken).ConfigureAwait(false)); }
protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var semanticModel = ctx.SemanticModel; var result = new List<CompletionData> (); if (info.TriggerCharacter == ' ') { var newExpression = ObjectCreationContextHandler.GetObjectCreationNewExpression (ctx.SyntaxTree, completionContext.Position, cancellationToken); if (newExpression == null && info.CompletionTriggerReason == CompletionTriggerReason.CharTyped && !ctx.LeftToken.IsKind (SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind (SyntaxKind.EqualsEqualsToken)) return Task.FromResult (Enumerable.Empty<CompletionData> ()); completionResult.AutoCompleteEmptyMatch = false; } var parent = ctx.TargetToken.Parent; bool isInAttribute = ctx.CSharpSyntaxContext.IsAttributeNameContext; bool isInBaseList = parent != null && parent.IsKind (SyntaxKind.BaseList); bool isInUsingDirective = parent != null && parent.Parent != null && parent.Parent.IsKind (SyntaxKind.UsingDirective) && !parent.IsKind (SyntaxKind.QualifiedName); var isInQuery = ctx.CSharpSyntaxContext.IsInQuery; var completionDataLookup = new Dictionary<Tuple<string, SymbolKind>, ISymbolCompletionData> (); bool isInCatchTypeExpression = parent != null && parent.IsKind (SyntaxKind.CatchDeclaration) || parent.IsKind (SyntaxKind.QualifiedName) && parent.Parent != null && parent.Parent.IsKind (SyntaxKind.CatchDeclaration); Action<ISymbolCompletionData> addData = d => { var key = Tuple.Create (d.DisplayText, d.Symbol.Kind); ISymbolCompletionData data; if (completionDataLookup.TryGetValue (key, out data)) { data.AddOverload (d); return; } completionDataLookup.Add (key, d); result.Add (d); }; var completionCategoryLookup = new Dictionary<string, CompletionCategory> (); foreach (var symbol in Recommender.GetRecommendedSymbolsAtPosition (semanticModel, completionContext.Position, engine.Workspace, null, cancellationToken)) { if (symbol.Kind == SymbolKind.NamedType) { if (isInAttribute) { var type = (ITypeSymbol)symbol; if (type.IsAttribute ()) { var v = type.Name.Substring (0, type.Name.Length - "Attribute".Length); var needsEscaping = SyntaxFacts.GetKeywordKind(v) != SyntaxKind.None; needsEscaping = needsEscaping || (isInQuery && SyntaxFacts.IsQueryContextualKeyword(SyntaxFacts.GetContextualKeywordKind(v))); if (!needsEscaping) { addData (engine.Factory.CreateSymbolCompletionData (this, symbol, v)); continue; } } } if (isInBaseList) { var type = (ITypeSymbol)symbol; if (type.IsSealed || type.IsStatic) continue; } if (isInCatchTypeExpression) { var type = (ITypeSymbol)symbol; if (!IsException (type)) continue; } } if (isInUsingDirective && symbol.Kind != SymbolKind.Namespace) continue; var newData = engine.Factory.CreateSymbolCompletionData (this, symbol, symbol.Name.EscapeIdentifier (isInQuery)); ISymbol categorySymbol; var method = symbol as IMethodSymbol; if (method != null) { if (method.IsReducedExtension ()) { categorySymbol = method.ReceiverType; } else { categorySymbol = (ISymbol)symbol.ContainingType; } } else { categorySymbol = (ISymbol)symbol.ContainingType ?? symbol.ContainingNamespace; } if (categorySymbol != null) { CompletionCategory category; var key = categorySymbol.ToDisplayString (); if (!completionCategoryLookup.TryGetValue (key, out category)) { completionCategoryLookup [key] = category = engine.Factory.CreateCompletionDataCategory (categorySymbol); } newData.CompletionCategory = category; } addData (newData); } return Task.FromResult ((IEnumerable<CompletionData>)result); }
protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax; if (ma == null) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var model = ctx.CSharpSyntaxContext.SemanticModel; var symbolInfo = model.GetSymbolInfo(ma.Expression); if (symbolInfo.Symbol == null) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var list = new List <CompletionData> (); var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); var addedSymbols = new HashSet <string> (); SyntaxNode ancestor = ma.Expression; while (ancestor != null) { // check parent if for direct type check var ifStmSyntax = ancestor as IfStatementSyntax; if (ifStmSyntax != null) { var condition = SkipParens(ifStmSyntax.Condition); if (condition != null && condition.IsKind(SyntaxKind.IsExpression)) { var isExpr = ((BinaryExpressionSyntax)condition); var leftSymbol = model.GetSymbolInfo(isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo(isExpr.Right).Type; if (type != null) { Analyze(engine, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, list, addedSymbols, cancellationToken); } } } // skip if else ... if else if (ancestor.Parent is ElseClauseSyntax) { while (ancestor is IfStatementSyntax || ancestor is ElseClauseSyntax) { ancestor = ancestor.Parent; } continue; } goto loop; } // check parent block if an if is there that checks the type var blockSyntax = ancestor as BlockSyntax; if (blockSyntax != null) { foreach (var ifStmt in blockSyntax.Statements.OfType <IfStatementSyntax> ()) { if (ifStmt.Span.End >= ma.Span.Start) { break; } var condition = SkipParens(ifStmt.Condition); bool wasNegated = false; if (condition.IsKind(SyntaxKind.LogicalNotExpression)) { condition = SkipParens(((PrefixUnaryExpressionSyntax)condition).Operand); wasNegated = true; } if (condition == null || !condition.IsKind(SyntaxKind.IsExpression)) { goto loop; } var stmt = ifStmt.Statement; if (stmt is BlockSyntax) { stmt = ((BlockSyntax)stmt).Statements.LastOrDefault(); } if (!wasNegated || stmt == null || !stmt.IsKind(SyntaxKind.ReturnStatement) && !stmt.IsKind(SyntaxKind.ContinueStatement) && !stmt.IsKind(SyntaxKind.BreakStatement) && !stmt.IsKind(SyntaxKind.ThrowStatement)) { goto loop; } var isExpr = ((BinaryExpressionSyntax)condition); var leftSymbol = model.GetSymbolInfo(isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo(isExpr.Right).Type; if (type != null) { Analyze(engine, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, list, addedSymbols, cancellationToken); } } } } var binOp = ancestor as BinaryExpressionSyntax; if (binOp != null && binOp.IsKind(SyntaxKind.LogicalAndExpression)) { if (SkipParens(binOp.Left).IsKind(SyntaxKind.IsExpression)) { var isExpr = (BinaryExpressionSyntax)SkipParens(binOp.Left); var leftSymbol = model.GetSymbolInfo(isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo(isExpr.Right).Type; if (type != null) { Analyze(engine, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, list, addedSymbols, cancellationToken); } } } } loop : ancestor = ancestor.Parent; } return(Task.FromResult((IEnumerable <CompletionData>)list)); }
public override async Task <bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var syntaxTree = await document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken) .GetPreviousTokenIfTouchingWord(position); return(IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token)); }
protected override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var position = completionContext.Position; var document = completionContext.Document; var syntaxTree = ctx.SyntaxTree; if (syntaxTree.IsInNonUserCode(position, cancellationToken) || syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken)) return Task.FromResult (Enumerable.Empty<CompletionData> ()); if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(position, cancellationToken)) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax; if (ma == null) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var model = ctx.CSharpSyntaxContext.SemanticModel; var symbolInfo = model.GetSymbolInfo (ma.Expression); if (symbolInfo.Symbol == null) return Task.FromResult (Enumerable.Empty<CompletionData> ()); var list = new List<CompletionData> (); var within = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken); var addedSymbols = new HashSet<string> (); SyntaxNode ancestor = ma.Expression; while (ancestor != null) { // check parent if for direct type check var ifStmSyntax = ancestor as IfStatementSyntax; if (ifStmSyntax != null) { var condition = ifStmSyntax.Condition.SkipParens (); if (condition != null && condition.IsKind (SyntaxKind.IsExpression)) { var isExpr = ((BinaryExpressionSyntax)condition); var leftSymbol = model.GetSymbolInfo (isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo (isExpr.Right).Type; if (type != null) { Analyze (engine, ma.Expression, type, model.GetTypeInfo (isExpr.Left).Type, within, list, addedSymbols, cancellationToken); } } } // skip if else ... if else if (ancestor.Parent is ElseClauseSyntax) { while (ancestor is IfStatementSyntax || ancestor is ElseClauseSyntax) ancestor = ancestor.Parent; continue; } goto loop; } // check parent block if an if is there that checks the type var blockSyntax = ancestor as BlockSyntax; if (blockSyntax != null) { foreach (var ifStmt in blockSyntax.Statements.OfType<IfStatementSyntax> ()) { if (ifStmt.Span.End >= ma.Span.Start) break; var condition = ifStmt.Condition.SkipParens (); bool wasNegated = false; if (condition.IsKind (SyntaxKind.LogicalNotExpression)) { condition = ((PrefixUnaryExpressionSyntax)condition).Operand.SkipParens (); wasNegated = true; } if (condition == null || !condition.IsKind (SyntaxKind.IsExpression)) goto loop; var stmt = ifStmt.Statement; if (stmt is BlockSyntax) { stmt = ((BlockSyntax)stmt).Statements.LastOrDefault (); } if (!wasNegated || stmt == null || !stmt.IsKind (SyntaxKind.ReturnStatement) && !stmt.IsKind (SyntaxKind.ContinueStatement) && !stmt.IsKind (SyntaxKind.BreakStatement) && !stmt.IsKind (SyntaxKind.ThrowStatement)) goto loop; var isExpr = ((BinaryExpressionSyntax)condition); var leftSymbol = model.GetSymbolInfo (isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo (isExpr.Right).Type; if (type != null) { Analyze (engine, ma.Expression, type, model.GetTypeInfo (isExpr.Left).Type, within, list, addedSymbols, cancellationToken); } } } } var binOp = ancestor as BinaryExpressionSyntax; if (binOp != null && binOp.IsKind (SyntaxKind.LogicalAndExpression)) { if (binOp.Left.SkipParens ().IsKind (SyntaxKind.IsExpression)) { var isExpr = ((BinaryExpressionSyntax)binOp.Left.SkipParens ()); var leftSymbol = model.GetSymbolInfo (isExpr.Left); if (leftSymbol.Symbol == symbolInfo.Symbol) { var type = model.GetTypeInfo (isExpr.Right).Type; if (type != null) { Analyze (engine, ma.Expression, type, model.GetTypeInfo (isExpr.Left).Type, within, list, addedSymbols, cancellationToken); } } } } loop: ancestor = ancestor.Parent; } return Task.FromResult ((IEnumerable<CompletionData>)list); }
public virtual Task <bool> IsExclusiveAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { return(Task.FromResult(false)); }
protected async override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var semanticModel = ctx.SemanticModel; var result = new List <CompletionData> (); if (info.TriggerCharacter == ' ') { var newExpression = ObjectCreationContextHandler.GetObjectCreationNewExpression(ctx.SyntaxTree, completionContext.Position, cancellationToken); if (newExpression == null && info.CompletionTriggerReason == CompletionTriggerReason.CharTyped && !ctx.LeftToken.IsKind(SyntaxKind.EqualsToken) && !ctx.LeftToken.IsKind(SyntaxKind.EqualsEqualsToken)) { return(Enumerable.Empty <CompletionData> ()); } completionResult.AutoCompleteEmptyMatch = false; } var parent = ctx.TargetToken.Parent; bool isInAttribute = ctx.CSharpSyntaxContext.IsAttributeNameContext; bool isInBaseList = parent != null && parent.IsKind(SyntaxKind.BaseList); bool isInUsingDirective = parent != null && parent.Parent != null && parent.Parent.IsKind(SyntaxKind.UsingDirective) && !parent.IsKind(SyntaxKind.QualifiedName); var isInQuery = ctx.CSharpSyntaxContext.IsInQuery; var completionDataLookup = new Dictionary <Tuple <string, SymbolKind>, ISymbolCompletionData> (); bool isInCatchTypeExpression = parent.IsKind(SyntaxKind.CatchDeclaration) || parent.IsKind(SyntaxKind.QualifiedName) && parent != null && parent.Parent.IsKind(SyntaxKind.CatchDeclaration); Action <ISymbolCompletionData> addData = d => { var key = Tuple.Create(d.DisplayText, d.Symbol.Kind); ISymbolCompletionData data; if (completionDataLookup.TryGetValue(key, out data)) { data.AddOverload(d); return; } completionDataLookup.Add(key, d); result.Add(d); }; var completionCategoryLookup = new Dictionary <string, CompletionCategory> (); foreach (var symbol in Recommender.GetRecommendedSymbolsAtPosition(semanticModel, completionContext.Position, engine.Workspace, null, cancellationToken)) { if (symbol.Kind == SymbolKind.NamedType) { if (isInAttribute) { var type = (ITypeSymbol)symbol; if (type.IsAttribute()) { var v = type.Name.Substring(0, type.Name.Length - "Attribute".Length); var needsEscaping = SyntaxFacts.GetKeywordKind(v) != SyntaxKind.None; needsEscaping = needsEscaping || (isInQuery && SyntaxFacts.IsQueryContextualKeyword(SyntaxFacts.GetContextualKeywordKind(v))); if (!needsEscaping) { addData(engine.Factory.CreateSymbolCompletionData(this, symbol, v)); continue; } } } if (isInBaseList) { var type = (ITypeSymbol)symbol; if (type.IsSealed || type.IsStatic) { continue; } } if (isInCatchTypeExpression) { var type = (ITypeSymbol)symbol; if (!IsException(type)) { continue; } } } if (isInUsingDirective && symbol.Kind != SymbolKind.Namespace) { continue; } var newData = engine.Factory.CreateSymbolCompletionData(this, symbol, symbol.Name.EscapeIdentifier(isInQuery)); var categorySymbol = (ISymbol)symbol.ContainingType ?? symbol.ContainingNamespace; if (categorySymbol != null) { CompletionCategory category; var key = categorySymbol.ToDisplayString(); if (!completionCategoryLookup.TryGetValue(key, out category)) { completionCategoryLookup [key] = category = engine.Factory.CreateCompletionDataCategory(categorySymbol); } newData.CompletionCategory = category; } addData(newData); } return(result); }
protected abstract Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken);
protected override Task <IEnumerable <CompletionData> > GetItemsWorkerAsync(CompletionResult result, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var document = completionContext.Document; var position = completionContext.Position; var tree = ctx.SyntaxTree; var model = ctx.SemanticModel; if (tree.IsInNonUserCode(position, cancellationToken)) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } if (!ctx.CSharpSyntaxContext.IsAnyExpressionContext) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var enclosingType = model.GetEnclosingNamedType(position, cancellationToken); if (enclosingType == null) { return(Task.FromResult(Enumerable.Empty <CompletionData> ())); } var list = new List <CompletionData> (); foreach (var type in ctx.InferredTypes) { if (type.TypeKind != TypeKind.Delegate) { continue; } string delegateName = null; if (ctx.TargetToken.IsKind(SyntaxKind.PlusEqualsToken)) { delegateName = GuessEventHandlerBaseName(ctx.LeftToken.Parent, ctx.ContainingTypeDeclaration); } AddDelegateHandlers(list, ctx.TargetToken.Parent, model, engine, result, type, position, delegateName, cancellationToken); } if (list.Count > 0) { result.AutoSelect = false; } return(Task.FromResult((IEnumerable <CompletionData>)list)); }
public virtual Task <bool> IsExclusiveAsync(CompletionContext completionContext, SyntaxContext syntaxContext, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { return(Task.FromResult(false)); }
protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var tree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree.IsInNonUserCode(completionContext.Position, cancellationToken) || tree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken) || info.CompletionTriggerReason != CompletionTriggerReason.CompletionCommand) return Enumerable.Empty<CompletionData>(); var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); if (token.Span.End == completionContext.Position) return Enumerable.Empty<CompletionData>(); var parent = token.Parent.AncestorsAndSelf ().OfType<GenericNameSyntax> ().FirstOrDefault () ?? token.Parent; if (!parent.Parent.IsKind (SyntaxKind.IncompleteMember) && !IsLocal(parent) && !parent.Parent.IsKind (SyntaxKind.Parameter) && !parent.Parent.IsKind (SyntaxKind.ForEachStatement)) { return Enumerable.Empty<CompletionData>(); } if (info.TriggerCharacter != ' ' && parent.Parent.IsKind (SyntaxKind.ExpressionStatement)) { return Enumerable.Empty<CompletionData>(); } var list = new List<CompletionData> (); if (parent.IsKind(SyntaxKind.PredefinedType)) { switch (token.Kind()) { case SyntaxKind.ObjectKeyword: list.Add (engine.Factory.CreateGenericData(this, "o", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "obj", GenericDataType.NameProposal)); return list; case SyntaxKind.BoolKeyword: list.Add (engine.Factory.CreateGenericData(this, "b", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "pred", GenericDataType.NameProposal)); return list; case SyntaxKind.CharKeyword: list.Add (engine.Factory.CreateGenericData(this, "c", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "ch", GenericDataType.NameProposal)); return list; case SyntaxKind.StringKeyword: list.Add (engine.Factory.CreateGenericData(this, "str", GenericDataType.NameProposal)); return list; case SyntaxKind.DoubleKeyword: case SyntaxKind.FloatKeyword: case SyntaxKind.DecimalKeyword: list.Add (engine.Factory.CreateGenericData(this, "d", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "f", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "m", GenericDataType.NameProposal)); return list; default: list.Add (engine.Factory.CreateGenericData(this, "i", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "j", GenericDataType.NameProposal)); list.Add (engine.Factory.CreateGenericData(this, "k", GenericDataType.NameProposal)); return list; } } else { var incompleteMember = parent.Parent as IncompleteMemberSyntax; if (incompleteMember != null) return list; var gns = parent as GenericNameSyntax; var names = WordParser.BreakWords (gns != null ? gns.Identifier.ToString () : token.ToString ().Trim ()); var possibleName = new StringBuilder (); for (int i = 0; i < names.Count; i++) { possibleName.Length = 0; for (int j = i; j < names.Count; j++) { if (string.IsNullOrEmpty (names [j])) { continue; } if (j == i) { names [j] = Char.ToLower (names [j] [0]) + names [j].Substring (1); } possibleName.Append (names [j]); } list.Add (engine.Factory.CreateGenericData (this, possibleName.ToString (), GenericDataType.NameProposal)); } } return list; }