Skip to content

Commit 56a064c

Browse files
authored
feat(tolk/completion): support match over struct type and add completion option to fill all cases (#42)
Fixes #37 Fixes #38
1 parent 48f124a commit 56a064c

File tree

3 files changed

+170
-3
lines changed

3 files changed

+170
-3
lines changed

server/src/e2e/tolk/testcases/completion-select/match.test

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,105 @@ fun foo() {
303303
else => {<caret>},
304304
}
305305
}
306+
307+
========================================================================
308+
Match over type completion, union type, fill all
309+
========================================================================
310+
fun foo(value: int | slice) {
311+
match (value) {
312+
Fill<caret>
313+
}
314+
}
315+
------------------------------------------------------------------------
316+
fun foo(value: int | slice) {
317+
match (value) {
318+
int => {<caret>}
319+
slice => {}
320+
else => {}
321+
}
322+
}
323+
324+
========================================================================
325+
Match over type completion, union type 2, fill all
326+
========================================================================
327+
struct MintNewJettons
328+
struct BurnNotificationForMinter
329+
struct RequestWalletAddress
330+
struct ChangeMinterAdmin
331+
struct ChangeMinterContent
332+
333+
type AllowedMessageToMinter =
334+
| MintNewJettons
335+
| BurnNotificationForMinter
336+
| RequestWalletAddress
337+
| ChangeMinterAdmin
338+
| ChangeMinterContent
339+
340+
fun main(msg: AllowedMessageToMinter) {
341+
match (msg) {
342+
Fill<caret>
343+
}
344+
}
345+
------------------------------------------------------------------------
346+
struct MintNewJettons
347+
struct BurnNotificationForMinter
348+
struct RequestWalletAddress
349+
struct ChangeMinterAdmin
350+
struct ChangeMinterContent
351+
352+
type AllowedMessageToMinter =
353+
| MintNewJettons
354+
| BurnNotificationForMinter
355+
| RequestWalletAddress
356+
| ChangeMinterAdmin
357+
| ChangeMinterContent
358+
359+
fun main(msg: AllowedMessageToMinter) {
360+
match (msg) {
361+
MintNewJettons => {<caret>}
362+
BurnNotificationForMinter => {}
363+
RequestWalletAddress => {}
364+
ChangeMinterAdmin => {}
365+
ChangeMinterContent => {}
366+
else => {}
367+
}
368+
}
369+
370+
========================================================================
371+
Match over struct type completion, union type, fill all
372+
========================================================================
373+
struct Foo {}
374+
375+
fun foo(value: Foo) {
376+
match (value) {
377+
Fill<caret>
378+
}
379+
}
380+
------------------------------------------------------------------------
381+
struct Foo {}
382+
383+
fun foo(value: Foo) {
384+
match (value) {
385+
Foo => {<caret>}
386+
else => {}
387+
}
388+
}
389+
390+
========================================================================
391+
Match over value completion, no fill all
392+
========================================================================
393+
const Fill = 100
394+
395+
fun foo(value: int) {
396+
match (value) {
397+
Fil<caret>
398+
}
399+
}
400+
------------------------------------------------------------------------
401+
const Fill = 100
402+
403+
fun foo(value: int) {
404+
match (value) {
405+
Fill<caret> => {}
406+
}
407+
}

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,46 @@ fun foo(value: int) {
214214
}
215215
------------------------------------------------------------------------
216216
No completion items
217+
218+
========================================================================
219+
Match over struct completion
220+
========================================================================
221+
struct Foo {}
222+
223+
fun foo(value: Foo) {
224+
match (value) {
225+
<caret>
226+
}
227+
}
228+
------------------------------------------------------------------------
229+
22 Foo => {}
230+
22 else => {}
231+
232+
========================================================================
233+
Match over struct completion with single arm
234+
========================================================================
235+
struct Foo {}
236+
237+
fun foo(value: Foo) {
238+
match (value) {
239+
Foo => {}
240+
<caret>
241+
}
242+
}
243+
------------------------------------------------------------------------
244+
22 else => {}
245+
246+
========================================================================
247+
Match over struct completion with single arm and else
248+
========================================================================
249+
struct Foo {}
250+
251+
fun foo(value: Foo) {
252+
match (value) {
253+
Foo => {}
254+
else => {}
255+
<caret>
256+
}
257+
}
258+
------------------------------------------------------------------------
259+
No completion items

server/src/languages/tolk/completion/providers/MatchArmsCompletionProvider.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {CompletionContext} from "@server/languages/tolk/completion/Completi
66
import {CompletionResult, CompletionWeight} from "@server/completion/WeightedCompletionItem"
77
import {parentOfType} from "@server/psi/utils"
88
import {inferenceOf} from "@server/languages/tolk/type-inference"
9-
import {UnionTy} from "@server/languages/tolk/types/ty"
9+
import {StructTy, UnionTy} from "@server/languages/tolk/types/ty"
1010
import {ResolveState} from "@server/psi/ResolveState"
1111
import {ReferenceCompletionProcessor} from "@server/languages/tolk/completion/ReferenceCompletionProcessor"
1212
import {Reference} from "@server/languages/tolk/psi/Reference"
@@ -32,7 +32,7 @@ export class MatchArmsCompletionProvider implements CompletionProvider<Completio
3232
const exprTy = inference.typeOf(expr)?.baseType()
3333
if (!exprTy) return
3434

35-
if (!(exprTy instanceof UnionTy)) {
35+
if (!(exprTy instanceof UnionTy) && !(exprTy instanceof StructTy)) {
3636
// non type-match
3737

3838
const state = new ResolveState()
@@ -93,7 +93,29 @@ export class MatchArmsCompletionProvider implements CompletionProvider<Completio
9393
handledTypes.add(type.name())
9494
}
9595

96-
for (const variant of exprTy.elements) {
96+
const variants = exprTy instanceof UnionTy ? exprTy.elements : [exprTy]
97+
98+
if (arms.length === 0) {
99+
const lines: string[] = []
100+
101+
for (const [index, variant] of variants.entries()) {
102+
lines.push(`${variant.name()} => {${index === 0 ? "$0" : ""}}`)
103+
}
104+
105+
lines.push("else => {}")
106+
107+
const insertText = lines.join("\n")
108+
109+
result.add({
110+
label: "Fill all cases...",
111+
kind: CompletionItemKind.Snippet,
112+
insertTextFormat: InsertTextFormat.Snippet,
113+
insertText: insertText.trim(),
114+
weight: CompletionWeight.SNIPPET - 10,
115+
})
116+
}
117+
118+
for (const variant of variants) {
97119
const variantName = variant.name()
98120
if (handledTypes.has(variantName)) continue
99121

0 commit comments

Comments
 (0)