@harmoniclabs/pebble 0.1.3-dev2 → 0.1.3-dev4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/nodes/statements/declarations/VarDecl/SimpleVarDecl.d.ts +5 -1
- package/dist/ast/nodes/statements/declarations/VarDecl/SimpleVarDecl.js +5 -1
- package/dist/compiler/AstCompiler/AstCompiler.d.ts +15 -0
- package/dist/compiler/AstCompiler/AstCompiler.js +226 -10
- package/dist/compiler/AstCompiler/internal/_deriveContractBody/_deriveContractBody.js +40 -35
- package/dist/compiler/AstCompiler/internal/statements/_compileVarStmt.d.ts +7 -2
- package/dist/compiler/AstCompiler/internal/statements/_compileVarStmt.js +17 -14
- package/dist/compiler/Compiler.d.ts +8 -1
- package/dist/compiler/Compiler.js +34 -1
- package/dist/compiler/SourceTypeMap.d.ts +43 -0
- package/dist/compiler/SourceTypeMap.js +432 -0
- package/dist/compiler/tir/statements/TirVarDecl/TirNamedDeconstructVarDecl.d.ts +19 -1
- package/dist/compiler/tir/statements/TirVarDecl/TirNamedDeconstructVarDecl.js +13 -1
- package/dist/compiler/tir/statements/TirVarDecl/TirSimpleVarDecl.d.ts +9 -1
- package/dist/compiler/tir/statements/TirVarDecl/TirSimpleVarDecl.js +9 -1
- package/dist/compiler/tir/statements/TirVarDecl/TirSingleDeconstructVarDecl.d.ts +15 -1
- package/dist/compiler/tir/statements/TirVarDecl/TirSingleDeconstructVarDecl.js +9 -1
- package/package.json +1 -1
|
@@ -11,7 +11,11 @@ export declare class SimpleVarDecl implements HasSourceRange, HasInitExpr {
|
|
|
11
11
|
initExpr: PebbleExpr | undefined;
|
|
12
12
|
flags: CommonFlags;
|
|
13
13
|
readonly range: SourceRange;
|
|
14
|
-
|
|
14
|
+
/** original source name when the identifier was renamed internally (for LSP) */
|
|
15
|
+
readonly sourceName?: string | undefined;
|
|
16
|
+
constructor(name: Identifier, type: AstTypeExpr | undefined, initExpr: PebbleExpr | undefined, flags: CommonFlags, range: SourceRange,
|
|
17
|
+
/** original source name when the identifier was renamed internally (for LSP) */
|
|
18
|
+
sourceName?: string | undefined);
|
|
15
19
|
isConst(): boolean;
|
|
16
20
|
static onlyIdentifier(identifier: Identifier, flags: CommonFlags): SimpleVarDecl;
|
|
17
21
|
static onlyNameConst(name: string, range: SourceRange): SimpleVarDecl;
|
|
@@ -6,12 +6,16 @@ export class SimpleVarDecl {
|
|
|
6
6
|
initExpr;
|
|
7
7
|
flags;
|
|
8
8
|
range;
|
|
9
|
-
|
|
9
|
+
sourceName;
|
|
10
|
+
constructor(name, type, initExpr, flags, range,
|
|
11
|
+
/** original source name when the identifier was renamed internally (for LSP) */
|
|
12
|
+
sourceName) {
|
|
10
13
|
this.name = name;
|
|
11
14
|
this.type = type;
|
|
12
15
|
this.initExpr = initExpr;
|
|
13
16
|
this.flags = flags;
|
|
14
17
|
this.range = range;
|
|
18
|
+
this.sourceName = sourceName;
|
|
15
19
|
}
|
|
16
20
|
isConst() {
|
|
17
21
|
return (this.flags & CommonFlags.Const) !== 0;
|
|
@@ -9,6 +9,7 @@ import { AstFuncName, AstScope, TirFuncName } from "./scope/AstScope.js";
|
|
|
9
9
|
import { TypedProgram } from "../tir/program/TypedProgram.js";
|
|
10
10
|
import { ResolveStackNode } from "./utils/deps/ResolveStackNode.js";
|
|
11
11
|
import { TirType } from "../tir/types/TirType.js";
|
|
12
|
+
import { CheckResult } from "../SourceTypeMap.js";
|
|
12
13
|
export interface AstTypeDefCompilationResult {
|
|
13
14
|
sop: TirType | undefined;
|
|
14
15
|
data: TirType | undefined;
|
|
@@ -54,6 +55,20 @@ export declare class AstCompiler extends DiagnosticEmitter {
|
|
|
54
55
|
* inside a function body.
|
|
55
56
|
*/
|
|
56
57
|
run(): Promise<TypedProgram>;
|
|
58
|
+
/**
|
|
59
|
+
* like `run()` but omits the return type annotation on the wrapping function
|
|
60
|
+
* and turns the last non-declaration statement into a `return` expression,
|
|
61
|
+
* allowing the type to be inferred from the expression.
|
|
62
|
+
*/
|
|
63
|
+
runRepl(): Promise<TypedProgram>;
|
|
64
|
+
/**
|
|
65
|
+
* runs the frontend only (parsing + semantic analysis + type checking)
|
|
66
|
+
* without requiring a contract and without throwing on diagnostics.
|
|
67
|
+
*
|
|
68
|
+
* returns `CheckResult` with diagnostics, the typed program,
|
|
69
|
+
* and a `SourceTypeMap` for querying types at source positions.
|
|
70
|
+
*/
|
|
71
|
+
check(): Promise<CheckResult>;
|
|
57
72
|
/**
|
|
58
73
|
* compiles the entry file specified in the config
|
|
59
74
|
*
|
|
@@ -35,6 +35,7 @@ import { _deriveContractBody } from "./internal/_deriveContractBody/_deriveContr
|
|
|
35
35
|
import { DiagnosticCategory } from "../../diagnostics/DiagnosticCategory.js";
|
|
36
36
|
import { VarStmt } from "../../ast/nodes/statements/VarStmt.js";
|
|
37
37
|
import { _compileSimpleVarDecl } from "./internal/statements/_compileVarStmt.js";
|
|
38
|
+
import { SourceTypeMap } from "../SourceTypeMap.js";
|
|
38
39
|
import { isIdentifier } from "../../utils/text.js";
|
|
39
40
|
/*
|
|
40
41
|
Handling type expressions that depend on other types
|
|
@@ -115,9 +116,6 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
115
116
|
* inside a function body.
|
|
116
117
|
*/
|
|
117
118
|
async run() {
|
|
118
|
-
const RUN_FUNC_NAME = "__pebble_run__";
|
|
119
|
-
this._isExporting = true;
|
|
120
|
-
this.program.contractTirFuncName = RUN_FUNC_NAME;
|
|
121
119
|
const filePath = this.cfg.entry;
|
|
122
120
|
if (!filePath) {
|
|
123
121
|
this.error(DiagnosticCode.File_0_not_found, undefined, this.cfg.entry);
|
|
@@ -128,14 +126,79 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
128
126
|
const src = await this.getAbsoulteProjPathSource(filePath);
|
|
129
127
|
if (!src)
|
|
130
128
|
throw new Error("AstCompiler.run: could not read source: " + filePath);
|
|
129
|
+
const funcName = _uniqueFuncName("__pebble_run__", src.text);
|
|
130
|
+
this._isExporting = true;
|
|
131
|
+
this.program.contractTirFuncName = funcName;
|
|
131
132
|
// 1) Rewrite the source text: wrap non-declaration statements in a function
|
|
132
|
-
src.text = _wrapSourceTextForRun(src.text,
|
|
133
|
+
src.text = _wrapSourceTextForRun(src.text, funcName);
|
|
133
134
|
// update range to match the new text length
|
|
134
135
|
src.range.end = src.text.length;
|
|
135
136
|
// 2) Use the normal compilation pipeline (parse + semantic analysis)
|
|
136
137
|
// which now sees the entry source as having a top-level function
|
|
137
138
|
return await this.compile();
|
|
138
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* like `run()` but omits the return type annotation on the wrapping function
|
|
142
|
+
* and turns the last non-declaration statement into a `return` expression,
|
|
143
|
+
* allowing the type to be inferred from the expression.
|
|
144
|
+
*/
|
|
145
|
+
async runRepl() {
|
|
146
|
+
const filePath = this.cfg.entry;
|
|
147
|
+
if (!filePath) {
|
|
148
|
+
this.error(DiagnosticCode.File_0_not_found, undefined, this.cfg.entry);
|
|
149
|
+
throw new Error("entry file not found");
|
|
150
|
+
}
|
|
151
|
+
if (!this.io.exsistSync(filePath))
|
|
152
|
+
throw new Error("AstCompiler.runRepl: entry file does not exist: " + filePath);
|
|
153
|
+
const src = await this.getAbsoulteProjPathSource(filePath);
|
|
154
|
+
if (!src)
|
|
155
|
+
throw new Error("AstCompiler.runRepl: could not read source: " + filePath);
|
|
156
|
+
const funcName = _uniqueFuncName("__pebble_repl__", src.text);
|
|
157
|
+
this._isExporting = true;
|
|
158
|
+
this.program.contractTirFuncName = funcName;
|
|
159
|
+
// 1) Rewrite the source text: wrap non-declaration statements in a function
|
|
160
|
+
// with no return type annotation, and turn the last statement into a return
|
|
161
|
+
src.text = _wrapSourceTextForRepl(src.text, funcName);
|
|
162
|
+
// update range to match the new text length
|
|
163
|
+
src.range.end = src.text.length;
|
|
164
|
+
// 2) Use the normal compilation pipeline (parse + semantic analysis)
|
|
165
|
+
return await this.compile();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* runs the frontend only (parsing + semantic analysis + type checking)
|
|
169
|
+
* without requiring a contract and without throwing on diagnostics.
|
|
170
|
+
*
|
|
171
|
+
* returns `CheckResult` with diagnostics, the typed program,
|
|
172
|
+
* and a `SourceTypeMap` for querying types at source positions.
|
|
173
|
+
*/
|
|
174
|
+
async check() {
|
|
175
|
+
const filePath = this.cfg.entry;
|
|
176
|
+
if (!filePath) {
|
|
177
|
+
this.error(DiagnosticCode.File_0_not_found, undefined, this.cfg.entry);
|
|
178
|
+
return {
|
|
179
|
+
diagnostics: this.diagnostics.slice(),
|
|
180
|
+
program: this.program,
|
|
181
|
+
sourceTypeMap: new SourceTypeMap(this.program)
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
if (!this.io.exsistSync(filePath)) {
|
|
185
|
+
this.error(DiagnosticCode.File_0_not_found, undefined, filePath);
|
|
186
|
+
return {
|
|
187
|
+
diagnostics: this.diagnostics.slice(),
|
|
188
|
+
program: this.program,
|
|
189
|
+
sourceTypeMap: new SourceTypeMap(this.program)
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
await this.compileFile(filePath, true);
|
|
193
|
+
// no contract check, no throw — just collect diagnostics
|
|
194
|
+
const typeMap = new SourceTypeMap(this.program);
|
|
195
|
+
typeMap.buildFromProgram();
|
|
196
|
+
return {
|
|
197
|
+
diagnostics: this.diagnostics.slice(),
|
|
198
|
+
program: this.program,
|
|
199
|
+
sourceTypeMap: typeMap
|
|
200
|
+
};
|
|
201
|
+
}
|
|
139
202
|
/**
|
|
140
203
|
* compiles the entry file specified in the config
|
|
141
204
|
*
|
|
@@ -154,14 +217,15 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
154
217
|
let msg;
|
|
155
218
|
const fstErrorMsg = this.diagnostics[0].toString();
|
|
156
219
|
const nDiags = this.diagnostics.length;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
this.io.stdout.write(
|
|
220
|
+
for (msg of this.diagnostics) {
|
|
221
|
+
//*
|
|
222
|
+
this.io.stdout.write(msg.toString() + "\n");
|
|
160
223
|
/*/
|
|
161
|
-
console.log(msg);
|
|
162
|
-
console.log(msg.toString());
|
|
224
|
+
console.log( msg );
|
|
225
|
+
console.log( msg.toString() );
|
|
163
226
|
//*/
|
|
164
227
|
}
|
|
228
|
+
// return this.program;
|
|
165
229
|
throw new Error("AstCompiler.compile: failed with " + nDiags + " diagnostic messages; first message: " + fstErrorMsg);
|
|
166
230
|
}
|
|
167
231
|
const mainFuncExpr = this.program.functions.get(this.program.contractTirFuncName);
|
|
@@ -690,7 +754,8 @@ export class AstCompiler extends DiagnosticEmitter {
|
|
|
690
754
|
const internalName = getUniqueInternalName(param.name.text);
|
|
691
755
|
paramsInternalNamesMap.set(astName, internalName);
|
|
692
756
|
funcParams[i] = new SimpleVarDecl(new Identifier(internalName, param.name.range), astType, undefined, // initExpr
|
|
693
|
-
CommonFlags.Const, param.range
|
|
757
|
+
CommonFlags.Const, param.range, astName // original source name for LSP
|
|
758
|
+
);
|
|
694
759
|
}
|
|
695
760
|
const scriptContextName = getUniqueInternalName("ctx");
|
|
696
761
|
funcParams[contractDecl.params.length] = new SimpleVarDecl(new Identifier(scriptContextName, contractDecl.name.range), new AstNamedTypeExpr(new Identifier("ScriptContext", contractDecl.name.range), [], contractDecl.name.range), undefined, // initExpr
|
|
@@ -721,6 +786,18 @@ const _declKeywords = new Set([
|
|
|
721
786
|
"data",
|
|
722
787
|
"runtime",
|
|
723
788
|
]);
|
|
789
|
+
/**
|
|
790
|
+
* Returns a function name that does not appear in the source text.
|
|
791
|
+
* Starts with `baseName` and appends an incrementing suffix if needed.
|
|
792
|
+
*/
|
|
793
|
+
function _uniqueFuncName(baseName, sourceText) {
|
|
794
|
+
let name = baseName;
|
|
795
|
+
let i = 0;
|
|
796
|
+
while (sourceText.includes(name)) {
|
|
797
|
+
name = baseName + "_" + (i++);
|
|
798
|
+
}
|
|
799
|
+
return name;
|
|
800
|
+
}
|
|
724
801
|
/**
|
|
725
802
|
* Splits source text into declaration blocks and body blocks
|
|
726
803
|
* using a simple character scanner, then wraps body blocks
|
|
@@ -842,6 +919,145 @@ function _wrapSourceTextForRun(text, funcName) {
|
|
|
842
919
|
bodyParts.join("\n") + "\n" +
|
|
843
920
|
"}\n");
|
|
844
921
|
}
|
|
922
|
+
/**
|
|
923
|
+
* Like `_wrapSourceTextForRun` but:
|
|
924
|
+
* - omits the return type annotation (no `: void`)
|
|
925
|
+
* - turns the last non-declaration statement into a `return` expression
|
|
926
|
+
*
|
|
927
|
+
* This allows the compiler to infer the return type from the expression,
|
|
928
|
+
* used by the REPL to evaluate and return expression values.
|
|
929
|
+
*/
|
|
930
|
+
function _wrapSourceTextForRepl(text, funcName) {
|
|
931
|
+
const len = text.length;
|
|
932
|
+
const ranges = [];
|
|
933
|
+
let pos = 0;
|
|
934
|
+
while (pos < len) {
|
|
935
|
+
// skip whitespace
|
|
936
|
+
while (pos < len && _isWhitespace(text.charCodeAt(pos)))
|
|
937
|
+
pos++;
|
|
938
|
+
if (pos >= len)
|
|
939
|
+
break;
|
|
940
|
+
const stmtStart = pos;
|
|
941
|
+
// read the first word to determine if this is a declaration
|
|
942
|
+
const word = _readWord(text, pos);
|
|
943
|
+
const isDecl = _declKeywords.has(word);
|
|
944
|
+
// find the end of this statement:
|
|
945
|
+
// track brace/paren depth, respect strings and comments
|
|
946
|
+
let braceDepth = 0;
|
|
947
|
+
let parenDepth = 0;
|
|
948
|
+
let ended = false;
|
|
949
|
+
while (pos < len && !ended) {
|
|
950
|
+
const ch = text.charCodeAt(pos);
|
|
951
|
+
// single-line comment
|
|
952
|
+
if (ch === 0x2F /* / */ && pos + 1 < len && text.charCodeAt(pos + 1) === 0x2F /* / */) {
|
|
953
|
+
pos += 2;
|
|
954
|
+
while (pos < len && text.charCodeAt(pos) !== 0x0A /* \n */)
|
|
955
|
+
pos++;
|
|
956
|
+
continue;
|
|
957
|
+
}
|
|
958
|
+
// multi-line comment
|
|
959
|
+
if (ch === 0x2F /* / */ && pos + 1 < len && text.charCodeAt(pos + 1) === 0x2A /* * */) {
|
|
960
|
+
pos += 2;
|
|
961
|
+
while (pos < len && !(text.charCodeAt(pos) === 0x2A && pos + 1 < len && text.charCodeAt(pos + 1) === 0x2F))
|
|
962
|
+
pos++;
|
|
963
|
+
pos += 2; // skip */
|
|
964
|
+
continue;
|
|
965
|
+
}
|
|
966
|
+
// string literals
|
|
967
|
+
if (ch === 0x22 /* " */ || ch === 0x27 /* ' */ || ch === 0x60 /* ` */) {
|
|
968
|
+
pos++;
|
|
969
|
+
while (pos < len) {
|
|
970
|
+
const sc = text.charCodeAt(pos);
|
|
971
|
+
if (sc === 0x5C /* \ */) {
|
|
972
|
+
pos += 2;
|
|
973
|
+
continue;
|
|
974
|
+
} // escaped char
|
|
975
|
+
if (sc === ch) {
|
|
976
|
+
pos++;
|
|
977
|
+
break;
|
|
978
|
+
}
|
|
979
|
+
pos++;
|
|
980
|
+
}
|
|
981
|
+
continue;
|
|
982
|
+
}
|
|
983
|
+
if (ch === 0x28 /* ( */) {
|
|
984
|
+
parenDepth++;
|
|
985
|
+
pos++;
|
|
986
|
+
}
|
|
987
|
+
else if (ch === 0x29 /* ) */) {
|
|
988
|
+
parenDepth--;
|
|
989
|
+
pos++;
|
|
990
|
+
}
|
|
991
|
+
else if (ch === 0x7B /* { */) {
|
|
992
|
+
braceDepth++;
|
|
993
|
+
pos++;
|
|
994
|
+
}
|
|
995
|
+
else if (ch === 0x7D /* } */) {
|
|
996
|
+
braceDepth--;
|
|
997
|
+
pos++;
|
|
998
|
+
if (braceDepth <= 0 && parenDepth <= 0) {
|
|
999
|
+
// consume optional trailing semicolon
|
|
1000
|
+
let p2 = pos;
|
|
1001
|
+
while (p2 < len && _isWhitespace(text.charCodeAt(p2)))
|
|
1002
|
+
p2++;
|
|
1003
|
+
if (p2 < len && text.charCodeAt(p2) === 0x3B /* ; */)
|
|
1004
|
+
pos = p2 + 1;
|
|
1005
|
+
ended = true;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
else if (ch === 0x3B /* ; */ && braceDepth === 0 && parenDepth === 0) {
|
|
1009
|
+
pos++;
|
|
1010
|
+
ended = true;
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
pos++;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
const stmtEnd = pos;
|
|
1017
|
+
// skip empty ranges
|
|
1018
|
+
if (stmtEnd > stmtStart) {
|
|
1019
|
+
ranges.push({ start: stmtStart, end: stmtEnd, isDecl });
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
// If there are no body ranges, nothing to wrap
|
|
1023
|
+
if (ranges.every(r => r.isDecl)) {
|
|
1024
|
+
return text;
|
|
1025
|
+
}
|
|
1026
|
+
// Build the new source text
|
|
1027
|
+
const declarations = [];
|
|
1028
|
+
const bodyParts = [];
|
|
1029
|
+
for (const r of ranges) {
|
|
1030
|
+
const slice = text.substring(r.start, r.end);
|
|
1031
|
+
if (r.isDecl)
|
|
1032
|
+
declarations.push(slice);
|
|
1033
|
+
else
|
|
1034
|
+
bodyParts.push(slice);
|
|
1035
|
+
}
|
|
1036
|
+
// turn the last body part into a return statement
|
|
1037
|
+
// (if it isn't already one and doesn't start with a statement keyword)
|
|
1038
|
+
if (bodyParts.length > 0) {
|
|
1039
|
+
let last = bodyParts[bodyParts.length - 1].trim();
|
|
1040
|
+
// remove trailing semicolon for wrapping
|
|
1041
|
+
if (last.endsWith(";"))
|
|
1042
|
+
last = last.slice(0, -1).trim();
|
|
1043
|
+
const firstWord = last.match(/^([a-zA-Z_]\w*)/);
|
|
1044
|
+
const isStmtKeyword = firstWord && _stmtKeywords.has(firstWord[1]);
|
|
1045
|
+
if (!isStmtKeyword && !last.startsWith("return")) {
|
|
1046
|
+
bodyParts[bodyParts.length - 1] = "return " + last + ";";
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return (declarations.join("\n") +
|
|
1050
|
+
(declarations.length > 0 ? "\n" : "") +
|
|
1051
|
+
"function " + funcName + "() {\n" +
|
|
1052
|
+
bodyParts.join("\n") + "\n" +
|
|
1053
|
+
"}\n");
|
|
1054
|
+
}
|
|
1055
|
+
const _stmtKeywords = new Set([
|
|
1056
|
+
"let", "var", "const", "using",
|
|
1057
|
+
"if", "for", "while", "match",
|
|
1058
|
+
"return", "break", "continue",
|
|
1059
|
+
"trace", "assert", "fail", "test",
|
|
1060
|
+
]);
|
|
845
1061
|
function _isWhitespace(ch) {
|
|
846
1062
|
return ch === 0x20 || ch === 0x09 || ch === 0x0A || ch === 0x0D;
|
|
847
1063
|
}
|
|
@@ -44,6 +44,7 @@ import { TraceStmt } from "../../../../ast/nodes/statements/TraceStmt.js";
|
|
|
44
44
|
import { UsingStmt } from "../../../../ast/nodes/statements/UsingStmt.js";
|
|
45
45
|
import { VarStmt } from "../../../../ast/nodes/statements/VarStmt.js";
|
|
46
46
|
import { WhileStmt } from "../../../../ast/nodes/statements/WhileStmt.js";
|
|
47
|
+
import { SourceRange } from "../../../../ast/Source/SourceRange.js";
|
|
47
48
|
import { CommonFlags } from "../../../../common.js";
|
|
48
49
|
import { DiagnosticCode } from "../../../../diagnostics/diagnosticMessages.generated.js";
|
|
49
50
|
import { getUniqueInternalName } from "../../../internalVar.js";
|
|
@@ -89,6 +90,9 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
89
90
|
//
|
|
90
91
|
// so we only have 3 statements in the body
|
|
91
92
|
const bodyStmts = [];
|
|
93
|
+
// generated identifiers/declarations use mock ranges so they don't
|
|
94
|
+
// produce SourceTypeMap entries (which would span the entire contract)
|
|
95
|
+
const mockRange = SourceRange.mock;
|
|
92
96
|
const txUniqueName = getUniqueInternalName("tx");
|
|
93
97
|
const purposeUniqueName = getUniqueInternalName("purpose");
|
|
94
98
|
const redeemerUniqueName = getUniqueInternalName("redeemer");
|
|
@@ -96,20 +100,20 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
96
100
|
// fields
|
|
97
101
|
new Map([
|
|
98
102
|
[
|
|
99
|
-
new Identifier("tx",
|
|
100
|
-
SimpleVarDecl.onlyNameConst(txUniqueName,
|
|
103
|
+
new Identifier("tx", mockRange),
|
|
104
|
+
SimpleVarDecl.onlyNameConst(txUniqueName, mockRange)
|
|
101
105
|
],
|
|
102
106
|
[
|
|
103
|
-
new Identifier("purpose",
|
|
104
|
-
SimpleVarDecl.onlyNameConst(purposeUniqueName,
|
|
107
|
+
new Identifier("purpose", mockRange),
|
|
108
|
+
SimpleVarDecl.onlyNameConst(purposeUniqueName, mockRange)
|
|
105
109
|
],
|
|
106
110
|
[
|
|
107
|
-
new Identifier("redeemer",
|
|
108
|
-
SimpleVarDecl.onlyNameConst(redeemerUniqueName,
|
|
111
|
+
new Identifier("redeemer", mockRange),
|
|
112
|
+
SimpleVarDecl.onlyNameConst(redeemerUniqueName, mockRange)
|
|
109
113
|
],
|
|
110
114
|
]), undefined, // rest
|
|
111
115
|
undefined, // type (inferred from initExpr)
|
|
112
|
-
new Identifier(scriptContextName,
|
|
116
|
+
new Identifier(scriptContextName, mockRange), // initExpr
|
|
113
117
|
CommonFlags.Const, contractRange)], contractRange));
|
|
114
118
|
/*
|
|
115
119
|
const { data: scriptInfo_t } = defineMultiConstructorStruct(
|
|
@@ -144,12 +148,12 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
144
148
|
const optionalDatumUniqueName = getUniqueInternalName("optionalDatum");
|
|
145
149
|
const fields = new Map([
|
|
146
150
|
[
|
|
147
|
-
new Identifier("ref",
|
|
148
|
-
SimpleVarDecl.onlyNameConst(spendingRefUniqueName,
|
|
151
|
+
new Identifier("ref", mockRange),
|
|
152
|
+
SimpleVarDecl.onlyNameConst(spendingRefUniqueName, mockRange)
|
|
149
153
|
],
|
|
150
154
|
[
|
|
151
|
-
new Identifier("optionalDatum",
|
|
152
|
-
SimpleVarDecl.onlyNameConst(optionalDatumUniqueName,
|
|
155
|
+
new Identifier("optionalDatum", mockRange),
|
|
156
|
+
SimpleVarDecl.onlyNameConst(optionalDatumUniqueName, mockRange)
|
|
153
157
|
],
|
|
154
158
|
]);
|
|
155
159
|
const bodyStmts = _getMatchedPurposeBlockStatements(compiler, contractDecl.spendMethods, paramsInternalNamesMap,
|
|
@@ -163,7 +167,7 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
163
167
|
}), "SpendRedeemer", contractRange);
|
|
164
168
|
if (!Array.isArray(bodyStmts))
|
|
165
169
|
return undefined;
|
|
166
|
-
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Spend",
|
|
170
|
+
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Spend", mockRange), fields, undefined, // rest
|
|
167
171
|
undefined, // type (inferred from initExpr)
|
|
168
172
|
undefined, // initExpr
|
|
169
173
|
CommonFlags.Const, contractRange), new BlockStmt(bodyStmts, contractRange), contractRange));
|
|
@@ -172,8 +176,8 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
172
176
|
const policyUniqueName = getUniqueInternalName("policy");
|
|
173
177
|
const fields = new Map([
|
|
174
178
|
[
|
|
175
|
-
new Identifier("policy",
|
|
176
|
-
SimpleVarDecl.onlyNameConst(policyUniqueName,
|
|
179
|
+
new Identifier("policy", mockRange),
|
|
180
|
+
SimpleVarDecl.onlyNameConst(policyUniqueName, mockRange)
|
|
177
181
|
],
|
|
178
182
|
]);
|
|
179
183
|
const bodyStmts = _getMatchedPurposeBlockStatements(compiler, contractDecl.mintMethods, paramsInternalNamesMap,
|
|
@@ -186,7 +190,7 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
186
190
|
}), "MintRedeemer", contractRange);
|
|
187
191
|
if (!Array.isArray(bodyStmts))
|
|
188
192
|
return undefined;
|
|
189
|
-
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Mint",
|
|
193
|
+
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Mint", mockRange), fields, undefined, // rest
|
|
190
194
|
undefined, // type (inferred from initExpr)
|
|
191
195
|
undefined, // initExpr
|
|
192
196
|
CommonFlags.Const, contractRange), new BlockStmt(bodyStmts, contractRange), contractRange));
|
|
@@ -195,8 +199,8 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
195
199
|
const credentialUniqueName = getUniqueInternalName("credential");
|
|
196
200
|
const fields = new Map([
|
|
197
201
|
[
|
|
198
|
-
new Identifier("credential",
|
|
199
|
-
SimpleVarDecl.onlyNameConst(credentialUniqueName,
|
|
202
|
+
new Identifier("credential", mockRange),
|
|
203
|
+
SimpleVarDecl.onlyNameConst(credentialUniqueName, mockRange)
|
|
200
204
|
],
|
|
201
205
|
]);
|
|
202
206
|
const bodyStmts = _getMatchedPurposeBlockStatements(compiler, contractDecl.withdrawMethods, paramsInternalNamesMap,
|
|
@@ -209,7 +213,7 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
209
213
|
}), "WithdrawRedeemer", contractRange);
|
|
210
214
|
if (!Array.isArray(bodyStmts))
|
|
211
215
|
return undefined;
|
|
212
|
-
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Withdraw",
|
|
216
|
+
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Withdraw", mockRange), fields, undefined, // rest
|
|
213
217
|
undefined, // type (inferred from initExpr)
|
|
214
218
|
undefined, // initExpr
|
|
215
219
|
CommonFlags.Const, contractRange), new BlockStmt(bodyStmts, contractRange), contractRange));
|
|
@@ -219,12 +223,12 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
219
223
|
const certificateUniqueName = getUniqueInternalName("certificate");
|
|
220
224
|
const fields = new Map([
|
|
221
225
|
[
|
|
222
|
-
new Identifier("certificateIndex",
|
|
223
|
-
SimpleVarDecl.onlyNameConst(indexUniqueName,
|
|
226
|
+
new Identifier("certificateIndex", mockRange),
|
|
227
|
+
SimpleVarDecl.onlyNameConst(indexUniqueName, mockRange)
|
|
224
228
|
],
|
|
225
229
|
[
|
|
226
|
-
new Identifier("certificate",
|
|
227
|
-
SimpleVarDecl.onlyNameConst(certificateUniqueName,
|
|
230
|
+
new Identifier("certificate", mockRange),
|
|
231
|
+
SimpleVarDecl.onlyNameConst(certificateUniqueName, mockRange)
|
|
228
232
|
],
|
|
229
233
|
]);
|
|
230
234
|
const bodyStmts = _getMatchedPurposeBlockStatements(compiler, contractDecl.certifyMethods, paramsInternalNamesMap,
|
|
@@ -238,7 +242,7 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
238
242
|
}), "CertifyRedeemer", contractRange);
|
|
239
243
|
if (!Array.isArray(bodyStmts))
|
|
240
244
|
return undefined;
|
|
241
|
-
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Certificate",
|
|
245
|
+
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Certificate", mockRange), fields, undefined, // rest
|
|
242
246
|
undefined, // type (inferred from initExpr)
|
|
243
247
|
undefined, // initExpr
|
|
244
248
|
CommonFlags.Const, contractRange), new BlockStmt(bodyStmts, contractRange), contractRange));
|
|
@@ -248,12 +252,12 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
248
252
|
const proposalUniqueName = getUniqueInternalName("proposal");
|
|
249
253
|
const fields = new Map([
|
|
250
254
|
[
|
|
251
|
-
new Identifier("proposalIndex",
|
|
252
|
-
SimpleVarDecl.onlyNameConst(indexUniqueName,
|
|
255
|
+
new Identifier("proposalIndex", mockRange),
|
|
256
|
+
SimpleVarDecl.onlyNameConst(indexUniqueName, mockRange)
|
|
253
257
|
],
|
|
254
258
|
[
|
|
255
|
-
new Identifier("proposal",
|
|
256
|
-
SimpleVarDecl.onlyNameConst(proposalUniqueName,
|
|
259
|
+
new Identifier("proposal", mockRange),
|
|
260
|
+
SimpleVarDecl.onlyNameConst(proposalUniqueName, mockRange)
|
|
257
261
|
],
|
|
258
262
|
]);
|
|
259
263
|
const bodyStmts = _getMatchedPurposeBlockStatements(compiler, contractDecl.proposeMethods, paramsInternalNamesMap,
|
|
@@ -267,7 +271,7 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
267
271
|
}), "ProposeRedeemer", contractRange);
|
|
268
272
|
if (!Array.isArray(bodyStmts))
|
|
269
273
|
return undefined;
|
|
270
|
-
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Propose",
|
|
274
|
+
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Propose", mockRange), fields, undefined, // rest
|
|
271
275
|
undefined, // type (inferred from initExpr)
|
|
272
276
|
undefined, // initExpr
|
|
273
277
|
CommonFlags.Const, contractRange), new BlockStmt(bodyStmts, contractRange), contractRange));
|
|
@@ -276,8 +280,8 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
276
280
|
const voterUniqueName = getUniqueInternalName("voter");
|
|
277
281
|
const fields = new Map([
|
|
278
282
|
[
|
|
279
|
-
new Identifier("voter",
|
|
280
|
-
SimpleVarDecl.onlyNameConst(voterUniqueName,
|
|
283
|
+
new Identifier("voter", mockRange),
|
|
284
|
+
SimpleVarDecl.onlyNameConst(voterUniqueName, mockRange)
|
|
281
285
|
],
|
|
282
286
|
]);
|
|
283
287
|
const bodyStmts = _getMatchedPurposeBlockStatements(compiler, contractDecl.voteMethods, paramsInternalNamesMap,
|
|
@@ -290,12 +294,12 @@ export function _deriveContractBody(compiler, contractDecl, paramsInternalNamesM
|
|
|
290
294
|
}), "VoteRedeemer", contractRange);
|
|
291
295
|
if (!Array.isArray(bodyStmts))
|
|
292
296
|
return undefined;
|
|
293
|
-
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Vote",
|
|
297
|
+
purposeMatchCases.push(new MatchStmtCase(new NamedDeconstructVarDecl(new Identifier("Vote", mockRange), fields, undefined, // rest
|
|
294
298
|
undefined, // type (inferred from initExpr)
|
|
295
299
|
undefined, // initExpr
|
|
296
300
|
CommonFlags.Const, contractRange), new BlockStmt(bodyStmts, contractRange), contractRange));
|
|
297
301
|
}
|
|
298
|
-
bodyStmts.push(new MatchStmt(new Identifier(purposeUniqueName,
|
|
302
|
+
bodyStmts.push(new MatchStmt(new Identifier(purposeUniqueName, mockRange), purposeMatchCases, new MatchStmtElseCase(new FailStmt(undefined, contractRange), contractRange), contractRange));
|
|
299
303
|
bodyStmts.push(new FailStmt(undefined, contractRange)); // unreachable in theory (else case)
|
|
300
304
|
return new BlockStmt(bodyStmts, contractRange);
|
|
301
305
|
}
|
|
@@ -336,8 +340,9 @@ function _getMatchedPurposeBlockStatements(compiler, methods, paramsInternalName
|
|
|
336
340
|
CommonFlags.Const, method.expr.name.range), new BlockStmt(stmts, contractRange), method.expr.range));
|
|
337
341
|
}
|
|
338
342
|
return [
|
|
339
|
-
new MatchStmt(new TypeConversionExpr(new Identifier(contextVarsMapping.redeemerData,
|
|
340
|
-
contractRange)
|
|
343
|
+
new MatchStmt(new TypeConversionExpr(new Identifier(contextVarsMapping.redeemerData, SourceRange.mock), new AstNamedTypeExpr(new Identifier(redeemerTypeDef.name.text, SourceRange.mock), [], // typeArgs
|
|
344
|
+
contractRange), SourceRange.mock // mock range: generated expression should not appear in SourceTypeMap
|
|
345
|
+
), redeemerMatchCases, new MatchStmtElseCase(new FailStmt(undefined, contractRange), contractRange), contractRange),
|
|
341
346
|
new FailStmt(undefined, contractRange) // unreachable in theory (else case)
|
|
342
347
|
];
|
|
343
348
|
}
|
|
@@ -759,7 +764,7 @@ function _deriveRedeemerTypeDef(redeemerName, methods, contractRange) {
|
|
|
759
764
|
if (methods.length <= 1)
|
|
760
765
|
defFlags |= StructDeclAstFlags.untaggedSingleConstructor;
|
|
761
766
|
const uniqueName = getUniqueInternalName(redeemerName);
|
|
762
|
-
return new StructDecl(new Identifier(uniqueName,
|
|
767
|
+
return new StructDecl(new Identifier(uniqueName, SourceRange.mock), [], // typeParams
|
|
763
768
|
methods.map(m => {
|
|
764
769
|
const methodParams = m.expr.signature.params;
|
|
765
770
|
if (!methodParams.every(p => p instanceof SimpleVarDecl && !p.initExpr && p.type))
|
|
@@ -23,7 +23,11 @@ export declare function _compileSingleDeconstructVarDecl(ctx: AstCompilationCtx,
|
|
|
23
23
|
export declare function _compileArrayLikeDeconstr(ctx: AstCompilationCtx, decl: ArrayLikeDeconstr, typeHint: TirType | undefined): TirArrayLikeDeconstr | undefined;
|
|
24
24
|
export declare function _getDeconstructedFields(ctx: AstCompilationCtx, astDeconstruct: ISingleDeconstructVarDecl, ctorDef: TirStructConstr): [
|
|
25
25
|
fields: Map<string, TirVarDecl>,
|
|
26
|
-
rest: string | undefined
|
|
26
|
+
rest: string | undefined,
|
|
27
|
+
fieldLabelRanges: Map<string, {
|
|
28
|
+
range: SourceRange;
|
|
29
|
+
type: TirType;
|
|
30
|
+
}>
|
|
27
31
|
] | undefined;
|
|
28
32
|
export declare function _getVarDeclTypeAndExpr(ctx: AstCompilationCtx, decl: {
|
|
29
33
|
type: AstTypeExpr | undefined;
|
|
@@ -31,5 +35,6 @@ export declare function _getVarDeclTypeAndExpr(ctx: AstCompilationCtx, decl: {
|
|
|
31
35
|
range: SourceRange;
|
|
32
36
|
}, deconstructTypeHint: TirType | undefined): [
|
|
33
37
|
varType: TirType,
|
|
34
|
-
varInitExpr: TirExpr | undefined
|
|
38
|
+
varInitExpr: TirExpr | undefined,
|
|
39
|
+
typeAnnotationRange: SourceRange | undefined
|
|
35
40
|
] | undefined;
|