@harmoniclabs/pebble 0.1.3-dev3 → 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.
@@ -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
- constructor(name: Identifier, type: AstTypeExpr | undefined, initExpr: PebbleExpr | undefined, flags: CommonFlags, range: SourceRange);
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
- constructor(name, type, initExpr, flags, range) {
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, RUN_FUNC_NAME);
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
- while (msg = this.diagnostics.shift()) {
158
- /*
159
- this.io.stdout.write( msg.toString() + "\n" );
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", contractRange),
100
- SimpleVarDecl.onlyNameConst(txUniqueName, contractRange)
103
+ new Identifier("tx", mockRange),
104
+ SimpleVarDecl.onlyNameConst(txUniqueName, mockRange)
101
105
  ],
102
106
  [
103
- new Identifier("purpose", contractRange),
104
- SimpleVarDecl.onlyNameConst(purposeUniqueName, contractRange)
107
+ new Identifier("purpose", mockRange),
108
+ SimpleVarDecl.onlyNameConst(purposeUniqueName, mockRange)
105
109
  ],
106
110
  [
107
- new Identifier("redeemer", contractRange),
108
- SimpleVarDecl.onlyNameConst(redeemerUniqueName, contractRange)
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, contractRange), // initExpr
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", contractRange),
148
- SimpleVarDecl.onlyNameConst(spendingRefUniqueName, contractRange)
151
+ new Identifier("ref", mockRange),
152
+ SimpleVarDecl.onlyNameConst(spendingRefUniqueName, mockRange)
149
153
  ],
150
154
  [
151
- new Identifier("optionalDatum", contractRange),
152
- SimpleVarDecl.onlyNameConst(optionalDatumUniqueName, contractRange)
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", contractRange), fields, undefined, // rest
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", contractRange),
176
- SimpleVarDecl.onlyNameConst(policyUniqueName, contractRange)
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", contractRange), fields, undefined, // rest
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", contractRange),
199
- SimpleVarDecl.onlyNameConst(credentialUniqueName, contractRange)
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", contractRange), fields, undefined, // rest
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", contractRange),
223
- SimpleVarDecl.onlyNameConst(indexUniqueName, contractRange)
226
+ new Identifier("certificateIndex", mockRange),
227
+ SimpleVarDecl.onlyNameConst(indexUniqueName, mockRange)
224
228
  ],
225
229
  [
226
- new Identifier("certificate", contractRange),
227
- SimpleVarDecl.onlyNameConst(certificateUniqueName, contractRange)
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", contractRange), fields, undefined, // rest
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", contractRange),
252
- SimpleVarDecl.onlyNameConst(indexUniqueName, contractRange)
255
+ new Identifier("proposalIndex", mockRange),
256
+ SimpleVarDecl.onlyNameConst(indexUniqueName, mockRange)
253
257
  ],
254
258
  [
255
- new Identifier("proposal", contractRange),
256
- SimpleVarDecl.onlyNameConst(proposalUniqueName, contractRange)
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", contractRange), fields, undefined, // rest
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", contractRange),
280
- SimpleVarDecl.onlyNameConst(voterUniqueName, contractRange)
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", contractRange), fields, undefined, // rest
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, contractRange), purposeMatchCases, new MatchStmtElseCase(new FailStmt(undefined, contractRange), contractRange), contractRange));
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, contractRange), new AstNamedTypeExpr(new Identifier(redeemerTypeDef.name.text, contractRange), [], // typeArgs
340
- contractRange)), redeemerMatchCases, new MatchStmtElseCase(new FailStmt(undefined, contractRange), contractRange), 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, contractRange), [], // typeParams
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;