Skip to content

Commit 931275a

Browse files
authored
feat(tolk/inspections): add unused type parameter inspection and fix find references for type parameters (#22)
Fixes #15
1 parent c8dc11b commit 931275a

File tree

7 files changed

+178
-0
lines changed

7 files changed

+178
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@
391391
"type": "string",
392392
"enum": [
393393
"unused-parameter",
394+
"unused-type-parameter",
394395
"unused-variable",
395396
"unused-top-level-declaration",
396397
"deprecated-symbol-usage",
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
========================================================================
2+
Unused type parameter inspection: function
3+
========================================================================
4+
fun main<T>() {}
5+
------------------------------------------------------------------------
6+
3 0:9 to 0:10 Type parameter 'T' is never used (tolk)
7+
8+
========================================================================
9+
Used type parameter inspection: function
10+
========================================================================
11+
fun main<T>(param: T) {
12+
param;
13+
}
14+
------------------------------------------------------------------------
15+
no issues
16+
17+
========================================================================
18+
Unused several type parameters inspection: function
19+
========================================================================
20+
fun main<TName, TOther>() {}
21+
------------------------------------------------------------------------
22+
3 0:9 to 0:14 Type parameter 'TName' is never used (tolk)
23+
3 0:16 to 0:22 Type parameter 'TOther' is never used (tolk)
24+
25+
========================================================================
26+
Used and unused type parameter inspection: function
27+
========================================================================
28+
fun main<TName, TOther>(param: TName) {
29+
param;
30+
}
31+
------------------------------------------------------------------------
32+
3 0:16 to 0:22 Type parameter 'TOther' is never used (tolk)
33+
34+
========================================================================
35+
Unused type parameter inspection: method
36+
========================================================================
37+
fun int.bar<T>() {}
38+
------------------------------------------------------------------------
39+
3 0:8 to 0:11 Method 'bar' is never used (tolk)
40+
3 0:12 to 0:13 Type parameter 'T' is never used (tolk)
41+
42+
========================================================================
43+
Used type parameter inspection: method
44+
========================================================================
45+
fun int.bar<T>(): T {}
46+
------------------------------------------------------------------------
47+
3 0:8 to 0:11 Method 'bar' is never used (tolk)
48+
49+
========================================================================
50+
Unused type parameter inspection: struct
51+
========================================================================
52+
struct Foo<T> {}
53+
------------------------------------------------------------------------
54+
3 0:7 to 0:10 Struct 'Foo' is never used (tolk)
55+
3 0:11 to 0:12 Type parameter 'T' is never used (tolk)
56+
57+
========================================================================
58+
Used type parameter inspection: struct
59+
========================================================================
60+
struct Foo<T> {
61+
field: T
62+
}
63+
------------------------------------------------------------------------
64+
3 0:7 to 0:10 Struct 'Foo' is never used (tolk)
65+
3 1:4 to 1:12 Field 'field' is never used (tolk)
66+
67+
========================================================================
68+
Unused type parameter inspection: type alias
69+
========================================================================
70+
type Foo<T> = int | slice
71+
------------------------------------------------------------------------
72+
3 0:5 to 0:8 Type alias 'Foo' is never used (tolk)
73+
3 0:9 to 0:10 Type parameter 'T' is never used (tolk)
74+
75+
========================================================================
76+
Used type parameter inspection: type alias
77+
========================================================================
78+
type Foo<T> = T | null
79+
------------------------------------------------------------------------
80+
3 0:5 to 0:8 Type alias 'Foo' is never used (tolk)

server/src/e2e/tolk/testcases/references/type-parameters.test

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,45 @@ fun <caret>T.foo(): T {}
2626
References: [0:13]
2727
Scope: LocalSearchScope:
2828
fun T.foo(): T {}
29+
30+
========================================================================
31+
Function type parameters
32+
========================================================================
33+
fun foo<<caret>T>(a: T): T {}
34+
------------------------------------------------------------------------
35+
References: [0:14, 0:18]
36+
Scope: LocalSearchScope:
37+
fun foo<T>(a: T): T {}
38+
39+
========================================================================
40+
Method type parameters
41+
========================================================================
42+
fun int.foo<<caret>T>(a: T): T {}
43+
------------------------------------------------------------------------
44+
References: [0:18, 0:22]
45+
Scope: LocalSearchScope:
46+
fun int.foo<T>(a: T): T {}
47+
48+
========================================================================
49+
Struct type parameters
50+
========================================================================
51+
struct Foo<<caret>T> {
52+
field: T
53+
other: Bar<T>
54+
}
55+
------------------------------------------------------------------------
56+
References: [1:11, 2:15]
57+
Scope: LocalSearchScope:
58+
struct Foo<T> {
59+
field: T
60+
other: Bar<T>
61+
}
62+
63+
========================================================================
64+
Type alias type parameters
65+
========================================================================
66+
type Foo<<caret>T> = T | null
67+
------------------------------------------------------------------------
68+
References: [0:14]
69+
Scope: LocalSearchScope:
70+
type Foo<T> = T | null

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {TolkFile} from "@server/languages/tolk/psi/TolkFile"
55

66
export const InspectionIds = {
77
UNUSED_PARAMETER: "unused-parameter",
8+
UNUSED_TYPE_PARAMETER: "unused-type-parameter",
89
UNUSED_VARIABLE: "unused-variable",
910
UNUSED_TOP_LEVEL_DECLARATION: "unused-top-level-declaration",
1011
DEPRECATED_SYMBOL_USAGE: "deprecated-symbol-usage",
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// SPDX-License-Identifier: MIT
2+
// Copyright © 2025 TON Core
3+
import type * as lsp from "vscode-languageserver"
4+
import type {TolkFile} from "@server/languages/tolk/psi/TolkFile"
5+
import {UnusedInspection} from "./UnusedInspection"
6+
import {Inspection, InspectionIds} from "./Inspection"
7+
import {TypeParameter} from "@server/languages/tolk/psi/Decls"
8+
9+
export class UnusedTypeParameterInspection extends UnusedInspection implements Inspection {
10+
public readonly id: "unused-type-parameter" = InspectionIds.UNUSED_TYPE_PARAMETER
11+
12+
protected checkFile(file: TolkFile, diagnostics: lsp.Diagnostic[]): void {
13+
for (const fun of file.getFunctions()) {
14+
this.checkTypeParameters(fun.typeParameters(), diagnostics)
15+
}
16+
for (const method of file.getMethods()) {
17+
this.checkTypeParameters(method.typeParameters(), diagnostics)
18+
}
19+
for (const struct of file.getStructs()) {
20+
this.checkTypeParameters(struct.typeParameters(), diagnostics)
21+
}
22+
for (const alias of file.getTypeAliases()) {
23+
this.checkTypeParameters(alias.typeParameters(), diagnostics)
24+
}
25+
}
26+
27+
private checkTypeParameters(parameters: TypeParameter[], diagnostics: lsp.Diagnostic[]): void {
28+
for (const param of parameters) {
29+
const name = param.nameIdentifier()
30+
if (!name) continue
31+
32+
this.checkUnused(name, param.file, diagnostics, {
33+
kind: "Type parameter",
34+
code: "unused-type-parameter",
35+
rangeNode: name,
36+
})
37+
}
38+
}
39+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {StructInitializationInspection} from "@server/languages/tolk/inspections
1010
import {TypeCompatibilityInspection} from "@server/languages/tolk/inspections/TypeCompatibilityInspection"
1111
import {CannotReassignInspection} from "@server/languages/tolk/inspections/CannotReassignInspection"
1212
import {UnusedTopLevelDeclarationInspection} from "@server/languages/tolk/inspections/UnusedTopLevelDeclarationInspection"
13+
import {UnusedTypeParameterInspection} from "@server/languages/tolk/inspections/UnusedTypeParameterInspection"
1314

1415
export async function runTolkInspections(
1516
uri: string,
@@ -18,6 +19,7 @@ export async function runTolkInspections(
1819
): Promise<void> {
1920
const inspections = [
2021
new UnusedParameterInspection(),
22+
new UnusedTypeParameterInspection(),
2123
new UnusedVariableInspection(),
2224
new UnusedImportInspection(),
2325
new UnusedTopLevelDeclarationInspection(),

server/src/languages/tolk/psi/Referent.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ export class Referent {
200200
parent.type === "type_alias_declaration" ||
201201
parent.type === "struct_declaration" ||
202202
parent.type === "struct_field_declaration" ||
203+
parent.type === "type_parameter" ||
203204
parent.type === "parameter_declaration") && parent.childForFieldName("name")?.equals(node)
204205
) {
205206
return true
@@ -326,6 +327,18 @@ export class Referent {
326327
return Referent.localSearchScope(parentOfType(parent, "method_declaration"))
327328
}
328329

330+
if (node.type === "type_parameter") {
331+
return Referent.localSearchScope(
332+
parentOfType(
333+
parent,
334+
"function_declaration",
335+
"method_declaration",
336+
"struct_declaration",
337+
"type_alias_declaration",
338+
),
339+
)
340+
}
341+
329342
return null
330343
}
331344

0 commit comments

Comments
 (0)