diff --git a/server/src/e2e/tolk/testcases/documentation/basic.test b/server/src/e2e/tolk/testcases/documentation/basic.test index e179e4e2..3d18cbb3 100644 --- a/server/src/e2e/tolk/testcases/documentation/basic.test +++ b/server/src/e2e/tolk/testcases/documentation/basic.test @@ -231,7 +231,7 @@ value: int some useful field ======================================================================== -Struct field documentation with inline comment +Struct field documentation with inline comment ======================================================================== struct Foo { value: int, // some useful field @@ -242,6 +242,7 @@ struct Foo { struct Foo value: int ``` +some useful field ======================================================================== Type alias documentation diff --git a/server/src/e2e/tolk/testcases/documentation/fields.test b/server/src/e2e/tolk/testcases/documentation/fields.test new file mode 100644 index 00000000..9d52f689 --- /dev/null +++ b/server/src/e2e/tolk/testcases/documentation/fields.test @@ -0,0 +1,52 @@ +======================================================================== +Inline field documentation without comma +======================================================================== +struct Foo { + value: int // comment here +} +------------------------------------------------------------------------ +```tolk +struct Foo +value: int +``` +comment here + +======================================================================== +Inline field documentation with comma +======================================================================== +struct Foo { + value: int, // comment here +} +------------------------------------------------------------------------ +```tolk +struct Foo +value: int +``` +comment here + +======================================================================== +Inline field documentation with several comments +======================================================================== +struct Foo { + value: int, /* comment */ /* comment2 */ +} +------------------------------------------------------------------------ +```tolk +struct Foo +value: int +``` +comment + +======================================================================== +Inline field documentation with plain documentation +======================================================================== +struct Foo { + // documentation here + value: int, // comment here +} +------------------------------------------------------------------------ +```tolk +struct Foo +value: int +``` +documentation here diff --git a/server/src/languages/tolk/psi/TolkNode.ts b/server/src/languages/tolk/psi/TolkNode.ts index a6ced4cf..d7603694 100644 --- a/server/src/languages/tolk/psi/TolkNode.ts +++ b/server/src/languages/tolk/psi/TolkNode.ts @@ -2,13 +2,11 @@ // Copyright © 2025 TON Core import type {Node as SyntaxNode} from "web-tree-sitter" import {TolkFile} from "./TolkFile" -import {Position} from "vscode-languageclient" -import {trimPrefix} from "@server/utils/strings" -import {asLspPosition} from "@server/utils/position" import {BaseNode} from "@server/psi/BaseNode" import {TensorTy, TupleTy, Ty} from "@server/languages/tolk/types/ty" import {TypeInferer} from "@server/languages/tolk/TypeInferer" import {parentOfType} from "@server/psi/utils" +import {extractCommentsDoc} from "@server/psi/comments" export class TolkNode extends BaseNode { public node: SyntaxNode @@ -273,50 +271,3 @@ export class VarDeclaration extends NamedNode { return this.node.childForFieldName("redef") !== null } } - -export function extractCommentsDocContent(node: SyntaxNode): { - lines: string[] - startPosition: Position -} | null { - const prevSibling = node.previousSibling - if (!prevSibling || prevSibling.type !== "comment") return null - - const nodeStartLine = node.startPosition.row - - const comments: SyntaxNode[] = [] - let comment: SyntaxNode | null = prevSibling - while (comment?.type === "comment") { - const commentStartLine = comment.startPosition.row - - if (commentStartLine + 1 + comments.length != nodeStartLine) { - break - } - - // possibly inline comment - const prev = comment.previousSibling - if (prev?.endPosition.row === commentStartLine) { - // same line with the previous node, inline comment - break - } - - comments.push(comment) - comment = comment.previousSibling - } - - if (comments.length === 0) return null - - const finalComments = comments.reverse() - - return { - lines: finalComments.map(c => - trimPrefix(trimPrefix(trimPrefix(c.text, "///"), "//"), " ").trimEnd(), - ), - startPosition: asLspPosition(comments[0].startPosition), - } -} - -export function extractCommentsDoc(node: SyntaxNode): string { - const content = extractCommentsDocContent(node) - if (!content) return "" - return content.lines.join("\n") -} diff --git a/server/src/psi/comments.ts b/server/src/psi/comments.ts index 3b24c488..7292ee2c 100644 --- a/server/src/psi/comments.ts +++ b/server/src/psi/comments.ts @@ -37,18 +37,60 @@ export function extractCommentsDocContent(node: SyntaxNode): { const finalComments = comments.reverse() return { - lines: finalComments.map(c => - trimPrefix( - trimPrefix(trimPrefix(trimPrefix(c.text, ";;;"), "///"), "//"), - " ", - ).trimEnd(), - ), + lines: finalComments.map(c => normalizeRawComment(c)), startPosition: asLspPosition(comments[0].startPosition), } } +function findInlineComment(node: SyntaxNode): SyntaxNode | null { + const nextSibling = node.nextSibling + if (nextSibling?.type === "comment") { + return nextSibling + } + + if (nextSibling?.type === ",") { + // foo: int, // comment + // ^ ^ + // | nextNextSibling + // | + // nextSibling + const nextNextSibling = nextSibling.nextSibling + if (nextNextSibling?.type === "comment") { + return nextNextSibling + } + } + + return null +} + +export function extractInlineDocCommentContent(node: SyntaxNode): { + lines: string[] + startPosition: Position +} | null { + const inlineComment = findInlineComment(node) + if (!inlineComment) return null + return { + lines: [normalizeRawComment(inlineComment)], + startPosition: asLspPosition(inlineComment.startPosition), + } +} + export function extractCommentsDoc(node: SyntaxNode): string { const content = extractCommentsDocContent(node) - if (!content) return "" + if (!content) { + const inlineContent = extractInlineDocCommentContent(node) + if (inlineContent) { + return inlineContent.lines.join("\n") + } + return "" + } return content.lines.join("\n") } + +function normalizeRawComment(c: SyntaxNode): string { + const text = c.text + if (text.startsWith("/*") && text.endsWith("*/")) { + return text.slice(2, -2).trim() + } + return trimPrefix(trimPrefix(trimPrefix(trimPrefix(text, ";;;"), "///"), "//"), " ").trimEnd() +}