Skip to content

Commit

Permalink
feat(all): initial support for codeOf (#356)
Browse files Browse the repository at this point in the history
Fixes #308
  • Loading branch information
i582 authored Feb 24, 2025
1 parent adfd0f0 commit 1dbb6e6
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 5 deletions.
6 changes: 6 additions & 0 deletions server/src/TypeInferer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ export class TypeInferer {
return new StructTy("StateInit", stateInit)
}

if (node.node.type === "codeOf") {
const cell = index.elementByName(IndexKey.Primitives, "Cell")
if (!cell) return null
return new PrimitiveTy("Cell", cell, null)
}

if (node.node.type === "parenthesized_expression") {
const inner = node.node.children[1]
if (!inner) return null
Expand Down
8 changes: 7 additions & 1 deletion server/src/completion/CompletionContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export class CompletionContext {
public isMessageContext: boolean = false
public isBouncedMessage: boolean = false
public isInitOfName: boolean = false
public isCodeOfName: boolean = false
public afterFieldType: boolean = false
public insideImport: boolean = false
public inDestruct: boolean = false
Expand Down Expand Up @@ -228,6 +229,10 @@ export class CompletionContext {
this.isInitOfName = true
}

if (parent.type === "codeOf" && parent.childForFieldName("name")?.equals(element.node)) {
this.isCodeOfName = true
}

if (parent.type === "ERROR" && parent.parent?.type === "map_type") {
this.isType = true
this.isExpression = false
Expand Down Expand Up @@ -316,7 +321,8 @@ export class CompletionContext {
!this.inParameter &&
!this.afterFieldType &&
!this.insideImport &&
!this.isInitOfName
!this.isInitOfName &&
!this.isCodeOfName
)
}
}
4 changes: 2 additions & 2 deletions server/src/completion/ReferenceCompletionProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export class ReferenceCompletionProcessor implements ScopeProcessor {
return node instanceof Trait
}

if (this.ctx.isInitOfName) {
// only contracts can be used in `initOf Name()`
if (this.ctx.isInitOfName || this.ctx.isCodeOfName) {
// only contracts can be used in `initOf Name()` or in `codeOf Name`
return node instanceof Contract
}

Expand Down
12 changes: 11 additions & 1 deletion server/src/completion/providers/KeywordsCompletionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,17 @@ export class KeywordsCompletionProvider implements CompletionProvider {
kind: CompletionItemKind.Keyword,
insertText: "initOf $1($2)$0",
insertTextFormat: InsertTextFormat.Snippet,
weight: contextWeight(CompletionWeight.KEYWORD, expectedNull),
})

result.add({
label: "codeOf",
labelDetails: {
detail: " Contract",
description: " Cell",
},
kind: CompletionItemKind.Keyword,
insertText: "codeOf $1$0",
insertTextFormat: InsertTextFormat.Snippet,
})
}
}
8 changes: 7 additions & 1 deletion server/src/completion/providers/MapTypeCompletionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import {CompletionResult, CompletionWeight} from "@server/completion/WeightedCom

export class MapTypeCompletionProvider implements CompletionProvider {
public isAvailable(ctx: CompletionContext): boolean {
return ctx.isType && !ctx.inTraitList && !ctx.isMessageContext && !ctx.isInitOfName
return (
ctx.isType &&
!ctx.inTraitList &&
!ctx.isMessageContext &&
!ctx.isInitOfName &&
!ctx.isCodeOfName
)
}

public addCompletion(_ctx: CompletionContext, result: CompletionResult): void {
Expand Down
13 changes: 13 additions & 0 deletions server/src/e2e/suite/testcases/types/codeOf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
========================================================================
Trait inheritance
========================================================================
primitive Cell;

contract Foo {
fun derived() {
codeOf Foo;
//! ^ Cell
}
}
------------------------------------------------------------------------
ok
5 changes: 5 additions & 0 deletions syntaxes/.tmLanguage.json
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,11 @@
"match": "\\b(initOf)\\b",
"name": "keyword.operator.new.tact"
},
{
"comment": "codeOf expression",
"match": "\\b(codeOf)\\b",
"name": "keyword.operator.new.tact"
},
{
"comment": "Ternary expression",
"begin": "(?!\\?\\.\\s*[^[:digit:]])(\\?)(?!\\?)",
Expand Down
7 changes: 7 additions & 0 deletions tree-sitter-tact/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ module.exports = grammar({
$.identifier, // id
$.null, // null
$.initOf, // ExpressionInitOf
$.codeOf, // ExpressionCodeOf
$.string, // stringLiteral
$.self, // self
),
Expand Down Expand Up @@ -867,6 +868,12 @@ module.exports = grammar({
optional(field("arguments", $.argument_list)),
),

codeOf: ($) =>
seq(
"codeOf",
field("name", alias($._type_identifier, $.type_identifier)),
),

/* Types */

_type: ($) => choice($.map_type, $.bounced_type, $._simple_type),
Expand Down

0 comments on commit 1dbb6e6

Please sign in to comment.