Skip to content

Commit c6407ab

Browse files
authored
feat(tolk/inspections): don't require ; in grammar and give an error later (#126)
Fixes #125
1 parent bca03a0 commit c6407ab

File tree

8 files changed

+21526
-20267
lines changed

8 files changed

+21526
-20267
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,8 @@
435435
"unused-import",
436436
"struct-initialization",
437437
"cannot-reassign",
438-
"need-not-null-unwrapping"
438+
"need-not-null-unwrapping",
439+
"missed-semicolon"
439440
]
440441
},
441442
"default": [
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
========================================================================
2+
Missed ; after variable declaration
3+
========================================================================
4+
fun main() {
5+
var a = 100
6+
a = 100;
7+
}
8+
------------------------------------------------------------------------
9+
0 1:15 to 1:15 Missed `;` at end of statement (tolk)
10+
11+
========================================================================
12+
Missed ; after assignment
13+
========================================================================
14+
fun main() {
15+
var a = 100;
16+
a = 100
17+
return a
18+
}
19+
------------------------------------------------------------------------
20+
0 2:11 to 2:11 Missed `;` at end of statement (tolk)
21+
22+
========================================================================
23+
Missed ; after expression in if
24+
========================================================================
25+
fun main() {
26+
var a = 100;
27+
if (a == 200) {
28+
200
29+
a = 200
30+
}
31+
return a
32+
}
33+
------------------------------------------------------------------------
34+
0 3:11 to 3:11 Missed `;` at end of statement (tolk)
35+
36+
========================================================================
37+
Missed ; after do-while
38+
========================================================================
39+
fun main() {
40+
var a = 100;
41+
if (a == 200) {
42+
do {
43+
a -= 1
44+
} while (a > 10)
45+
a = 200
46+
}
47+
return a
48+
}
49+
------------------------------------------------------------------------
50+
0 5:24 to 5:24 Missed `;` at end of statement (tolk)

server/src/languages/tolk/inspections/Inspection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const InspectionIds = {
1313
STRUCT_INITIALIZATION: "struct-initialization",
1414
TYPE_COMPATIBILITY: "type-compatibility",
1515
CANNOT_REASSIGN: "cannot-reassign",
16+
MISSED_SEMICOLON: "missed-semicolon",
1617
NEED_NOT_NULL_UNWRAPPING: "need-not-null-unwrapping",
1718
} as const
1819

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright © 2025 TON Core
3+
import * as lsp from "vscode-languageserver"
4+
import type {TolkFile} from "@server/languages/tolk/psi/TolkFile"
5+
import {Inspection, InspectionIds} from "./Inspection"
6+
import {RecursiveVisitor} from "@server/visitor/visitor"
7+
import {asLspRange} from "@server/utils/position"
8+
9+
export class MissedSemicolonInspection implements Inspection {
10+
public readonly id: "missed-semicolon" = InspectionIds.MISSED_SEMICOLON
11+
12+
public inspect(file: TolkFile): lsp.Diagnostic[] {
13+
if (file.fromStdlib) return []
14+
const diagnostics: lsp.Diagnostic[] = []
15+
this.checkFile(file, diagnostics)
16+
return diagnostics
17+
}
18+
19+
protected checkFile(file: TolkFile, diagnostics: lsp.Diagnostic[]): void {
20+
RecursiveVisitor.visit(file.rootNode, (node): boolean => {
21+
if (node.type === "block_statement") {
22+
const statements = node.namedChildren.filter(it => it?.type !== "comment")
23+
for (const [index, stmt] of statements.entries()) {
24+
if (!stmt) break
25+
const stmtType = stmt.type
26+
27+
if (
28+
stmtType === "local_vars_declaration" ||
29+
stmtType === "return_statement" ||
30+
stmtType === "do_while_statement" ||
31+
stmtType === "break_statement" ||
32+
stmtType === "continue_statement" ||
33+
stmtType === "throw_statement" ||
34+
stmtType === "assert_statement" ||
35+
stmtType === "expression_statement"
36+
) {
37+
const nextSibling = stmt.nextSibling
38+
if (nextSibling?.text !== ";" && index !== statements.length - 1) {
39+
const stmtRange = asLspRange(stmt)
40+
diagnostics.push({
41+
severity: lsp.DiagnosticSeverity.Error,
42+
range: {
43+
start: {
44+
line: stmtRange.end.line,
45+
character: stmtRange.end.character,
46+
},
47+
end: {
48+
line: stmtRange.end.line,
49+
character: stmtRange.end.character,
50+
},
51+
},
52+
message: `Missed \`;\` at end of statement`,
53+
source: "tolk",
54+
code: "parser",
55+
})
56+
}
57+
}
58+
}
59+
}
60+
return true
61+
})
62+
}
63+
}

server/src/languages/tolk/inspections/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {CannotReassignInspection} from "@server/languages/tolk/inspections/Canno
1212
import {UnusedTopLevelDeclarationInspection} from "@server/languages/tolk/inspections/UnusedTopLevelDeclarationInspection"
1313
import {UnusedTypeParameterInspection} from "@server/languages/tolk/inspections/UnusedTypeParameterInspection"
1414
import {NeedNotNullUnwrappingInspection} from "@server/languages/tolk/inspections/NeedNotNullUnwrappingInspection"
15+
import {MissedSemicolonInspection} from "@server/languages/tolk/inspections/MissedSemicolonInspection"
1516

1617
export async function runTolkInspections(
1718
uri: string,
@@ -29,6 +30,7 @@ export async function runTolkInspections(
2930
new TypeCompatibilityInspection(),
3031
new CannotReassignInspection(),
3132
new NeedNotNullUnwrappingInspection(),
33+
new MissedSemicolonInspection(),
3234
]
3335

3436
const settings = await getDocumentSettings(uri)

server/src/languages/tolk/tree-sitter-tolk/grammar.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,12 @@ const TOLK_GRAMMAR = {
218218
$.continue_statement,
219219
$.throw_statement,
220220
$.assert_statement,
221+
$.expression_statement,
221222
),
222223
_statement: $ =>
223224
choice(
224225
$._statement_ending_with_brace,
225-
seq($._statement_require_semicolon_unless_last, ";"),
226-
prec.right(seq($.expression_statement, optional(";"))),
226+
prec.right(seq($._statement_require_semicolon_unless_last, optional(";"))),
227227
),
228228

229229
local_vars_declaration: $ =>

server/src/languages/tolk/tree-sitter-tolk/src/grammar.json

Lines changed: 5 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)