コード例 #1
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var options = context.Options;
            var cancellationToken = context.CancellationToken;

            using (Logger.LogBlock(FunctionId.Completion_SnippetCompletionProvider_GetItemsWorker_CSharp, cancellationToken))
            {
                // TODO (https://github.com/dotnet/roslyn/issues/5107): Enable in Interactive.
                var workspace = document.Project.Solution.Workspace;
                if (!workspace.CanApplyChange(ApplyChangesKind.ChangeDocument) ||
                     workspace.Kind == WorkspaceKind.Debugger ||
                     workspace.Kind == WorkspaceKind.Interactive)
                {
                    return;
                }

                var snippetCompletionItems = await document.GetUnionItemsFromDocumentAndLinkedDocumentsAsync(
                    UnionCompletionItemComparer.Instance,
                    (d, c) => GetSnippetsForDocumentAsync(d, position, context.DefaultItemSpan, workspace, c),
                    cancellationToken).ConfigureAwait(false);

                context.AddItems(snippetCompletionItems);
            }
        }
コード例 #2
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

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

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            if (ctx.TargetToken.Parent != null && ctx.TargetToken.Parent.Parent != null &&
                ctx.TargetToken.Parent.Parent.IsKind(SyntaxKind.Argument))
            {
                SourceText text;
                if (!context.Document.TryGetText(out text))
                {
                    text = await context.Document.GetTextAsync();
                }
                var currentChar = text [context.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;
                }
                var formatArgument       = GetFormatItemNumber(document, position);
                var invocationExpression = ctx.TargetToken.Parent.Parent.Parent.Parent as InvocationExpressionSyntax;
                GetFormatCompletionData(context, semanticModel, invocationExpression, formatArgument, currentChar);
            }
        }
コード例 #3
0
        void GetFormatCompletionForType(Microsoft.CodeAnalysis.Completion.CompletionContext completionContext, ITypeSymbol type)
        {
            if (type == null)
            {
                GenerateNumberFormatitems(completionContext);
                GenerateDateTimeFormatitems(completionContext);
                GenerateTimeSpanFormatitems(completionContext);
                GenerateEnumFormatitems(completionContext);
                GenerateGuidFormatitems(completionContext);
                return;
            }

            switch (type.ToString())
            {
            case "long":
            case "System.Int64":
            case "ulong":
            case "System.UInt64":
            case "int":
            case "System.Int32":
            case "uint":
            case "System.UInt32":
            case "short":
            case "System.Int16":
            case "ushort":
            case "System.UInt16":
            case "byte":
            case "System.Byte":
            case "sbyte":
            case "System.SByte":
                GenerateNumberFormatitems(completionContext);
                break;

            case "float":
            case "System.Single":
            case "double":
            case "System.Double":
            case "decimal":
            case "System.Decimal":
                GenerateNumberFormatitems(completionContext);
                break;

            case "System.Enum":
                GenerateEnumFormatitems(completionContext);
                break;

            case "System.DateTime":
                GenerateDateTimeFormatitems(completionContext);
                break;

            case "System.TimeSpan":
                GenerateTimeSpanFormatitems(completionContext);
                break;

            case "System.Guid":
                GenerateGuidFormatitems(completionContext);
                break;
            }
        }
コード例 #4
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var cancellationToken = context.CancellationToken;

            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            if (syntaxTree.IsInNonUserCode(position, cancellationToken))
            {
                return;
            }

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

            if (!token.IsKind(SyntaxKind.OpenParenToken, SyntaxKind.CommaToken))
            {
                return;
            }

            var attributeArgumentList = token.Parent as AttributeArgumentListSyntax;
            var attributeSyntax = token.Parent.Parent as AttributeSyntax;
            if (attributeSyntax == null || attributeArgumentList == null)
            {
                return;
            }

            if (IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token))
            {
                context.IsExclusive = true;
            }

            // 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.GetSemanticModelForNodeAsync(attributeSyntax, cancellationToken).ConfigureAwait(false);
            var nameColonItems = await GetNameColonItemsAsync(context, semanticModel, token, attributeSyntax, existingNamedParameters).ConfigureAwait(false);
            var nameEqualsItems = await GetNameEqualsItemsAsync(context, semanticModel, token, attributeSyntax, existingNamedParameters).ConfigureAwait(false);

            context.AddItems(nameEqualsItems);

            // If we're after a name= parameter, then we only want to show name= parameters.
            // Otherwise, show name: parameters too.
            if (!IsAfterNameEqualsArgument(token))
            {
                context.AddItems(nameColonItems);
            }
        }
コード例 #5
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace  = document.Project.Solution.Workspace;
            var ctx        = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);
            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return;
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(
                    position,
                    syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position),
                    cancellationToken))
            {
                return;
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return;
            }
            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null || symbolInfo.Symbol.Kind != SymbolKind.Parameter)
            {
                return;
            }
            var within       = model.GetEnclosingNamedTypeOrAssembly(position, cancellationToken);
            var addedSymbols = new HashSet <string> ();

            foreach (var ano in ma.AncestorsAndSelf().OfType <AnonymousMethodExpressionSyntax> ())
            {
                Analyze(context, model, ma.Expression, within, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
            }

            foreach (var ano in ma.AncestorsAndSelf().OfType <ParenthesizedLambdaExpressionSyntax> ())
            {
                Analyze(context, model, ma.Expression, within, ano.ParameterList, symbolInfo.Symbol, addedSymbols, cancellationToken);
            }
        }
コード例 #6
0
        void Analyze(Microsoft.CodeAnalysis.Completion.CompletionContext context, SemanticModel model, SyntaxNode node, ITypeSymbol type, ITypeSymbol stopAt, ISymbol within, HashSet <string> addedSymbols, CancellationToken cancellationToken)
        {
            var startType  = type;
            var typeString = CSharpAmbience.SafeMinimalDisplayString(type, model, context.CompletionListSpan.Start, Ambience.LabelFormat);
            var pDict      = ImmutableDictionary <string, string> .Empty;

            if (typeString != null)
            {
                pDict = pDict.Add("CastTypeString", typeString);
            }
            pDict = pDict.Add("DescriptionMarkup", "- <span foreground=\"darkgray\" size='small'>" + GettextCatalog.GetString("Cast to '{0}'", type.Name) + "</span>");

            pDict = pDict.Add("NodeString", node.ToString());

            while (type != null && type.SpecialType != SpecialType.System_Object && type != stopAt)
            {
                foreach (var member in type.GetMembers())
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (member.IsImplicitlyDeclared || member.IsStatic)
                    {
                        continue;
                    }
                    if (member.IsOrdinaryMethod() || member.Kind == SymbolKind.Field || member.Kind == SymbolKind.Property)
                    {
                        if (member.IsAccessibleWithin(within))
                        {
                            var completionData = SymbolCompletionItem.CreateWithSymbolId(
                                member.Name,
                                new [] { member },
                                CompletionItemRules.Default,
                                context.Position,
                                properties: pDict
                                );

                            if (addedSymbols.Contains(completionData.DisplayText))
                            {
                                continue;
                            }
                            addedSymbols.Add(completionData.DisplayText);
                            context.AddItem(completionData);
                        }
                    }
                }
                type = type.BaseType;
            }
        }
コード例 #7
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var options = context.Options;
            var cancellationToken = context.CancellationToken;

            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            if (!tree.IsEntirelyWithinCrefSyntax(position, cancellationToken))
            {
                return;
            }

            var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDocumentationComments: true)
                            .GetPreviousTokenIfTouchingWord(position);

            // To get a Speculative SemanticModel (which is much faster), we need to 
            // walk up to the node the DocumentationTrivia is attached to.
            var parentNode = token.Parent.FirstAncestorOrSelf<DocumentationCommentTriviaSyntax>()?.ParentTrivia.Token.Parent;
            _testSpeculativeNodeCallbackOpt?.Invoke(parentNode);
            if (parentNode == null)
            {
                return;
            }

            var semanticModel = await document.GetSemanticModelForNodeAsync(
                parentNode, cancellationToken).ConfigureAwait(false);

            var symbols = GetSymbols(token, semanticModel, cancellationToken);

            symbols = symbols.FilterToVisibleAndBrowsableSymbols(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation);

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

            context.IsExclusive = true;

            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
            var span = GetCompletionItemSpan(text, position);

            var items = CreateCompletionItems(document.Project.Solution.Workspace, semanticModel, symbols, token, span);
            context.AddItems(items);
        }
コード例 #8
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var cancellationToken = context.CancellationToken;

            var showSpeculativeT = await document.IsValidContextForDocumentOrLinkedDocumentsAsync(
                (doc, ct) => ShouldShowSpeculativeTCompletionItemAsync(doc, position, ct),
                cancellationToken).ConfigureAwait(false);

            if (showSpeculativeT)
            {
                var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                const string T = nameof(T);
                context.AddItem(CommonCompletionItem.Create(T, glyph: Glyph.TypeParameter));
            }
        }
コード例 #9
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var cancellationToken = context.CancellationToken;

            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            if (tree.IsInNonUserCode(position, cancellationToken))
            {
                return;
            }

            var targetToken = tree
                .FindTokenOnLeftOfPosition(position, cancellationToken)
                .GetPreviousTokenIfTouchingWord(position);

            if (targetToken.IsKind(SyntaxKind.AliasKeyword) && targetToken.Parent.IsKind(SyntaxKind.ExternAliasDirective))
            {
                var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
                var aliases = compilation.ExternalReferences.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);

                    aliases.RemoveRange(usedAliases);
                    aliases.Remove(MetadataReferenceProperties.GlobalAlias);

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

                    foreach (var alias in aliases)
                    {
                        context.AddItem(CommonCompletionItem.Create(alias, glyph: Glyph.Namespace));
                    }
                }
            }
        }
コード例 #10
0
        void GetFormatCompletionData(Microsoft.CodeAnalysis.Completion.CompletionContext engine, SemanticModel semanticModel, InvocationExpressionSyntax invocationExpression, int formatArgument, char currentChar)
        {
            var symbolInfo = semanticModel.GetSymbolInfo(invocationExpression);
            var method     = symbolInfo.Symbol as IMethodSymbol ?? symbolInfo.CandidateSymbols.OfType <IMethodSymbol> ().FirstOrDefault();
            var ma         = invocationExpression.Expression as MemberAccessExpressionSyntax;

            if (ma != null && ma.Name.ToString() == "ToString")
            {
                if (method == null || currentChar != '"')
                {
                    return;
                }
                if (method != null)
                {
                    GetFormatCompletionForType(engine, method.ContainingType);
                }
                return;
            }
            else
            {
                if (method == null || currentChar != ':')
                {
                    return;
                }
                ExpressionSyntax         fmtArgumets;
                IList <ExpressionSyntax> args;
                if (FormatStringHelper.TryGetFormattingParameters(semanticModel, invocationExpression, out fmtArgumets, out args, null))
                {
                    ITypeSymbol type = null;
                    if (formatArgument + 1 < args.Count)
                    {
                        var invokeArgument = semanticModel.GetSymbolInfo(args [formatArgument + 1]);
                        if (invokeArgument.Symbol != null)
                        {
                            type = invokeArgument.Symbol.GetReturnType();
                        }
                    }
                    GetFormatCompletionForType(engine, type);
                }
            }
        }
コード例 #11
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var cancellationToken = context.CancellationToken;

            // the provider might be invoked in non-interactive context:
            Workspace ws;
            SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
            if (Workspace.TryGetWorkspace(sourceText.Container, out ws))
            {
                var workspace = ws as InteractiveWorkspace;
                if (workspace != null)
                {
                    var window = workspace.Window;
                    var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                    if (await ShouldDisplayCommandCompletionsAsync(tree, position, cancellationToken).ConfigureAwait(false))
                    {
                        IInteractiveWindowCommands commands = window.GetInteractiveCommands();
                        if (commands != null)
                        {
                            foreach (var command in commands.GetCommands())
                            {
                                foreach (var commandName in command.Names)
                                {
                                    string completion = GetCompletionString(commandName);
                                    context.AddItem(CommonCompletionItem.Create(
                                        completion, description: command.Description.ToSymbolDisplayParts(), glyph: Glyph.Intrinsic));
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #12
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);

            var tree = ctx.SyntaxTree;

            if (tree.IsInNonUserCode(context.Position, cancellationToken))
            {
                return;
            }

            var token = tree.FindTokenOnLeftOfPosition(context.Position, cancellationToken);

            if (token.IsKind(SyntaxKind.DotToken) || token.IsMandatoryNamedParameterPosition())
            {
                return;
            }

            // 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;
                }
                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(context.Position, model, cancellationToken).ConfigureAwait(false);

                if (!IsReachable(model, type, token.Parent))
                {
                    var pDict         = ImmutableDictionary <string, string> .Empty;
                    var displayString = CSharpAmbience.SafeMinimalDisplayString(type, model, context.Position, SymbolDisplayFormat.CSharpErrorMessageFormat);
                    var item          = CompletionItem.Create(displayString, properties: pDict, tags: tags);
                    context.AddItem(item.WithRules(item.Rules.WithMatchPriority(int.MaxValue)));
                }

                foreach (IFieldSymbol field in type.GetMembers().OfType <IFieldSymbol> ())
                {
                    if (field.DeclaredAccessibility == Accessibility.Public && (field.IsConst || field.IsStatic))
                    {
                        var displayString = CSharpAmbience.SafeMinimalDisplayString(alias ?? field.Type, model, context.Position, SymbolDisplayFormat.CSharpErrorMessageFormat) + "." + field.Name;
                        var pDict         = ImmutableDictionary <string, string> .Empty;
                        context.AddItem(CompletionItem.Create(displayString, properties: pDict, tags: tags));
                    }
                }
            }
        }
コード例 #13
0
ファイル: CompletionProvider.cs プロジェクト: Rickinio/roslyn
 /// <summary>
 /// Implement to contribute <see cref="CompletionItem"/>'s and other details to a <see cref="CompletionList"/>
 /// </summary>
 public abstract Task ProvideCompletionsAsync(CompletionContext context);
コード例 #14
0
 private static bool HasAnyItems(CompletionContext cc)
 {
     return(cc.Items.Count > 0 || cc.SuggestionModeItem != null);
 }
コード例 #15
0
 void GenerateGuidFormatitems(Microsoft.CodeAnalysis.Completion.CompletionContext completionContext)
 {
     completionContext.AddItems(guidFormatItems);
 }
コード例 #16
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

            var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, model, position, cancellationToken);

            var syntaxTree = ctx.SyntaxTree;

            if (syntaxTree.IsInNonUserCode(position, cancellationToken) ||
                syntaxTree.IsPreProcessorDirectiveContext(position, cancellationToken))
            {
                return;
            }
            if (!syntaxTree.IsRightOfDotOrArrowOrColonColon(
                    position,
                    syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position),
                    cancellationToken))
            {
                return;
            }
            var ma = ctx.LeftToken.Parent as MemberAccessExpressionSyntax;

            if (ma == null)
            {
                return;
            }

            var symbolInfo = model.GetSymbolInfo(ma.Expression);

            if (symbolInfo.Symbol == null)
            {
                return;
            }

            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(context, model, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, 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(context, model, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, 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(context, model, ma.Expression, type, model.GetTypeInfo(isExpr.Left).Type, within, addedSymbols, cancellationToken);
                            }
                        }
                    }
                }

                loop : ancestor = ancestor.Parent;
            }
        }
コード例 #17
0
        private async Task<IEnumerable<CompletionItem>> GetNameColonItemsAsync(
            CompletionContext context, SemanticModel semanticModel, SyntaxToken token, AttributeSyntax attributeSyntax, ISet<string> existingNamedParameters)
        {
            var parameterLists = GetParameterLists(semanticModel, context.Position, attributeSyntax, context.CancellationToken);
            parameterLists = parameterLists.Where(pl => IsValid(pl, existingNamedParameters));

            var text = await semanticModel.SyntaxTree.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
            return from pl in parameterLists
                   from p in pl
                   where !existingNamedParameters.Contains(p.Name)
                   select SymbolCompletionItem.Create(
                       displayText: p.Name.ToIdentifierToken().ToString() + ColonString,
                       insertionText: null,
                       symbol: p,
                       contextPosition: token.SpanStart,
                       sortText: p.Name,
                       rules: CompletionItemRules.Default);
        }
コード例 #18
0
 void GenerateTimeSpanFormatitems(Microsoft.CodeAnalysis.Completion.CompletionContext completionContext)
 {
     completionContext.AddItems(timeSpanFormatItems);
 }
コード例 #19
0
 /// <summary>
 /// Implement to contribute <see cref="CompletionItem"/>'s and other details to a <see cref="CompletionList"/>
 /// </summary>
 public abstract Task ProvideCompletionsAsync(CompletionContext context);
コード例 #20
0
 void AddFormatCompletionData(Microsoft.CodeAnalysis.Completion.CompletionContext context, bool isVerbatimString)
 {
     context.AddItems(isVerbatimString ? verbatimFormatItems : formatItems);
 }
コード例 #21
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var options = context.Options;
            var cancellationToken = context.CancellationToken;

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

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

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

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

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

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

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

            var symbol = semanticModel.GetSymbolInfo(name, cancellationToken).Symbol as ITypeSymbol;
            if (symbol?.TypeKind != TypeKind.Interface)
            {
                return;
            }

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

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

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

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

                var item = SymbolCompletionItem.Create(
                    displayText,
                    insertionText: insertionText,
                    symbol: member,
                    contextPosition: position,
                    rules: CompletionItemRules.Default);
                item = item.AddProperty(InsertionTextOnOpenParen, member.Name);

                context.AddItem(item);
            }
        }
コード例 #22
0
 public override async Task ProvideCompletionsAsync(CompletionContext context)
 {
     var text = await context.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
     var items = GetItems(text, context.Document, context.Position, context.Trigger, context.CancellationToken);
     context.AddItems(items);
 }
コード例 #23
0
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            try
            {
                var document = context.Document;
                var position = context.Position;
                var options = context.Options;
                var cancellationToken = context.CancellationToken;

                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                if (tree.IsInNonUserCode(position, cancellationToken))
                {
                    return;
                }

                var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken);
                if (token.IsMandatoryNamedParameterPosition())
                {
                    return;
                }

                var typeInferenceService = document.GetLanguageService<ITypeInferenceService>();
                Contract.ThrowIfNull(typeInferenceService, nameof(typeInferenceService));

                var span = new TextSpan(position, 0);
                var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);
                var type = typeInferenceService.InferType(semanticModel, position,
                    objectAsDefault: true,
                    cancellationToken: cancellationToken);

                // If we have a Nullable<T>, unwrap it.
                if (type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                {
                    type = type.GetTypeArguments().FirstOrDefault();

                    if (type == null)
                    {
                        return;
                    }
                }

                if (type.TypeKind != TypeKind.Enum)
                {
                    type = GetCompletionListType(type, semanticModel.GetEnclosingNamedType(position, cancellationToken), semanticModel.Compilation);
                    if (type == null)
                    {
                        return;
                    }
                }

                if (!type.IsEditorBrowsable(options.GetOption(CompletionOptions.HideAdvancedMembers, semanticModel.Language), semanticModel.Compilation))
                {
                    return;
                }

                // Does type have any aliases?
                ISymbol alias = await type.FindApplicableAlias(position, semanticModel, cancellationToken).ConfigureAwait(false);

                var displayService = document.GetLanguageService<ISymbolDisplayService>();
                var displayText = alias != null
                    ? alias.Name
                    : displayService.ToMinimalDisplayString(semanticModel, position, type);

                var workspace = document.Project.Solution.Workspace;
                var text = await semanticModel.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

                var item = SymbolCompletionItem.Create(
                    displayText: displayText,
                    insertionText: null,
                    span: context.DefaultItemSpan,
                    symbol: alias ?? type,
                    descriptionPosition: position,
                    matchPriority: MatchPriority.Preselect,
                    rules: s_rules);

                context.AddItem(item);
            }
            catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
コード例 #24
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            var document          = context.Document;
            var position          = context.Position;
            var cancellationToken = context.CancellationToken;

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

            var workspace = document.Project.Solution.Workspace;
            var ctx       = CSharpSyntaxContext.CreateContext(workspace, semanticModel, position, cancellationToken);

            if (context.Trigger.Character == '\\')
            {
                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;
                    }

                    if (SemanticHighlightingVisitor <string> .IsRegexMatchMethod(symbolInfo))
                    {
                        if (((ArgumentListSyntax)argument.Parent).Arguments [1] != argument)
                        {
                            return;
                        }
                        AddFormatCompletionData(context, argument.Expression.ToString() [0] == '@');
                        return;
                    }
                    if (SemanticHighlightingVisitor <string> .IsRegexConstructor(symbolInfo))
                    {
                        if (((ArgumentListSyntax)argument.Parent).Arguments [0] != argument)
                        {
                            return;
                        }
                        AddFormatCompletionData(context, argument.Expression.ToString() [0] == '@');
                        return;
                    }
                }
            }
            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")
                    {
                        foreach (var grp in GetGroups(ctx, symbolInfo.Symbol))
                        {
                            context.AddItem(FormatItemCompletionProvider.CreateCompletionItem("Groups[\"" + grp + "\"]", null, null));
                        }
                    }
                }
            }
        }
コード例 #25
0
 private static async Task<CompletionContext> GetProviderCompletionsAsync(
     CompletionProvider provider,
     Document document,
     int position,
     TextSpan defaultFilterSpan,
     CompletionTrigger triggerInfo,
     OptionSet options,
     CancellationToken cancellationToken)
 {
     var context = new CompletionContext(provider, document, position, defaultFilterSpan, triggerInfo, options, cancellationToken);
     await provider.ProvideCompletionsAsync(context).ConfigureAwait(false);
     return context;
 }
コード例 #26
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            try {
                var document          = context.Document;
                var position          = context.Position;
                var cancellationToken = context.CancellationToken;

                var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

                var tree = model.SyntaxTree;
                if (tree.IsInNonUserCode(context.Position, cancellationToken))
                {
                    return;
                }

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

                var startLineNumber = text.Lines.IndexOf(context.Position);

                // modifiers* override modifiers* type? |
                //DeclarationModifiers modifiers;
                var token = tree.FindTokenOnLeftOfPosition(context.Position, cancellationToken);
                if (token.Parent == null)
                {
                    return;
                }

                // don't show up in that case: int { $$
                if (token.Parent.IsKind(SyntaxKind.SkippedTokensTrivia))
                {
                    return;
                }

                var im = token.Parent.Ancestors().OfType <IncompleteMemberSyntax> ().FirstOrDefault();
                if (im != null)
                {
                    var token2 = tree.FindTokenOnLeftOfPosition(im.Span.Start, cancellationToken);
                    if (token2.Parent.IsKind(SyntaxKind.SkippedTokensTrivia))
                    {
                        return;
                    }
                }

                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;
                }

                var startToken = token.GetPreviousTokenIfTouchingWord(position);
                TryDetermineReturnType(startToken, model, cancellationToken, out ITypeSymbol returnType, out SyntaxToken tokenBeforeReturnType);
                if (returnType == null)
                {
                    var enclosingType = model.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol;
                    if (enclosingType != null && (startToken.IsKind(SyntaxKind.OpenBraceToken) || startToken.IsKind(SyntaxKind.CloseBraceToken) || startToken.IsKind(SyntaxKind.SemicolonToken)))
                    {
                        CreateCompletionData(context, model, position, returnType, Accessibility.NotApplicable, startToken, tokenBeforeReturnType, false, cancellationToken);
                        return;
                    }
                }

                if (!TryDetermineModifiers(ref tokenBeforeReturnType, text, startLineNumber, out Accessibility seenAccessibility /*, out modifiers*/) ||
                    !TryCheckForTrailingTokens(tree, text, startLineNumber, position, cancellationToken))
                {
                    return;
                }

                CreateCompletionData(context, model, position, returnType, seenAccessibility, startToken, tokenBeforeReturnType, true, cancellationToken);
            } catch (OperationCanceledException) {
                return;
            }
        }
コード例 #27
0
        public override async Task ProvideCompletionsAsync(Microsoft.CodeAnalysis.Completion.CompletionContext context)
        {
            try {
                var document          = context.Document;
                var position          = context.Position;
                var cancellationToken = context.CancellationToken;

                var model = await document.GetSemanticModelForSpanAsync(new TextSpan (position, 0), cancellationToken).ConfigureAwait(false);

                var tree = model.SyntaxTree;
                if (tree.IsInNonUserCode(context.Position, cancellationToken))
                {
                    return;
                }

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

                var startLineNumber = text.Lines.IndexOf(context.Position);

                // modifiers* override modifiers* type? |
                //DeclarationModifiers modifiers;
                var token = tree.FindTokenOnLeftOfPosition(context.Position, cancellationToken);
                if (token.Parent == null)
                {
                    return;
                }

                // don't show up in that case: int { $$
                if (token.Parent.IsKind(SyntaxKind.SkippedTokensTrivia))
                {
                    return;
                }

                var im = token.Parent.Ancestors().OfType <IncompleteMemberSyntax> ().FirstOrDefault();
                if (im != null)
                {
                    var token2 = tree.FindTokenOnLeftOfPosition(im.Span.Start, cancellationToken);
                    if (token2.Parent.IsKind(SyntaxKind.SkippedTokensTrivia))
                    {
                        return;
                    }
                }

                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;
                }

                var startToken = token.GetPreviousTokenIfTouchingWord(position);

                // We're marking the context as exclusive, to resolve the
                // regression in the new editor that appeared since introducing
                // Roslyn's provider mechanism. The actual override completion
                // provider took precedence and therefore this one was ignored.
                // We submitted a PR for roslyn, that allows multiple providers,
                // marked as exclusive, to render suggestions.
                // See: https://github.com/dotnet/roslyn/pull/36088
                //
                // Important note, though, we should only set exclusivity when
                // we are actually competing with an override provider - that
                // is, if the token before this one is the override keyword. If
                // it's not, we're not competing, and therefore shouldn't set
                // this to true, as we'll be the ones stealing the spotlight.
                context.IsExclusive = startToken.IsKind(SyntaxKind.OverrideKeyword);

                TryDetermineReturnType(startToken, model, cancellationToken, out ITypeSymbol returnType, out SyntaxToken tokenBeforeReturnType);
                if (returnType == null)
                {
                    var enclosingType = model.GetEnclosingSymbol(position, cancellationToken) as INamedTypeSymbol;
                    if (enclosingType != null && (startToken.IsKind(SyntaxKind.OpenBraceToken) || startToken.IsKind(SyntaxKind.CloseBraceToken) || startToken.IsKind(SyntaxKind.SemicolonToken)))
                    {
                        CreateCompletionData(context, model, position, returnType, Accessibility.NotApplicable, startToken, tokenBeforeReturnType, false, cancellationToken);
                        return;
                    }
                }

                if (!TryDetermineModifiers(ref tokenBeforeReturnType, text, startLineNumber, out Accessibility seenAccessibility /*, out modifiers*/) ||
                    !TryCheckForTrailingTokens(tree, text, startLineNumber, position, cancellationToken))
                {
                    return;
                }

                CreateCompletionData(context, model, position, returnType, seenAccessibility, startToken, tokenBeforeReturnType, true, cancellationToken);
            } catch (OperationCanceledException) {
                return;
            }
        }
        public override async Task ProvideCompletionsAsync(CompletionContext context)
        {
            var document = context.Document;
            var position = context.Position;
            var cancellationToken = context.CancellationToken;

            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            // first try to get the #r string literal token.  If we couldn't, then we're not in a #r
            // reference directive and we immediately bail.
            SyntaxToken stringLiteral;
            if (!TryGetStringLiteralToken(tree, position, out stringLiteral, cancellationToken))
            {
                return;
            }

            var textChangeSpan = this.GetTextChangeSpan(stringLiteral, position);

            var gacHelper = new GlobalAssemblyCacheCompletionHelper(this, textChangeSpan, itemRules: s_rules);
            var text = await document.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
            var snapshot = text.FindCorrespondingEditorTextSnapshot();
            if (snapshot == null)
            {
                // Passing null to GetFileSystemDiscoveryService raises an exception.
                // Instead, return here since there is no longer snapshot for this document.
                return;
            }

            var referenceResolver = document.Project.CompilationOptions.MetadataReferenceResolver;

            // TODO: https://github.com/dotnet/roslyn/issues/5263
            // Avoid dependency on a specific resolvers.
            // The search paths should be provided by specialized workspaces:
            // - InteractiveWorkspace for interactive window 
            // - ScriptWorkspace for loose .csx files (we don't have such workspace today)
            ImmutableArray<string> searchPaths;

            RuntimeMetadataReferenceResolver rtResolver;
            WorkspaceMetadataFileReferenceResolver workspaceResolver;

            if ((rtResolver = referenceResolver as RuntimeMetadataReferenceResolver) != null)
            {
                searchPaths = rtResolver.PathResolver.SearchPaths;
            }
            else if ((workspaceResolver = referenceResolver as WorkspaceMetadataFileReferenceResolver) != null)
            {
                searchPaths = workspaceResolver.PathResolver.SearchPaths;
            }
            else
            {
                return;
            }

            var fileSystemHelper = new FileSystemCompletionHelper(
                this, textChangeSpan,
                GetFileSystemDiscoveryService(snapshot),
                Glyph.OpenFolder,
                Glyph.Assembly,
                searchPaths: searchPaths,
                allowableExtensions: new[] { ".dll", ".exe" },
                exclude: path => path.Contains(","),
                itemRules: s_rules);

            var pathThroughLastSlash = GetPathThroughLastSlash(stringLiteral, position);

            var documentPath = document.Project.IsSubmission ? null : document.FilePath;
            context.AddItems(gacHelper.GetItems(pathThroughLastSlash, documentPath));
            context.AddItems(fileSystemHelper.GetItems(pathThroughLastSlash, documentPath));
        }
コード例 #29
0
        private async Task<ImmutableArray<CompletionItem>> GetNameEqualsItemsAsync(
            CompletionContext context, SemanticModel semanticModel,
            SyntaxToken token, AttributeSyntax attributeSyntax, ISet<string> existingNamedParameters)
        {
            var attributeNamedParameters = GetAttributeNamedParameters(semanticModel, context.Position, attributeSyntax, context.CancellationToken);
            var unspecifiedNamedParameters = attributeNamedParameters.Where(p => !existingNamedParameters.Contains(p.Name));

            var text = await semanticModel.SyntaxTree.GetTextAsync(context.CancellationToken).ConfigureAwait(false);
            var q = from p in attributeNamedParameters
                    where !existingNamedParameters.Contains(p.Name)
                    select SymbolCompletionItem.Create(
                       displayText: p.Name.ToIdentifierToken().ToString() + SpaceEqualsString,
                       insertionText: null,
                       symbol: p,
                       contextPosition: token.SpanStart,
                       sortText: p.Name,
                       rules: CompletionItemRules.Default);
            return q.ToImmutableArray();
        }