Пример #1
0
        static async Task <CompletionModel> ComputeModelAsync(
            RoslynCompilationWorkspace compilationWorkspace,
            SourceText text,
            int position,
            CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();

            var completions = await compilationWorkspace.CompletionService.GetCompletionsAsync(
                compilationWorkspace.GetSubmissionDocument(text.Container),
                position,
                options : compilationWorkspace.Options,
                cancellationToken : ct).ConfigureAwait(false);

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

            // TODO: Default tracking span
            //var trackingSpan = await _completionService.GetDefaultTrackingSpanAsync(_documentOpt, _subjectBufferCaretPosition, cancellationToken).ConfigureAwait(false);

            return(CompletionModel.CreateModel(
                       text,
                       default(TextSpan),
                       completions.Items));
        }
Пример #2
0
        public async Task <SignatureHelpViewModel> ComputeSignatureHelpAsync(
            SourceText sourceText,
            LinePosition linePosition,
            CancellationToken cancellationToken)
        {
            var signatureHelp = new SignatureHelpViewModel();
            var position      = sourceText.Lines.GetPosition(linePosition);

            if (position <= 0)
            {
                return(signatureHelp);
            }

            var document = compilationWorkspace.GetSubmissionDocument(sourceText.Container);
            var root     = await document.GetSyntaxRootAsync(cancellationToken);

            var syntaxToken = root.FindToken(position);

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var currentNode = syntaxToken.Parent;

            do
            {
                var creationExpression = currentNode as ObjectCreationExpressionSyntax;
                if (creationExpression != null && creationExpression.ArgumentList.Span.Contains(position))
                {
                    return(CreateMethodGroupSignatureHelp(
                               creationExpression,
                               creationExpression.ArgumentList,
                               position,
                               semanticModel));
                }

                var invocationExpression = currentNode as InvocationExpressionSyntax;
                if (invocationExpression != null && invocationExpression.ArgumentList.Span.Contains(position))
                {
                    return(CreateMethodGroupSignatureHelp(
                               invocationExpression.Expression,
                               invocationExpression.ArgumentList,
                               position,
                               semanticModel));
                }

                currentNode = currentNode.Parent;
            } while (currentNode != null);

            return(signatureHelp);
        }
Пример #3
0
        /// <summary>
        /// Start a new ModelComputation. Completion computations and filtering tasks will be chained to this
        /// ModelComputation, and when the chain is complete the view will be notified via the
        /// OnCompletionModelUpdated handler.
        ///
        /// The latest immutable CompletionModel can be accessed at any time. Some parts of the code may choose
        /// to wait on it to arrive synchronously.
        ///
        /// Inspired by similar method in Completion/Controller.cs in Roslyn.
        /// </summary>
        void StartNewComputation(
            int position,
            CompletionRules rules,
            bool filterItems)
        {
            computation = new ModelComputation <CompletionModel> (
                OnCompletionModelUpdated,
                Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.Completion.PrioritizedTaskScheduler.AboveNormalInstance);

            ComputeModel(position);

            if (filterItems)
            {
                var document = compilationWorkspace.GetSubmissionDocument(sourceTextContent.Container);
                FilterModel(CompletionHelper.GetHelper(document));
            }
        }
Пример #4
0
        public async Task <HoverViewModel> ProvideHoverAsync(
            SourceText sourceText,
            LinePosition linePosition,
            CancellationToken cancellationToken)
        {
            var hover    = new HoverViewModel();
            var position = sourceText.Lines.GetPosition(linePosition);

            if (position <= 0)
            {
                return(hover);
            }

            var document = compilationWorkspace.GetSubmissionDocument(sourceText.Container);
            var root     = await document.GetSyntaxRootAsync(cancellationToken);

            var syntaxToken = root.FindToken(position);

            var expression = syntaxToken.Parent as ExpressionSyntax;

            if (expression == null)
            {
                return(hover);
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            var symbolInfo = semanticModel.GetSymbolInfo(expression);

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

            hover.Contents = new [] { symbolInfo.Symbol.ToDisplayString(Constants.SymbolDisplayFormat) };
            hover.Range    = syntaxToken.GetLocation().GetLineSpan().Span;

            return(hover);
        }
Пример #5
0
        /// <summary>
        /// Filter currentCompletionList according to the current filter text. Roslyn's completion does not
        /// handle this automatically.
        /// </summary>
        static async Task <CompletionModel> FilterModelAsync(
            RoslynCompilationWorkspace compilationWorkspace,
            SourceText sourceText,
            CompletionModel model,
            CompletionHelper helper,
            CancellationToken ct)
        {
            if (model == null)
            {
                return(null);
            }

            CompletionItem bestFilterMatch      = null;
            var            bestFilterMatchIndex = 0;

            var document = compilationWorkspace.GetSubmissionDocument(sourceText.Container);
            var newFilteredCompletions = new List <CompletionItem> ();

            foreach (var item in model.TotalItems)
            {
                var completion = item;
                // TODO: Better range checking on delete before queuing up filtering (see TODO in HandleChange)
                if (completion.Span.Start > sourceText.Length)
                {
                    continue;
                }

                var filterText = GetFilterText(sourceText, completion);

                // CompletionRules.MatchesFilterText seems to always return false when filterText is
                // empty.
                if (filterText != String.Empty && !helper.MatchesPattern(
                        completion.FilterText,
                        filterText,
                        CultureInfo.CurrentCulture))
                {
                    continue;
                }

                var itemDetail = String.Empty;

                var symbols = await SymbolCompletionItem.GetSymbolsAsync(completion, document, ct)
                              .ConfigureAwait(false);

                var overloads = symbols.OfType <IMethodSymbol> ().ToArray();
                if (overloads.Length > 0)
                {
                    itemDetail = overloads [0].ToMonacoSignatureString();

                    if (overloads.Length > 1)
                    {
                        itemDetail += $" (+ {overloads.Length - 1} overload(s))";
                    }
                }

                completion = completion.AddProperty(itemDetailPropertyName, itemDetail);

                newFilteredCompletions.Add(completion);

                if (bestFilterMatch == null || helper.CompareItems(
                        completion,
                        bestFilterMatch,
                        filterText,
                        CultureInfo.CurrentCulture) > 0)
                {
                    bestFilterMatch      = completion;
                    bestFilterMatchIndex = newFilteredCompletions.Count - 1;
                }
            }

            if (newFilteredCompletions.Count == 0)
            {
                return(null);
            }

            return(model
                   .WithFilteredItems(newFilteredCompletions)
                   .WithSelectedItem(bestFilterMatch, bestFilterMatchIndex)
                   .WithText(sourceText));
        }