diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ab56004a..1b1b4b153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New CSpell dictionaries: TVM instructions and adjusted list of Fift words: PR [#881](https://github.com/tact-lang/tact/pull/881) - Docs: the `description` property to the frontmatter of the each page for better SEO: PR [#916](https://github.com/tact-lang/tact/pull/916) - Docs: Google Analytics tags per every page: PR [#921](https://github.com/tact-lang/tact/pull/921) -- Ability to specify a compile-time method ID expression for getters: PR [#922](https://github.com/tact-lang/tact/pull/922) +- Ability to specify a compile-time method ID expression for getters: PR [#922](https://github.com/tact-lang/tact/pull/922) and PR [#932](https://github.com/tact-lang/tact/pull/932) ### Changed diff --git a/src/grammar/__snapshots__/grammar.spec.ts.snap b/src/grammar/__snapshots__/grammar.spec.ts.snap index 5bfd1e508..f4b766283 100644 --- a/src/grammar/__snapshots__/grammar.spec.ts.snap +++ b/src/grammar/__snapshots__/grammar.spec.ts.snap @@ -956,6 +956,7 @@ exports[`grammar should parse contract-getter-with-method-id 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": get(crc32("crc32") + 42 & 0x3ffff | 0x4000), "methodId": { "id": 10, @@ -1493,6 +1494,7 @@ exports[`grammar should parse contract-with-trait 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": virtual, "type": "virtual", }, @@ -1572,6 +1574,7 @@ exports[`grammar should parse contract-with-trait 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": override, "type": "override", }, @@ -1679,6 +1682,7 @@ exports[`grammar should parse contract-with-trait-string-literal 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": virtual, "type": "virtual", }, @@ -1758,6 +1762,7 @@ exports[`grammar should parse contract-with-trait-string-literal 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": override, "type": "override", }, @@ -3573,6 +3578,7 @@ exports[`grammar should parse items-asm-funs 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -3639,6 +3645,7 @@ exports[`grammar should parse items-asm-funs 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -3715,6 +3722,7 @@ exports[`grammar should parse items-asm-funs 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -4370,6 +4378,7 @@ exports[`grammar should parse items-method-def-initof-trailing-comma-shifts 1`] { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -9735,6 +9744,7 @@ exports[`grammar should parse trait-optional-semicolon-for-last-fun-decl 1`] = ` { "attributes": [ { + "kind": "function_attribute", "loc": abstract, "type": "abstract", }, diff --git a/src/grammar/ast.ts b/src/grammar/ast.ts index b9267b6d1..6ab4cc9ad 100644 --- a/src/grammar/ast.ts +++ b/src/grammar/ast.ts @@ -633,13 +633,18 @@ export type AstContractAttribute = { }; export type AstFunctionAttribute = - | { type: "get"; methodId: AstExpression | null; loc: SrcInfo } - | { type: "mutates"; loc: SrcInfo } - | { type: "extends"; loc: SrcInfo } - | { type: "virtual"; loc: SrcInfo } - | { type: "abstract"; loc: SrcInfo } - | { type: "override"; loc: SrcInfo } - | { type: "inline"; loc: SrcInfo }; + | { + kind: "function_attribute"; + type: "get"; + methodId: AstExpression | null; + loc: SrcInfo; + } + | { kind: "function_attribute"; type: "mutates"; loc: SrcInfo } + | { kind: "function_attribute"; type: "extends"; loc: SrcInfo } + | { kind: "function_attribute"; type: "virtual"; loc: SrcInfo } + | { kind: "function_attribute"; type: "abstract"; loc: SrcInfo } + | { kind: "function_attribute"; type: "override"; loc: SrcInfo } + | { kind: "function_attribute"; type: "inline"; loc: SrcInfo }; export type AstTypedParameter = { kind: "typed_parameter"; @@ -685,6 +690,7 @@ export type AstNode = | AstFieldDecl | AstTypedParameter | AstFunctionDef + | AstFunctionAttribute | AstAsmFunctionDef | AstFunctionDecl | AstModule diff --git a/src/grammar/grammar.ts b/src/grammar/grammar.ts index 760d58b13..ba5d8c7d3 100644 --- a/src/grammar/grammar.ts +++ b/src/grammar/grammar.ts @@ -585,28 +585,53 @@ semantics.addOperation("astOfAsmInstruction", { semantics.addOperation("astOfFunctionAttributes", { FunctionAttribute_getter(_getKwd, _optLparen, optMethodId, _optRparen) { return { + kind: "function_attribute", type: "get", methodId: unwrapOptNode(optMethodId, (e) => e.astOfExpression()), loc: createRef(this), }; }, FunctionAttribute_extends(_) { - return { type: "extends", loc: createRef(this) }; + return { + kind: "function_attribute", + type: "extends", + loc: createRef(this), + }; }, FunctionAttribute_mutates(_) { - return { type: "mutates", loc: createRef(this) }; + return { + kind: "function_attribute", + type: "mutates", + loc: createRef(this), + }; }, FunctionAttribute_override(_) { - return { type: "override", loc: createRef(this) }; + return { + kind: "function_attribute", + type: "override", + loc: createRef(this), + }; }, FunctionAttribute_inline(_) { - return { type: "inline", loc: createRef(this) }; + return { + kind: "function_attribute", + type: "inline", + loc: createRef(this), + }; }, FunctionAttribute_virtual(_) { - return { type: "virtual", loc: createRef(this) }; + return { + kind: "function_attribute", + type: "virtual", + loc: createRef(this), + }; }, FunctionAttribute_abstract(_) { - return { type: "abstract", loc: createRef(this) }; + return { + kind: "function_attribute", + type: "abstract", + loc: createRef(this), + }; }, }); diff --git a/src/grammar/iterators.ts b/src/grammar/iterators.ts index 4a8501470..5ac36dc14 100644 --- a/src/grammar/iterators.ts +++ b/src/grammar/iterators.ts @@ -25,6 +25,9 @@ export function traverse(node: AstNode, callback: (node: AstNode) => void) { traverse(node.name, callback); break; case "function_def": + node.attributes.forEach((attr) => { + traverse(attr, callback); + }); traverse(node.name, callback); if (node.return) traverse(node.return, callback); node.params.forEach((e) => { @@ -48,6 +51,9 @@ export function traverse(node: AstNode, callback: (node: AstNode) => void) { }); break; case "function_decl": + node.attributes.forEach((attr) => { + traverse(attr, callback); + }); traverse(node.name, callback); if (node.return) traverse(node.return, callback); node.params.forEach((e) => { @@ -62,6 +68,22 @@ export function traverse(node: AstNode, callback: (node: AstNode) => void) { }); if (node.return) traverse(node.return, callback); break; + case "function_attribute": + switch (node.type) { + case "get": + { + if (node.methodId) traverse(node.methodId, callback); + } + break; + case "mutates": + case "extends": + case "virtual": + case "abstract": + case "override": + case "inline": + break; + } + break; case "constant_def": traverse(node.name, callback); traverse(node.type, callback); diff --git a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap index 8437d6927..edb29b44e 100644 --- a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap +++ b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap @@ -657,10 +657,12 @@ exports[`resolveDescriptors should resolve descriptors for asm-extends-fun 1`] = "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, { + "kind": "function_attribute", "loc": mutates, "type": "mutates", }, @@ -4395,10 +4397,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr { "attributes": [ { + "kind": "function_attribute", "loc": abstract, "type": "abstract", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -4443,10 +4447,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr "ast": { "attributes": [ { + "kind": "function_attribute", "loc": abstract, "type": "abstract", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -4544,10 +4550,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr { "attributes": [ { + "kind": "function_attribute", "loc": override, "type": "override", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -4613,10 +4621,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr "ast": { "attributes": [ { + "kind": "function_attribute", "loc": override, "type": "override", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -4736,10 +4746,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr { "attributes": [ { + "kind": "function_attribute", "loc": abstract, "type": "abstract", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -4784,10 +4796,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr "ast": { "attributes": [ { + "kind": "function_attribute", "loc": abstract, "type": "abstract", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -4956,10 +4970,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr { "attributes": [ { + "kind": "function_attribute", "loc": virtual, "type": "virtual", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -5018,10 +5034,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr "ast": { "attributes": [ { + "kind": "function_attribute", "loc": virtual, "type": "virtual", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -5133,10 +5151,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr { "attributes": [ { + "kind": "function_attribute", "loc": override, "type": "override", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -5202,10 +5222,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr "ast": { "attributes": [ { + "kind": "function_attribute", "loc": override, "type": "override", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -5325,10 +5347,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr { "attributes": [ { + "kind": "function_attribute", "loc": virtual, "type": "virtual", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -5387,10 +5411,12 @@ exports[`resolveDescriptors should resolve descriptors for contract-getter-overr "ast": { "attributes": [ { + "kind": "function_attribute", "loc": virtual, "type": "virtual", }, { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -5525,6 +5551,7 @@ exports[`resolveDescriptors should resolve descriptors for fun-extends-opt-self "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -5642,6 +5669,7 @@ exports[`resolveDescriptors should resolve descriptors for fun-extends-opt-self "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -5759,10 +5787,12 @@ exports[`resolveDescriptors should resolve descriptors for fun-extends-opt-self "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, { + "kind": "function_attribute", "loc": mutates, "type": "mutates", }, @@ -5880,10 +5910,12 @@ exports[`resolveDescriptors should resolve descriptors for fun-extends-opt-self "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, { + "kind": "function_attribute", "loc": mutates, "type": "mutates", }, @@ -6001,10 +6033,12 @@ exports[`resolveDescriptors should resolve descriptors for fun-extends-opt-self "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, { + "kind": "function_attribute", "loc": mutates, "type": "mutates", }, @@ -7274,6 +7308,7 @@ exports[`resolveDescriptors should resolve descriptors for item-funs-with-errors { "attributes": [ { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -7315,6 +7350,7 @@ exports[`resolveDescriptors should resolve descriptors for item-funs-with-errors { "attributes": [ { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -7426,6 +7462,7 @@ exports[`resolveDescriptors should resolve descriptors for item-funs-with-errors "ast": { "attributes": [ { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -7489,6 +7526,7 @@ exports[`resolveDescriptors should resolve descriptors for item-funs-with-errors "ast": { "attributes": [ { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -7698,6 +7736,7 @@ exports[`resolveDescriptors should resolve descriptors for item-method 1`] = ` "ast": { "attributes": [ { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -8069,10 +8108,12 @@ exports[`resolveDescriptors should resolve descriptors for item-native-mutating- "ast": { "attributes": [ { + "kind": "function_attribute", "loc": mutates, "type": "mutates", }, { + "kind": "function_attribute", "loc": extends, "type": "extends", }, @@ -8331,6 +8372,7 @@ exports[`resolveDescriptors should resolve descriptors for map-value-as-coins 1` { "attributes": [ { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get", @@ -8659,6 +8701,7 @@ exports[`resolveDescriptors should resolve descriptors for map-value-as-coins 1` "ast": { "attributes": [ { + "kind": "function_attribute", "loc": get, "methodId": null, "type": "get",