Skip to content

Commit 485edeb

Browse files
authored
fix(tolk/completion): fix completion for generic struct static methods (#30)
Fixes #29
1 parent 715ce71 commit 485edeb

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

server/src/e2e/tolk/testcases/completion/methods.test

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,33 @@ fun foo(someParameter: int) {
3535
1 bad() of Foo
3636
1 bar() of Foo
3737
1 baz() of Foo
38+
39+
========================================================================
40+
Static methods completion for generic struct
41+
========================================================================
42+
struct Second<T> {}
43+
fun Second<T>.new(): Second<T> {}
44+
fun Second<int>.new(): Second<int> {}
45+
46+
fun main() {
47+
val first = First<int>.<caret>;
48+
}
49+
------------------------------------------------------------------------
50+
No completion items
51+
52+
========================================================================
53+
Static methods completion for generic struct 2
54+
========================================================================
55+
struct Second<T> {}
56+
fun Second<T>.new(): Second<T> {}
57+
fun Second<int>.new(): Second<int> {}
58+
59+
fun main() {
60+
val first = Second<int>.<caret>;
61+
}
62+
------------------------------------------------------------------------
63+
1 fromCell(packedCell: cell, options: UnpackOptions = {}): T of T
64+
1 fromSlice(rawSlice: slice, options: UnpackOptions = {}): T of T
65+
1 getDeclaredPackPrefix(): int of T
66+
1 getDeclaredPackPrefixLen(): int of T
67+
1 new(): Second<T> of Second<T>

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,13 +291,19 @@ export class Reference {
291291
if (resolved) {
292292
// static methods like Foo.bar();
293293
if (resolved instanceof Struct || resolved instanceof TypeAlias) {
294-
return this.processStaticMethods(resolved, proc, state)
294+
return this.processStaticMethods(resolved.name(), proc, state)
295295
}
296296
}
297297

298298
const qualifierType = inference?.typeOf(qualifier.node)?.unwrapOption()
299299
if (!qualifierType) return true
300300

301+
if (qualifier.node.type === "generic_instantiation") {
302+
// Foo<int>.bar()
303+
const baseType = qualifierType.unwrapInstantiation()
304+
return this.processStaticMethods(baseType.name(), proc, state)
305+
}
306+
301307
if (!this.processType(qualifier, qualifierType, proc, state)) return false
302308

303309
// last resort, trying to find methods of T?
@@ -306,7 +312,7 @@ export class Reference {
306312
}
307313

308314
private processStaticMethods(
309-
resolved: NamedNode | null,
315+
typeName: string,
310316
proc: ScopeProcessor,
311317
state: ResolveState,
312318
): boolean {
@@ -315,10 +321,19 @@ export class Reference {
315321
new (class implements ScopeProcessor {
316322
public execute(node: InstanceMethod | StaticMethod, state: ResolveState): boolean {
317323
if (node instanceof InstanceMethod) return true
318-
const receiverType = node.receiverTypeString()
319-
if (receiverType === resolved?.name() || receiverType === "T") {
324+
const receiverTypeString = node.receiverTypeString()
325+
if (receiverTypeString === typeName || receiverTypeString === "T") {
320326
return proc.execute(node, state)
321327
}
328+
329+
const receiverType = node.receiverTypeNode()
330+
if (receiverType?.type === "type_instantiatedTs") {
331+
const innerName = receiverType.childForFieldName("name")?.text
332+
if (innerName === typeName) {
333+
return proc.execute(node, state)
334+
}
335+
}
336+
322337
return true
323338
}
324339
})(),

0 commit comments

Comments
 (0)