コード例 #1
0
 private void StartOrEndBold(StringBuilder stringBuilder, MarkupKind markupKind)
 {
     if (markupKind == MarkupKind.Markdown)
     {
         stringBuilder.Append("**");
     }
 }
コード例 #2
0
        public void Execute(IToolServices toolService)
        {
            Position   position = toolService.PointerOverPosition;
            MarkupInfo markups  = toolService.Node.Markups;

            MarkupKind markupKindOnPosition = markups.RemoveMarkupOnPosition(position);

            if (SequenceMarkup == SequenceMarkupKind.Letter)
            {
                char letter = markups.GetSmallestUnusedLetter();
                if (letter != '0' && markupKindOnPosition != MarkupKind.Label)
                {
                    markups.AddMarkup <Label>(new Label(position, letter.ToString()));
                }
            }
            else
            {
                int number = markups.GetSmallestUnusedNumber();
                if (markupKindOnPosition != MarkupKind.Label)
                {
                    markups.AddMarkup <Label>(new Label(position, number.ToString()));
                }
            }

            _shadows = toolService.Node.Markups.FillSequenceShadowMap(toolService.GameTree.BoardSize, SequenceMarkup);
        }
コード例 #3
0
        public object Initialize(JToken arg)
        {
            /* We want to support the hover capability. When we get a hover request we will respond
             * with the appropriate text.
             * Check the client's declared capabilities to identify what hover format the client expects
             * before returning a hover response from the server. Stash away the expected format for use
             * when composing the hover response.
             */
            var b = arg.ToObject <InitializeParams>();

            MarkupKind[] m = b.Capabilities.TextDocument.Hover.ContentFormat;

            // in the case of Visual Studio, this is what I am observing. Capturing that as an assertion
            // just in case things change.
            System.Diagnostics.Debug.Assert(m != null &&
                                            m.Length == 1 &&
                                            m[0] == MarkupKind.PlainText);

            HoverContentFormat = m[0];

            /*
             *"hover" is the only capability that we wil report back as supported.
             */
            var capabilities = new ServerCapabilities();

            capabilities.HoverProvider = true;

            var result = new InitializeResult();

            result.Capabilities = capabilities;

            Initialized?.Invoke(this, new EventArgs());

            return(result);
        }
コード例 #4
0
ファイル: LanguageServer.cs プロジェクト: pvlakshm/LSP
        /*
         * We could potentially provide a variety of features here.
         * But I will keep this simple. I unpack the parameters to extract the file name and hover position
         * and use that as the payload for my remote method call.
         */
        internal void OnTextDocumentHovered(TextDocumentPositionParams parameter, MarkupKind m)
        {
            string markupkind = m.ToString();
            string msg        = string.Empty;

            if (m == MarkupKind.PlainText)
            {
                msg = "The bar LSP - " +
                      " File: " + parameter.TextDocument.Uri.AbsolutePath +
                      " Line: " + parameter.Position.Line +
                      " Character: " + parameter.Position.Character +
                      " HoverContentFormat: " + markupkind;
            }
            else if (m == MarkupKind.Markdown)
            {
                // should never be taken in Visual Studio as per my observation. See assertion in
                // LanguageServerTarget.Initialize().
                // Even if we force this path via the debugger, the below text is not interpreted
                // as markdown when displayed in VS.
                msg = "The bar LSP - " +
                      " **File:** " + parameter.TextDocument.Uri.AbsolutePath +
                      " _Line:_ " + parameter.Position.Line +
                      " _Character:_ " + parameter.Position.Character +
                      " **HoverContentFormat:** " + markupkind;
            }
            else
            {
                msg = "The bar LSP - " +
                      " HoverContentFormat: " + "unknown.";
                System.Diagnostics.Debug.Fail("unknown hover content format"); // just for me to break in and attach the debugger.
            }

            // Send a informational message
            this.ShowMessage(msg, MessageType.Info);
        }
コード例 #5
0
        public void Execute(IToolServices toolService)
        {
            Position   position = toolService.PointerOverPosition;
            MarkupInfo markups  = toolService.Node.Markups;

            MarkupKind markupKindOnPosition = markups.RemoveMarkupOnPosition(position);

            // If the removed markup is the same as the new one than do not add anything.
            if (IsMarkupEqual(SimpleMarkup, markupKindOnPosition))
            {
                return;
            }

            if (SimpleMarkup == SimpleMarkupKind.Circle)
            {
                markups.AddMarkup <Circle>(new Circle(position));
            }
            if (SimpleMarkup == SimpleMarkupKind.Cross)
            {
                markups.AddMarkup <Cross>(new Cross(position));
            }
            if (SimpleMarkup == SimpleMarkupKind.Square)
            {
                markups.AddMarkup <Square>(new Square(position));
            }
            if (SimpleMarkup == SimpleMarkupKind.Triangle)
            {
                markups.AddMarkup <Triangle>(new Triangle(position));
            }
        }
コード例 #6
0
        /// <summary>
        /// Returns information about the item at the specified position as Hover information.
        /// Returns null if some parameters are unspecified (null),
        /// or if the specified position is not a valid position within the currently processed file content,
        /// or if no token exists at the specified position.
        /// </summary>
        public static Hover?HoverInformation(
            this FileContentManager file,
            CompilationUnit compilation,
            Position?position,
            MarkupKind format = MarkupKind.PlainText)
        {
            Hover?GetHover(string?info) => info == null ? null : new Hover
            {
                Contents = new MarkupContent {
                    Kind = format, Value = info
                },
                Range = new Lsp.Range {
                    Start = position?.ToLsp(), End = position?.ToLsp()
                }
            };

            var markdown   = format == MarkupKind.Markdown;
            var symbolInfo = file?.TryGetQsSymbolInfo(position, false, out var _);

            if (file is null || symbolInfo == null || compilation == null || position is null)
            {
                return(null);
            }

            if (symbolInfo.UsedLiterals.Any())
            {
                return(GetHover(symbolInfo.UsedLiterals.Single().LiteralInfo(markdown)));
            }
            var locals = compilation.TryGetLocalDeclarations(file, position, out var cName, includeDeclaredAtPosition: true);
            var nsName = cName?.Namespace ?? file.TryGetNamespaceAt(position);

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

            // TODO: add hover for functor generators and functor applications
            // TODO: add hover for new array expr ?
            // TODO: add nested types - requires dropping the .Single and actually resolving to the closest match!
            return(GetHover(symbolInfo.UsedVariables.Any()
                ? compilation.GlobalSymbols.VariableInfo(locals, nsName, file.FileName, symbolInfo.UsedVariables.Single(), markdown)
                : symbolInfo.UsedTypes.Any()
                ? compilation.GlobalSymbols.TypeInfo(nsName, file.FileName, symbolInfo.UsedTypes.Single(), markdown)
                : symbolInfo.DeclaredSymbols.Any()
                ? compilation.GlobalSymbols.DeclarationInfo(locals, nsName, file.FileName, symbolInfo.DeclaredSymbols.Single(), markdown)
                : null));
        }
コード例 #7
0
        /// <summary>
        /// Indicates whether the given markups have the same type.
        /// </summary>
        /// <param name="simpleMarkupKind">Markup kind.</param>
        /// <param name="markupKind">Other markup kind.</param>
        /// <returns>True, if the type of given markups equals.</returns>
        private bool IsMarkupEqual(SimpleMarkupKind simpleMarkupKind, MarkupKind markupKind)
        {
            switch (simpleMarkupKind)
            {
            case SimpleMarkupKind.Circle:
                return(markupKind == MarkupKind.Circle);

            case SimpleMarkupKind.Cross:
                return(markupKind == MarkupKind.Cross);

            case SimpleMarkupKind.Square:
                return(markupKind == MarkupKind.Square);

            case SimpleMarkupKind.Triangle:
                return(markupKind == MarkupKind.Triangle);
            }

            return(false);
        }
コード例 #8
0
 /// <summary>
 /// Resolves additional information for the given completion item. Returns the original completion item if no
 /// additional information is available, or if the completion item is no longer valid or accurate.
 /// <para/>
 /// Returns null if any parameter is null or the file given in the original completion request is invalid or
 /// ignored.
 /// </summary>
 internal CompletionItem ResolveCompletion(CompletionItem item, CompletionItemData data, MarkupKind format) =>
 item != null && ValidFileUri(data?.TextDocument?.Uri) && !IgnoreFile(data.TextDocument.Uri)
     ? this.Projects.ResolveCompletion(item, data, format)
     : null;
コード例 #9
0
 /// <summary>
 /// Returns information about the item at the specified position as Hover information.
 /// Returns null if the given file is listed as to be ignored,
 /// or if some parameters are unspecified (null),
 /// or if the specified position is not a valid position within the currently processed file content,
 /// or if no token exists at the specified position at this time.
 /// </summary>
 public Hover HoverInformation(TextDocumentPositionParams param, MarkupKind format = MarkupKind.PlainText) =>
 ValidFileUri(param?.TextDocument?.Uri) && !IgnoreFile(param.TextDocument.Uri) ? this.Projects.HoverInformation(param, format) : null;
コード例 #10
0
 /// <summary>
 /// Returns the signature help information for a call expression if there is such an expression at the specified position.
 /// Returns null if the given file is listed as to be ignored,
 /// or if some parameters are unspecified (null),
 /// or if the specified position is not a valid position within the currently processed file content
 /// or if no call expression exists at the specified position at this time
 /// or if no signature help information can be provided for the call expression at the specified position.
 /// </summary>
 public SignatureHelp SignatureHelp(TextDocumentPositionParams param, MarkupKind format = MarkupKind.PlainText) =>
 ValidFileUri(param?.TextDocument?.Uri) && !IgnoreFile(param.TextDocument.Uri) ? this.Projects.SignatureHelp(param, format) : null;
コード例 #11
0
        /// <summary>
        /// Updates the given completion item with additional information if any is available. The completion item
        /// returned is a reference to the same completion item that was given; the given completion item is mutated
        /// with the additional information.
        /// <para/>
        /// Returns null (and the item is not updated) if any argument is null.
        /// </summary>
        public static CompletionItem ResolveCompletion(
            this CompilationUnit compilation, CompletionItem item, CompletionItemData data, MarkupKind format)
        {
            if (compilation == null || item == null || data == null)
            {
                return(null);
            }
            var documentation = TryGetDocumentation(compilation, data, item.Kind, format == MarkupKind.Markdown);

            if (documentation != null)
            {
                item.Documentation = new MarkupContent {
                    Kind = format, Value = documentation
                }
            }
            ;
            return(item);
        }
コード例 #12
0
 public MarkupContent(MarkupKind kind, string value)
 {
     Kind  = kind;
     Value = value;
 }
コード例 #13
0
        public override bool TryCreateTooltip(
            AggregateBoundAttributeDescription attributeDescriptionInfo,
            MarkupKind markupKind,
            [NotNullWhen(true)] out MarkupContent?tooltipContent)
        {
            if (attributeDescriptionInfo is null)
            {
                throw new ArgumentNullException(nameof(attributeDescriptionInfo));
            }

            var associatedAttributeInfos = attributeDescriptionInfo.DescriptionInfos;

            if (associatedAttributeInfos.Count == 0)
            {
                tooltipContent = null;
                return(false);
            }

            // This generates a markdown description that looks like the following:
            // **ReturnTypeName** SomeTypeName.**SomeProperty**
            //
            // The Summary documentation text with `CrefTypeValues` in code.
            //
            // Additional description infos result in a triple `---` to separate the markdown entries.

            var descriptionBuilder = new StringBuilder();

            for (var i = 0; i < associatedAttributeInfos.Count; i++)
            {
                var descriptionInfo = associatedAttributeInfos[i];

                if (descriptionBuilder.Length > 0)
                {
                    descriptionBuilder.AppendLine();
                    descriptionBuilder.AppendLine("---");
                }

                StartOrEndBold(descriptionBuilder, markupKind);
                if (!TypeNameStringResolver.TryGetSimpleName(descriptionInfo.ReturnTypeName, out var returnTypeName))
                {
                    returnTypeName = descriptionInfo.ReturnTypeName;
                }

                var reducedReturnTypeName = ReduceTypeName(returnTypeName);
                descriptionBuilder.Append(reducedReturnTypeName);
                StartOrEndBold(descriptionBuilder, markupKind);
                descriptionBuilder.Append(" ");
                var tagHelperTypeName        = descriptionInfo.TypeName;
                var reducedTagHelperTypeName = ReduceTypeName(tagHelperTypeName);
                descriptionBuilder.Append(reducedTagHelperTypeName);
                descriptionBuilder.Append(".");
                StartOrEndBold(descriptionBuilder, markupKind);
                descriptionBuilder.Append(descriptionInfo.PropertyName);
                StartOrEndBold(descriptionBuilder, markupKind);

                var documentation = descriptionInfo.Documentation;
                if (!TryExtractSummary(documentation, out var summaryContent))
                {
                    continue;
                }

                descriptionBuilder.AppendLine();
                descriptionBuilder.AppendLine();
                var finalSummaryContent = CleanSummaryContent(summaryContent);
                descriptionBuilder.Append(finalSummaryContent);
            }

            tooltipContent = new MarkupContent
            {
                Kind  = markupKind,
                Value = descriptionBuilder.ToString(),
            };
            return(true);
        }
コード例 #14
0
        /// <summary>
        /// Returns the signature help information for a call expression if there is such an expression at the specified position.
        /// Returns null if some parameters are unspecified (null),
        /// or if the specified position is not a valid position within the currently processed file content,
        /// or if no call expression exists at the specified position at this time,
        /// or if no signature help information can be provided for the call expression at the specified position.
        /// </summary>
        public static SignatureHelp?SignatureHelp(
            this FileContentManager file,
            CompilationUnit compilation,
            Position?position,
            MarkupKind format = MarkupKind.PlainText)
        {
            // getting the relevant token (if any)

            var fragment = file?.TryGetFragmentAt(position, out var _, includeEnd: true);

            if (file is null || position is null || fragment?.Kind == null || compilation == null)
            {
                return(null);
            }
            var fragmentStart = fragment.Range.Start;

            // getting the overlapping call expressions (if any), and determine the header of the called callable

            bool OverlapsWithPosition(Range symRange) => (fragmentStart + symRange).ContainsEnd(position);

            var overlappingEx = fragment.Kind.CallExpressions().Where(ex => ex.Range.IsValue && OverlapsWithPosition(ex.Range.Item)).ToList();

            if (!overlappingEx.Any())
            {
                return(null);
            }
            overlappingEx.Sort((ex1, ex2) => // for nested call expressions, the last expressions (by range) is always the closest one
            {
                var(x, y)  = (ex1.Range.Item, ex2.Range.Item);
                int result = x.Start.CompareTo(y.Start);
                return(result == 0 ? x.End.CompareTo(y.End) : result);
            });

            var nsName = file.TryGetNamespaceAt(position);

            var(method, args) = overlappingEx.Last().Expression is QsExpressionKind <QsExpression, QsSymbol, QsType> .CallLikeExpression c ? (c.Item1, c.Item2) : (null, null);
            if (nsName == null || method == null || args == null)
            {
                return(null);
            }

            // getting the called identifier as well as what functors have been applied to it

            List <QsFunctor> FunctorApplications(ref QsExpression ex)
            {
                var(next, inner) =
                    ex.Expression is QsExpressionKind <QsExpression, QsSymbol, QsType> .AdjointApplication adj ? (QsFunctor.Adjoint, adj.Item) :
                    ex.Expression is QsExpressionKind <QsExpression, QsSymbol, QsType> .ControlledApplication ctl ? (QsFunctor.Controlled, ctl.Item) :
                    (null, null);
                var fs = inner == null ? new List <QsFunctor>() : FunctorApplications(ref inner);

                if (next != null)
                {
                    fs.Add(next);
                }
                ex = inner ?? ex;
                return(fs);
            }

            var functors = FunctorApplications(ref method);
            var id       = method.Expression as QsExpressionKind <QsExpression, QsSymbol, QsType> .Identifier;

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

            // extracting and adapting the relevant information for the called callable

            ResolutionResult <CallableDeclarationHeader> .Found?methodDecl = null;
            if (id.Item1.Symbol is QsSymbolKind <QsSymbol> .Symbol sym)
            {
                methodDecl =
                    compilation.GlobalSymbols.TryResolveAndGetCallable(
                        sym.Item,
                        nsName,
                        file.FileName)
                    as ResolutionResult <CallableDeclarationHeader> .Found;
            }
            else if (id.Item1.Symbol is QsSymbolKind <QsSymbol> .QualifiedSymbol qualSym)
            {
                methodDecl =
                    compilation.GlobalSymbols.TryGetCallable(
                        new QsQualifiedName(qualSym.Item1, qualSym.Item2),
                        nsName,
                        file.FileName)
                    as ResolutionResult <CallableDeclarationHeader> .Found;
            }

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

            var(documentation, argTuple) = (methodDecl.Item.Documentation, methodDecl.Item.ArgumentTuple);
            var nrCtlApplications = functors.Where(f => f.Equals(QsFunctor.Controlled)).Count();

            while (nrCtlApplications-- > 0)
            {
                var ctlQsName = QsLocalSymbol.NewValidName(nrCtlApplications == 0 ? "cs" : $"cs{nrCtlApplications}");
                argTuple = SyntaxGenerator.WithControlQubits(argTuple, QsNullable <Position> .Null, ctlQsName, QsNullable <Range> .Null);
            }

            // now that we now what callable is called we need to check which argument should come next

            bool BeforePosition(Range symRange) => fragmentStart + symRange.End < position;

            IEnumerable <(Range?, string?)> ExtractParameterRanges(
                QsExpression?ex, QsTuple <LocalVariableDeclaration <QsLocalSymbol> > decl)
            {
                var @null = ((Range?)null, (string?)null);

                IEnumerable <(Range?, string?)> SingleItem(string paramName)
                {
                    var arg = ex?.Range == null ? ((Range?)null, paramName)
                        : ex.Range.IsValue ? (ex.Range.Item, paramName)
                        : @null; // no signature help if there are invalid expressions

                    return(new[] { arg });
                }

                if (decl is QsTuple <LocalVariableDeclaration <QsLocalSymbol> > .QsTupleItem dItem)
                {
                    return(SingleItem(dItem.Item.VariableName is QsLocalSymbol.ValidName n ? n.Item : "__argName__"));
                }

                var declItems = decl as QsTuple <LocalVariableDeclaration <QsLocalSymbol> > .QsTuple;
                var exItems   = ex?.Expression as QsExpressionKind <QsExpression, QsSymbol, QsType> .ValueTuple;

                if (declItems == null)
                {
                    return(new[] { @null });
                }
                if (exItems == null && declItems.Item.Length > 1)
                {
                    return(SingleItem(decl.PrintArgumentTuple()));
                }

                var argItems = exItems != null
                    ? exItems.Item.ToImmutableArray <QsExpression?>()
                    : ex == null
                    ? ImmutableArray <QsExpression?> .Empty
                    : ImmutableArray.Create <QsExpression?>(ex);

                return(argItems.AddRange(Enumerable.Repeat <QsExpression?>(null, declItems.Item.Length - argItems.Length))
                       .Zip(declItems.Item, (e, d) => (e, d))
                       .SelectMany(arg => ExtractParameterRanges(arg.Item1, arg.Item2)));
            }

            var callArgs = ExtractParameterRanges(args, argTuple).ToArray();

            if (id == null || callArgs == null || callArgs.Any(item => item.Item2 == null))
            {
                return(null); // no signature help if there are invalid expressions
            }

            // finally we can build the signature help information

            MarkupContent AsMarkupContent(string str) => new MarkupContent
            {
                Kind = format, Value = str
            };
            ParameterInformation AsParameterInfo(string?paramName) => new ParameterInformation
            {
                Label         = paramName,
                Documentation = AsMarkupContent(documentation.ParameterDescription(paramName))
            };

            var signatureLabel = $"{methodDecl.Item.QualifiedName.Name} {argTuple.PrintArgumentTuple()}";

            foreach (var f in functors)
            {
                if (f.IsAdjoint)
                {
                    signatureLabel = $"{Keywords.qsAdjointFunctor.id} {signatureLabel}";
                }
                if (f.IsControlled)
                {
                    signatureLabel = $"{Keywords.qsControlledFunctor.id} {signatureLabel}";
                }
            }

            var doc  = documentation.PrintSummary(format == MarkupKind.Markdown).Trim();
            var info = new SignatureInformation
            {
                Documentation = AsMarkupContent(doc),
                Label         = signatureLabel, // Note: the label needs to be expressed in a way that the active parameter is detectable
                Parameters    = callArgs.Select(d => d.Item2).Select(AsParameterInfo).ToArray()
            };
            var precedingArgs = callArgs
                                .TakeWhile(item => item.Item1 == null || BeforePosition(item.Item1)) // skip args that have already been typed or - in the case of inner items - are missing
                                .Reverse().SkipWhile(item => item.Item1 == null);                    // don't count missing, i.e. not yet typed items, of the relevant inner argument tuple

            return(new SignatureHelp
            {
                Signatures = new[] { info }, // since we don't support overloading there is just one signature here
                ActiveSignature = 0,
                ActiveParameter = precedingArgs.Count()
            });
        }
コード例 #15
0
 public abstract bool TryCreateTooltip(AggregateBoundAttributeDescription attributeDescriptionInfo, MarkupKind markupKind, [NotNullWhen(true)] out MarkupContent?tooltipContent);