From 8fa154926f6a9d7107a77701608cc3fd361a983c Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 18 Dec 2024 03:21:50 +0400 Subject: [PATCH 1/5] refactor: abstract away SrcInfo interface --- src/errors.ts | 3 ++- src/grammar/ast.ts | 3 +-- src/grammar/grammar.spec.ts | 4 ++-- src/grammar/grammar.ts | 10 +++------ src/grammar/index.ts | 4 ++-- src/grammar/rename.ts | 2 +- src/grammar/src-info.ts | 32 ++++++++++++++++++++++++++-- src/types/resolveDescriptors.spec.ts | 3 ++- 8 files changed, 43 insertions(+), 18 deletions(-) diff --git a/src/errors.ts b/src/errors.ts index eee766790..adb2704b0 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -3,6 +3,7 @@ import path from "path"; import { cwd } from "process"; import { AstFuncId, AstId, AstTypeId } from "./grammar/ast"; import { ItemOrigin, SrcInfo } from "./grammar"; +import { OhmSrcInfo } from "./grammar/src-info"; export class TactError extends Error { readonly loc?: SrcInfo; @@ -64,7 +65,7 @@ export function throwParseError( origin: ItemOrigin, ): never { const interval = matchResult.getInterval(); - const source = new SrcInfo(interval, path, origin); + const source = new OhmSrcInfo(interval, path, origin); // eslint-disable-next-line @typescript-eslint/no-explicit-any const message = `Parse error: expected ${(matchResult as any).getExpectedText()}\n`; throw new TactParseError( diff --git a/src/grammar/ast.ts b/src/grammar/ast.ts index f9d54810b..58b9c5a3a 100644 --- a/src/grammar/ast.ts +++ b/src/grammar/ast.ts @@ -1,5 +1,4 @@ -import { dummySrcInfo } from "./grammar"; -import { SrcInfo } from "./src-info"; +import { dummySrcInfo, SrcInfo } from "./src-info"; export type AstModule = { kind: "module"; diff --git a/src/grammar/grammar.spec.ts b/src/grammar/grammar.spec.ts index 7af9c64dc..3c1d6c367 100644 --- a/src/grammar/grammar.spec.ts +++ b/src/grammar/grammar.spec.ts @@ -1,10 +1,10 @@ import { AstModule, getAstFactory } from "./ast"; import { loadCases } from "../utils/loadCases"; import { getParser } from "./grammar"; -import { SrcInfo } from "./src-info"; +import { OhmSrcInfo, SrcInfo } from "./src-info"; expect.addSnapshotSerializer({ - test: (src) => src instanceof SrcInfo, + test: (src) => src instanceof OhmSrcInfo, print: (src) => (src as SrcInfo).contents, }); diff --git a/src/grammar/grammar.ts b/src/grammar/grammar.ts index 069333659..f75665e0f 100644 --- a/src/grammar/grammar.ts +++ b/src/grammar/grammar.ts @@ -1,4 +1,4 @@ -import { Node, IterationNode, NonterminalNode, grammar, Grammar } from "ohm-js"; +import { Node, IterationNode, NonterminalNode } from "ohm-js"; import tactGrammar from "./grammar.ohm-bundle"; import { throwInternalCompilerError } from "../errors"; import { @@ -22,11 +22,7 @@ import { throwParseError, throwSyntaxError } from "../errors"; import { checkVariableName } from "./checkVariableName"; import { checkFunctionAttributes } from "./checkFunctionAttributes"; import { checkConstAttributes } from "./checkConstAttributes"; -import { ItemOrigin, SrcInfo } from "./src-info"; - -const DummyGrammar: Grammar = grammar("Dummy { DummyRule = any }"); -const DUMMY_INTERVAL = DummyGrammar.match("").getInterval(); -export const dummySrcInfo: SrcInfo = new SrcInfo(DUMMY_INTERVAL, null, "user"); +import { ItemOrigin, OhmSrcInfo, SrcInfo } from "./src-info"; type Context = { origin: ItemOrigin | null; @@ -56,7 +52,7 @@ function createRef(s: Node): SrcInfo { throwInternalCompilerError("Parser context was not initialized"); } - return new SrcInfo(s.source, context.currentFile, context.origin); + return new OhmSrcInfo(s.source, context.currentFile, context.origin); } const createNode: FactoryAst["createNode"] = (...args) => { diff --git a/src/grammar/index.ts b/src/grammar/index.ts index 749fc50c3..dd5411a2e 100644 --- a/src/grammar/index.ts +++ b/src/grammar/index.ts @@ -1,3 +1,3 @@ -export { dummySrcInfo, getParser, Parser } from "./grammar"; +export { getParser, Parser } from "./grammar"; -export { ItemOrigin, SrcInfo } from "./src-info"; +export { dummySrcInfo, ItemOrigin, SrcInfo } from "./src-info"; diff --git a/src/grammar/rename.ts b/src/grammar/rename.ts index 391ab1051..fb3960148 100644 --- a/src/grammar/rename.ts +++ b/src/grammar/rename.ts @@ -19,7 +19,7 @@ import { } from "./ast"; import { AstSorter } from "./sort"; import { AstHasher, AstHash } from "./hash"; -import { dummySrcInfo } from "./grammar"; +import { dummySrcInfo } from "./src-info"; type GivenName = string; diff --git a/src/grammar/src-info.ts b/src/grammar/src-info.ts index 54ddf7248..19a9d7046 100644 --- a/src/grammar/src-info.ts +++ b/src/grammar/src-info.ts @@ -1,12 +1,33 @@ -import { Interval as RawInterval } from "ohm-js"; +import { grammar, Grammar, Interval as RawInterval } from "ohm-js"; export type ItemOrigin = "stdlib" | "user"; +export type LineAndColumnInfo = { + lineNum: number; + colNum: number; + toString(...ranges: number[][]): string; +} + +export type AbstractInterval = { + contents: string; + getLineAndColumnMessage(): string; + getLineAndColumn(): LineAndColumnInfo; + startIdx: number; + endIdx: number; +}; + +interface AbstractSrcInfo { + file: string | null; + contents: string; + interval: AbstractInterval; + origin: ItemOrigin; +} + /** * Information about source code location (file and interval within it) * and the source code contents. */ -export class SrcInfo { +class SrcInfo implements AbstractSrcInfo { readonly #interval: RawInterval; readonly #file: string | null; readonly #origin: ItemOrigin; @@ -37,3 +58,10 @@ export class SrcInfo { return this.#origin; } } + +const DummyGrammar: Grammar = grammar("Dummy { DummyRule = any }"); +const DUMMY_INTERVAL = DummyGrammar.match("").getInterval(); +export const dummySrcInfo: SrcInfo = new SrcInfo(DUMMY_INTERVAL, null, "user"); + +// Rename is here so that OhmSrcInfo is called SrcInfo in snapshots, as it previously did +export { AbstractSrcInfo as SrcInfo, SrcInfo as OhmSrcInfo }; diff --git a/src/types/resolveDescriptors.spec.ts b/src/types/resolveDescriptors.spec.ts index ac966baf9..2f88222b5 100644 --- a/src/types/resolveDescriptors.spec.ts +++ b/src/types/resolveDescriptors.spec.ts @@ -10,9 +10,10 @@ import { openContext } from "../grammar/store"; import { featureEnable } from "../config/features"; import { getParser, SrcInfo } from "../grammar"; import { getAstFactory } from "../grammar/ast"; +import { OhmSrcInfo } from "../grammar/src-info"; expect.addSnapshotSerializer({ - test: (src) => src instanceof SrcInfo, + test: (src) => src instanceof OhmSrcInfo, print: (src) => (src as SrcInfo).contents, }); From cd42d4e879331114cf1f6a2fbe5e9ad6106844b4 Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 18 Dec 2024 03:28:06 +0400 Subject: [PATCH 2/5] refactor: plain dummySrcInfo --- src/grammar/src-info.ts | 23 +++++-- .../resolveDescriptors.spec.ts.snap | 65 +++++++++++++++++-- 2 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/grammar/src-info.ts b/src/grammar/src-info.ts index 19a9d7046..8c72cab23 100644 --- a/src/grammar/src-info.ts +++ b/src/grammar/src-info.ts @@ -1,4 +1,4 @@ -import { grammar, Grammar, Interval as RawInterval } from "ohm-js"; +import { Interval as RawInterval } from "ohm-js"; export type ItemOrigin = "stdlib" | "user"; @@ -59,9 +59,24 @@ class SrcInfo implements AbstractSrcInfo { } } -const DummyGrammar: Grammar = grammar("Dummy { DummyRule = any }"); -const DUMMY_INTERVAL = DummyGrammar.match("").getInterval(); -export const dummySrcInfo: SrcInfo = new SrcInfo(DUMMY_INTERVAL, null, "user"); +export const dummySrcInfo: AbstractSrcInfo = { + contents: '', + file: null, + interval: { + contents: '', + startIdx: 0, + endIdx: 0, + getLineAndColumn: () => ({ + colNum: 1, + lineNum: 1, + toString: () => { + throw new Error(); + }, + }), + getLineAndColumnMessage: () => 'Line 1, col 1:\n> 1 | \n ^\n', + }, + origin: 'user', +}; // Rename is here so that OhmSrcInfo is called SrcInfo in snapshots, as it previously did export { AbstractSrcInfo as SrcInfo, SrcInfo as OhmSrcInfo }; diff --git a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap index dc4bb74f7..2141c6921 100644 --- a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap +++ b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap @@ -2077,7 +2077,18 @@ exports[`resolveDescriptors should resolve descriptors for contract-bounced-slic "base": 10, "id": 0, "kind": "number", - "loc": , + "loc": { + "contents": "", + "file": null, + "interval": { + "contents": "", + "endIdx": 0, + "getLineAndColumn": [Function], + "getLineAndColumnMessage": [Function], + "startIdx": 0, + }, + "origin": "user", + }, "value": 3746466057n, }, "init": null, @@ -2644,7 +2655,18 @@ exports[`resolveDescriptors should resolve descriptors for contract-bounced-too- "base": 10, "id": 0, "kind": "number", - "loc": , + "loc": { + "contents": "", + "file": null, + "interval": { + "contents": "", + "endIdx": 0, + "getLineAndColumn": [Function], + "getLineAndColumnMessage": [Function], + "startIdx": 0, + }, + "origin": "user", + }, "value": 2219696518n, }, "init": null, @@ -4113,7 +4135,18 @@ exports[`resolveDescriptors should resolve descriptors for contract-external-fal "base": 10, "id": 0, "kind": "number", - "loc": , + "loc": { + "contents": "", + "file": null, + "interval": { + "contents": "", + "endIdx": 0, + "getLineAndColumn": [Function], + "getLineAndColumnMessage": [Function], + "startIdx": 0, + }, + "origin": "user", + }, "value": 3746466057n, }, "init": null, @@ -9281,7 +9314,18 @@ exports[`resolveDescriptors should resolve descriptors for message-opcode-expr 1 "base": 10, "id": 0, "kind": "number", - "loc": , + "loc": { + "contents": "", + "file": null, + "interval": { + "contents": "", + "endIdx": 0, + "getLineAndColumn": [Function], + "getLineAndColumnMessage": [Function], + "startIdx": 0, + }, + "origin": "user", + }, "value": 898001897n, }, "init": null, @@ -10582,7 +10626,18 @@ exports[`resolveDescriptors should resolve descriptors for struct-decl-non-rec-t "base": 10, "id": 0, "kind": "number", - "loc": , + "loc": { + "contents": "", + "file": null, + "interval": { + "contents": "", + "endIdx": 0, + "getLineAndColumn": [Function], + "getLineAndColumnMessage": [Function], + "startIdx": 0, + }, + "origin": "user", + }, "value": 383013829n, }, "init": null, From ce0a6d5a34aa2d3abf6ec800388108da3d26773b Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:44:33 +0400 Subject: [PATCH 3/5] feat: replace error printer from Ohm --- src/errors.ts | 4 +- src/grammar/grammar.spec.ts | 4 +- src/grammar/grammar.ts | 4 +- src/grammar/src-info.ts | 297 ++++++++++++--- .../resolveAllocation.spec.ts.snap | 356 +++++++++--------- .../resolveDescriptors.spec.ts.snap | 65 +--- src/types/resolveDescriptors.spec.ts | 4 +- 7 files changed, 439 insertions(+), 295 deletions(-) diff --git a/src/errors.ts b/src/errors.ts index adb2704b0..3bceaeffa 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -3,7 +3,7 @@ import path from "path"; import { cwd } from "process"; import { AstFuncId, AstId, AstTypeId } from "./grammar/ast"; import { ItemOrigin, SrcInfo } from "./grammar"; -import { OhmSrcInfo } from "./grammar/src-info"; +import { getSrcInfoFromOhm } from "./grammar/src-info"; export class TactError extends Error { readonly loc?: SrcInfo; @@ -65,7 +65,7 @@ export function throwParseError( origin: ItemOrigin, ): never { const interval = matchResult.getInterval(); - const source = new OhmSrcInfo(interval, path, origin); + const source = getSrcInfoFromOhm(interval, path, origin); // eslint-disable-next-line @typescript-eslint/no-explicit-any const message = `Parse error: expected ${(matchResult as any).getExpectedText()}\n`; throw new TactParseError( diff --git a/src/grammar/grammar.spec.ts b/src/grammar/grammar.spec.ts index 3c1d6c367..ee7d75f18 100644 --- a/src/grammar/grammar.spec.ts +++ b/src/grammar/grammar.spec.ts @@ -1,10 +1,10 @@ import { AstModule, getAstFactory } from "./ast"; import { loadCases } from "../utils/loadCases"; import { getParser } from "./grammar"; -import { OhmSrcInfo, SrcInfo } from "./src-info"; +import { SrcInfo, isSrcInfo } from "./src-info"; expect.addSnapshotSerializer({ - test: (src) => src instanceof OhmSrcInfo, + test: (src) => isSrcInfo(src), print: (src) => (src as SrcInfo).contents, }); diff --git a/src/grammar/grammar.ts b/src/grammar/grammar.ts index f75665e0f..09acefac8 100644 --- a/src/grammar/grammar.ts +++ b/src/grammar/grammar.ts @@ -22,7 +22,7 @@ import { throwParseError, throwSyntaxError } from "../errors"; import { checkVariableName } from "./checkVariableName"; import { checkFunctionAttributes } from "./checkFunctionAttributes"; import { checkConstAttributes } from "./checkConstAttributes"; -import { ItemOrigin, OhmSrcInfo, SrcInfo } from "./src-info"; +import { getSrcInfoFromOhm, ItemOrigin, SrcInfo } from "./src-info"; type Context = { origin: ItemOrigin | null; @@ -52,7 +52,7 @@ function createRef(s: Node): SrcInfo { throwInternalCompilerError("Parser context was not initialized"); } - return new OhmSrcInfo(s.source, context.currentFile, context.origin); + return getSrcInfoFromOhm(s.source, context.currentFile, context.origin); } const createNode: FactoryAst["createNode"] = (...args) => { diff --git a/src/grammar/src-info.ts b/src/grammar/src-info.ts index 8c72cab23..f807e10c9 100644 --- a/src/grammar/src-info.ts +++ b/src/grammar/src-info.ts @@ -1,5 +1,7 @@ import { Interval as RawInterval } from "ohm-js"; +import { throwInternalCompilerError } from "../errors"; + export type ItemOrigin = "stdlib" | "user"; export type LineAndColumnInfo = { @@ -8,7 +10,7 @@ export type LineAndColumnInfo = { toString(...ranges: number[][]): string; } -export type AbstractInterval = { +export type Interval = { contents: string; getLineAndColumnMessage(): string; getLineAndColumn(): LineAndColumnInfo; @@ -16,67 +18,264 @@ export type AbstractInterval = { endIdx: number; }; -interface AbstractSrcInfo { +// Do not export! Use isSrcInfo +const srcInfoSymbol = Symbol('src-info'); + +export const isSrcInfo = (t: unknown): t is SrcInfo => { + return typeof t === 'object' && t !== null && srcInfoSymbol in t && Boolean(t[srcInfoSymbol]); +}; + +export interface SrcInfo { file: string | null; contents: string; - interval: AbstractInterval; + interval: Interval; origin: ItemOrigin; + + /** + * Tag so that custom snapshot serializer can distinguish it + */ + [srcInfoSymbol]: true; + /** + * toJSON method is provided, so that it's not serialized into snapshots + */ + toJSON: () => object, +} + +const isEndline = (s: string) => s === '\n'; + +const repeat = (s: string, n: number): string => new Array(n + 1).join(s); + +type Range = { + start: number; + end: number; +} + +const intersect = (a: Range, b: Range): Range => { + return { + start: Math.max(a.start, b.start), + end: Math.min(a.end, b.end), + }; +}; + +const shift = (a: Range, b: number) => { + return { + start: a.start + b, + end: a.end + b, + }; +}; + +type Line = { + id: number; + text: string; + range: Range; } /** - * Information about source code location (file and interval within it) - * and the source code contents. + * Convert code into a list of lines */ -class SrcInfo implements AbstractSrcInfo { - readonly #interval: RawInterval; - readonly #file: string | null; - readonly #origin: ItemOrigin; - - constructor( - interval: RawInterval, - file: string | null, - origin: ItemOrigin, - ) { - this.#interval = interval; - this.#file = file; - this.#origin = origin; +const toLines = (source: string): Line[] => { + const result: Line[] = []; + let position = 0; + for (const [id, text] of source.split('\n').entries()) { + result.push({ + id, + text, + range: { + start: position, + end: position + text.length, + }, + }); + position += text.length + 1; } + return result; +}; - get file() { - return this.#file; - } +/** + * Should wrap string into ANSI codes for coloring + */ +type Colorer = (s: string) => string; - get contents() { - return this.#interval.contents; - } +type ErrorPrinterParams = { + /** + * Number of context lines below and above error + */ + contextLines: number; + /** + * Colorer for code with error + */ + error: Colorer, + /** + * Colorer for context lines of code + */ + context: Colorer, +} - get interval() { - return this.#interval; - } +const getErrorPrinter = ({ error, context, contextLines }: ErrorPrinterParams) => { + const displayLine = (line: Line, range: Range) => { + // Only the line that contains range.start is underlined in error message + // Otherwise error on `while (...) {}` would display the whole loop body, for example + const hasInterval = line.range.start <= range.start && range.start < line.range.end; + + // Find the line-relative range + const mapped = shift(intersect(range, line.range), -line.range.start); + + // All lines except with error message are displayed in gray + if (!hasInterval) { + return [{ + id: line.id, + text: context(line.text), + hasInterval, + startOfError: mapped.start, + }]; + } + + // Source line with error colored + const sourceLine = { + id: line.id, + text: [ + line.text.substring(0, mapped.start), + error(line.text.substring(mapped.start, mapped.end)), + line.text.substring(mapped.end), + ].join(''), + hasInterval: true, + startOfError: mapped.start, + }; + + // Wiggly line underneath it + const underline = { + id: null, + text: [ + repeat(' ', mapped.start), + '^', + repeat('~', Math.max(0, mapped.end - mapped.start - 1)), + ].join(''), + hasInterval: true, + startOfError: mapped.start, + }; - get origin() { - return this.#origin; + return [sourceLine, underline]; + }; + + const show = (str: string, range: Range): string => { + // Display all lines of source file + const lines = toLines(str).flatMap(line => displayLine(line, range)); + + // Find first and lines lines with error message + const firstLineNum = lines.findIndex(line => line.hasInterval); + const lastLineNum = lines.findLastIndex(line => line.hasInterval); + if (firstLineNum === -1 || lastLineNum === -1) { + throwInternalCompilerError(`Interval [${range.start}, ${range.end}[ is empty or out of source bounds (${str.length})`); + } + + // Expand the line range so that `contextLines` are above and below + const rangeStart = Math.max(0, firstLineNum - contextLines); + const rangeEnd = Math.min(lines.length - 1, lastLineNum + contextLines); + + // Pick displayed lines out of full list + const displayedLines = lines.slice(rangeStart, rangeEnd + 1); + + // Find padding based on the line with largest line number + const maxLineId = displayedLines.reduce((acc, line) => { + return line.id === null ? acc : Math.max(acc, line.id); + }, 1); + const lineNumLength = String(maxLineId + 1).length; + + // Add line numbers and cursor to lines + const paddedLines = displayedLines.map(({ hasInterval, id, text }) => { + const prefix = hasInterval && id !== null ? '>' : ' '; + const paddedLineNum = id === null + ? repeat(' ', lineNumLength) + ' ' + : String(id + 1).padStart(lineNumLength) + ' |'; + return `${prefix} ${paddedLineNum} ${text}`; + }); + + // Add header and concatenate lines + const header = `Line ${firstLineNum + 1}, col ${(lines[firstLineNum]?.startOfError ?? 0) + 1}:`; + return [header, ...paddedLines].join('\n') + '\n'; + }; + + const getLineAndColumn = (str: string, range: Range) => { + const prefix = str.substring(0, range.start).split(''); + const lineNum = prefix.filter(isEndline).length; + const prevLineEndPos = prefix.findLastIndex(isEndline); + const lineStartPos = prevLineEndPos === -1 ? 0 : prevLineEndPos + 1; + const colNum = range.start - lineStartPos; + + return { + offset: range.start, + lineNum: lineNum + 1, + colNum: colNum + 1, + toString: () => show(str, range), + }; } -} -export const dummySrcInfo: AbstractSrcInfo = { - contents: '', - file: null, - interval: { - contents: '', - startIdx: 0, - endIdx: 0, - getLineAndColumn: () => ({ - colNum: 1, - lineNum: 1, - toString: () => { - throw new Error(); - }, - }), - getLineAndColumnMessage: () => 'Line 1, col 1:\n> 1 | \n ^\n', - }, - origin: 'user', + return { show, getLineAndColumn }; +}; + +// Default error printer. Should be initialized in entry point instead +const errorPrinter = getErrorPrinter({ + // This should be `chalk.red` + error: s => s, + // This should be `chalk.gray` + context: s => s, + contextLines: 1, +}); + +export const getSrcInfo = ( + sourceString: string, + startIdx: number, + endIdx: number, + file: string | null, + origin: ItemOrigin, +): SrcInfo => { + const getLineAndColumn = () => { + return errorPrinter.getLineAndColumn(sourceString, { + start: startIdx, + end: endIdx, + }); + }; + + const getLineAndColumnMessage = () => { + return getLineAndColumn().toString(); + }; + + const contents = sourceString.substring(startIdx, endIdx); + + return { + [srcInfoSymbol]: true, + contents: contents, + file, + interval: { + contents: contents, + startIdx: startIdx, + endIdx: endIdx, + getLineAndColumn, + getLineAndColumnMessage, + }, + origin, + toJSON: () => ({}), + }; +}; + +/** + * @deprecated + */ +export const getSrcInfoFromOhm = ( + { + sourceString, + startIdx, + endIdx, + }: RawInterval, + file: string | null, + origin: ItemOrigin, +): SrcInfo => { + return getSrcInfo( + sourceString, + startIdx, + endIdx, + file, + origin, + ); }; -// Rename is here so that OhmSrcInfo is called SrcInfo in snapshots, as it previously did -export { AbstractSrcInfo as SrcInfo, SrcInfo as OhmSrcInfo }; +export const dummySrcInfo: SrcInfo = getSrcInfo('', 0, 0, null, 'user'); diff --git a/src/storage/__snapshots__/resolveAllocation.spec.ts.snap b/src/storage/__snapshots__/resolveAllocation.spec.ts.snap index 79708c492..eac051980 100644 --- a/src/storage/__snapshots__/resolveAllocation.spec.ts.snap +++ b/src/storage/__snapshots__/resolveAllocation.spec.ts.snap @@ -85,17 +85,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 31, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 29, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "x", }, "type": { "id": 30, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -104,28 +104,28 @@ exports[`resolveAllocation should write program 1`] = ` "id": 34, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 32, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "y", }, "type": { "id": 33, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, ], "id": 35, "kind": "struct_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 28, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point", }, }, @@ -148,23 +148,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 31, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 29, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "x", }, "type": { "id": 30, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 0, - "loc": SrcInfo {}, + "loc": {}, "name": "x", "type": { "kind": "ref", @@ -188,23 +188,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 34, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 32, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "y", }, "type": { "id": 33, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 1, - "loc": SrcInfo {}, + "loc": {}, "name": "y", "type": { "kind": "ref", @@ -291,28 +291,28 @@ exports[`resolveAllocation should write program 1`] = ` "id": 39, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 37, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "z", }, "type": { "id": 38, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point", }, }, ], "id": 40, "kind": "struct_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 36, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point2", }, }, @@ -334,23 +334,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 39, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 37, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "z", }, "type": { "id": 38, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point", }, }, "default": undefined, "index": 0, - "loc": SrcInfo {}, + "loc": {}, "name": "z", "type": { "kind": "ref", @@ -481,17 +481,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 23, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 21, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 22, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point", }, }, @@ -500,28 +500,28 @@ exports[`resolveAllocation should write program 1`] = ` "id": 26, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 24, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 25, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point2", }, }, ], "id": 27, "kind": "struct_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 20, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point3", }, }, @@ -543,23 +543,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 23, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 21, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 22, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point", }, }, "default": undefined, "index": 0, - "loc": SrcInfo {}, + "loc": {}, "name": "a", "type": { "kind": "ref", @@ -582,23 +582,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 26, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 24, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 25, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Point2", }, }, "default": undefined, "index": 1, - "loc": SrcInfo {}, + "loc": {}, "name": "b", "type": { "kind": "ref", @@ -981,17 +981,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 44, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 42, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 43, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1000,17 +1000,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 47, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 45, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 46, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1019,17 +1019,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 50, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 48, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "c", }, "type": { "id": 49, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1038,17 +1038,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 53, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 51, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "d", }, "type": { "id": 52, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1057,17 +1057,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 56, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 54, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "e", }, "type": { "id": 55, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1076,17 +1076,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 59, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 57, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "f", }, "type": { "id": 58, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1095,17 +1095,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 62, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 60, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "g", }, "type": { "id": 61, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1114,17 +1114,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 65, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 63, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "h", }, "type": { "id": 64, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1133,17 +1133,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 68, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 66, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "i", }, "type": { "id": 67, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1152,17 +1152,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 71, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 69, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "j", }, "type": { "id": 70, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -1171,28 +1171,28 @@ exports[`resolveAllocation should write program 1`] = ` "id": 74, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 72, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "k", }, "type": { "id": 73, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, ], "id": 75, "kind": "struct_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 41, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, @@ -1215,23 +1215,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 44, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 42, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 43, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 0, - "loc": SrcInfo {}, + "loc": {}, "name": "a", "type": { "kind": "ref", @@ -1255,23 +1255,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 47, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 45, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 46, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 1, - "loc": SrcInfo {}, + "loc": {}, "name": "b", "type": { "kind": "ref", @@ -1295,23 +1295,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 50, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 48, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "c", }, "type": { "id": 49, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 2, - "loc": SrcInfo {}, + "loc": {}, "name": "c", "type": { "kind": "ref", @@ -1335,23 +1335,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 53, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 51, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "d", }, "type": { "id": 52, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 3, - "loc": SrcInfo {}, + "loc": {}, "name": "d", "type": { "kind": "ref", @@ -1375,23 +1375,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 56, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 54, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "e", }, "type": { "id": 55, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 4, - "loc": SrcInfo {}, + "loc": {}, "name": "e", "type": { "kind": "ref", @@ -1415,23 +1415,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 59, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 57, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "f", }, "type": { "id": 58, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 5, - "loc": SrcInfo {}, + "loc": {}, "name": "f", "type": { "kind": "ref", @@ -1455,23 +1455,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 62, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 60, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "g", }, "type": { "id": 61, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 6, - "loc": SrcInfo {}, + "loc": {}, "name": "g", "type": { "kind": "ref", @@ -1495,23 +1495,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 65, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 63, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "h", }, "type": { "id": 64, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 7, - "loc": SrcInfo {}, + "loc": {}, "name": "h", "type": { "kind": "ref", @@ -1535,23 +1535,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 68, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 66, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "i", }, "type": { "id": 67, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 8, - "loc": SrcInfo {}, + "loc": {}, "name": "i", "type": { "kind": "ref", @@ -1575,23 +1575,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 71, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 69, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "j", }, "type": { "id": 70, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 9, - "loc": SrcInfo {}, + "loc": {}, "name": "j", "type": { "kind": "ref", @@ -1615,23 +1615,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 74, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 72, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "k", }, "type": { "id": 73, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": undefined, "index": 10, - "loc": SrcInfo {}, + "loc": {}, "name": "k", "type": { "kind": "ref", @@ -1806,17 +1806,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 79, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 77, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 78, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, @@ -1825,17 +1825,17 @@ exports[`resolveAllocation should write program 1`] = ` "id": 82, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 80, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 81, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, @@ -1844,28 +1844,28 @@ exports[`resolveAllocation should write program 1`] = ` "id": 85, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 83, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "c", }, "type": { "id": 84, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, ], "id": 86, "kind": "struct_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 76, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep2", }, }, @@ -1887,23 +1887,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 79, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 77, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 78, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, "default": undefined, "index": 0, - "loc": SrcInfo {}, + "loc": {}, "name": "a", "type": { "kind": "ref", @@ -1926,23 +1926,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 82, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 80, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 81, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, "default": undefined, "index": 1, - "loc": SrcInfo {}, + "loc": {}, "name": "b", "type": { "kind": "ref", @@ -1965,23 +1965,23 @@ exports[`resolveAllocation should write program 1`] = ` "id": 85, "initializer": null, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 83, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "c", }, "type": { "id": 84, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Deep", }, }, "default": undefined, "index": 2, - "loc": SrcInfo {}, + "loc": {}, "name": "c", "type": { "kind": "ref", @@ -2063,28 +2063,28 @@ exports[`resolveAllocation should write program 1`] = ` "base": 10, "id": 90, "kind": "number", - "loc": SrcInfo {}, + "loc": {}, "value": 0n, }, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 88, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "v", }, "type": { "id": 89, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, { "id": 92, "kind": "contract_init", - "loc": SrcInfo {}, + "loc": {}, "params": [], "statements": [], }, @@ -2092,45 +2092,45 @@ exports[`resolveAllocation should write program 1`] = ` "attributes": [], "id": 100, "kind": "function_def", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 93, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "main", }, "params": [ { "id": 96, "kind": "typed_parameter", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 94, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 95, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, { "id": 99, "kind": "typed_parameter", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 97, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 98, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -2141,11 +2141,11 @@ exports[`resolveAllocation should write program 1`] = ` ], "id": 101, "kind": "contract", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 87, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "Sample", }, "traits": [], @@ -2171,27 +2171,27 @@ exports[`resolveAllocation should write program 1`] = ` "base": 10, "id": 90, "kind": "number", - "loc": SrcInfo {}, + "loc": {}, "value": 0n, }, "kind": "field_decl", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 88, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "v", }, "type": { "id": 89, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, "default": 0n, "index": 0, - "loc": SrcInfo {}, + "loc": {}, "name": "v", "type": { "kind": "ref", @@ -2206,45 +2206,45 @@ exports[`resolveAllocation should write program 1`] = ` "attributes": [], "id": 100, "kind": "function_def", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 93, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "main", }, "params": [ { "id": 96, "kind": "typed_parameter", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 94, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { "id": 95, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, { "id": 99, "kind": "typed_parameter", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 97, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { "id": 98, "kind": "type_id", - "loc": SrcInfo {}, + "loc": {}, "text": "Int", }, }, @@ -2263,11 +2263,11 @@ exports[`resolveAllocation should write program 1`] = ` "origin": "user", "params": [ { - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 94, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "a", }, "type": { @@ -2277,11 +2277,11 @@ exports[`resolveAllocation should write program 1`] = ` }, }, { - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 97, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "b", }, "type": { @@ -2306,7 +2306,7 @@ exports[`resolveAllocation should write program 1`] = ` "ast": { "id": 92, "kind": "contract_init", - "loc": SrcInfo {}, + "loc": {}, "params": [], "statements": [], }, @@ -2327,11 +2327,11 @@ exports[`resolveAllocation should write program 1`] = ` "declarations": [], "id": 19, "kind": "trait", - "loc": SrcInfo {}, + "loc": {}, "name": { "id": 18, "kind": "id", - "loc": SrcInfo {}, + "loc": {}, "text": "BaseTrait", }, "traits": [], diff --git a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap index 2141c6921..dc4bb74f7 100644 --- a/src/types/__snapshots__/resolveDescriptors.spec.ts.snap +++ b/src/types/__snapshots__/resolveDescriptors.spec.ts.snap @@ -2077,18 +2077,7 @@ exports[`resolveDescriptors should resolve descriptors for contract-bounced-slic "base": 10, "id": 0, "kind": "number", - "loc": { - "contents": "", - "file": null, - "interval": { - "contents": "", - "endIdx": 0, - "getLineAndColumn": [Function], - "getLineAndColumnMessage": [Function], - "startIdx": 0, - }, - "origin": "user", - }, + "loc": , "value": 3746466057n, }, "init": null, @@ -2655,18 +2644,7 @@ exports[`resolveDescriptors should resolve descriptors for contract-bounced-too- "base": 10, "id": 0, "kind": "number", - "loc": { - "contents": "", - "file": null, - "interval": { - "contents": "", - "endIdx": 0, - "getLineAndColumn": [Function], - "getLineAndColumnMessage": [Function], - "startIdx": 0, - }, - "origin": "user", - }, + "loc": , "value": 2219696518n, }, "init": null, @@ -4135,18 +4113,7 @@ exports[`resolveDescriptors should resolve descriptors for contract-external-fal "base": 10, "id": 0, "kind": "number", - "loc": { - "contents": "", - "file": null, - "interval": { - "contents": "", - "endIdx": 0, - "getLineAndColumn": [Function], - "getLineAndColumnMessage": [Function], - "startIdx": 0, - }, - "origin": "user", - }, + "loc": , "value": 3746466057n, }, "init": null, @@ -9314,18 +9281,7 @@ exports[`resolveDescriptors should resolve descriptors for message-opcode-expr 1 "base": 10, "id": 0, "kind": "number", - "loc": { - "contents": "", - "file": null, - "interval": { - "contents": "", - "endIdx": 0, - "getLineAndColumn": [Function], - "getLineAndColumnMessage": [Function], - "startIdx": 0, - }, - "origin": "user", - }, + "loc": , "value": 898001897n, }, "init": null, @@ -10626,18 +10582,7 @@ exports[`resolveDescriptors should resolve descriptors for struct-decl-non-rec-t "base": 10, "id": 0, "kind": "number", - "loc": { - "contents": "", - "file": null, - "interval": { - "contents": "", - "endIdx": 0, - "getLineAndColumn": [Function], - "getLineAndColumnMessage": [Function], - "startIdx": 0, - }, - "origin": "user", - }, + "loc": , "value": 383013829n, }, "init": null, diff --git a/src/types/resolveDescriptors.spec.ts b/src/types/resolveDescriptors.spec.ts index 2f88222b5..c311b8b7f 100644 --- a/src/types/resolveDescriptors.spec.ts +++ b/src/types/resolveDescriptors.spec.ts @@ -10,10 +10,10 @@ import { openContext } from "../grammar/store"; import { featureEnable } from "../config/features"; import { getParser, SrcInfo } from "../grammar"; import { getAstFactory } from "../grammar/ast"; -import { OhmSrcInfo } from "../grammar/src-info"; +import { isSrcInfo } from "../grammar/src-info"; expect.addSnapshotSerializer({ - test: (src) => src instanceof OhmSrcInfo, + test: (src) => isSrcInfo(src), print: (src) => (src as SrcInfo).contents, }); From 340552aaf92b47fa085bb24df4bec9946166a41f Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:57:39 +0400 Subject: [PATCH 4/5] fix: format --- src/grammar/src-info.ts | 117 +++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/src/grammar/src-info.ts b/src/grammar/src-info.ts index f807e10c9..dcbad0a88 100644 --- a/src/grammar/src-info.ts +++ b/src/grammar/src-info.ts @@ -8,7 +8,7 @@ export type LineAndColumnInfo = { lineNum: number; colNum: number; toString(...ranges: number[][]): string; -} +}; export type Interval = { contents: string; @@ -19,10 +19,15 @@ export type Interval = { }; // Do not export! Use isSrcInfo -const srcInfoSymbol = Symbol('src-info'); +const srcInfoSymbol = Symbol("src-info"); export const isSrcInfo = (t: unknown): t is SrcInfo => { - return typeof t === 'object' && t !== null && srcInfoSymbol in t && Boolean(t[srcInfoSymbol]); + return ( + typeof t === "object" && + t !== null && + srcInfoSymbol in t && + Boolean(t[srcInfoSymbol]) + ); }; export interface SrcInfo { @@ -38,17 +43,17 @@ export interface SrcInfo { /** * toJSON method is provided, so that it's not serialized into snapshots */ - toJSON: () => object, + toJSON: () => object; } -const isEndline = (s: string) => s === '\n'; +const isEndline = (s: string) => s === "\n"; const repeat = (s: string, n: number): string => new Array(n + 1).join(s); type Range = { start: number; end: number; -} +}; const intersect = (a: Range, b: Range): Range => { return { @@ -68,7 +73,7 @@ type Line = { id: number; text: string; range: Range; -} +}; /** * Convert code into a list of lines @@ -76,7 +81,7 @@ type Line = { const toLines = (source: string): Line[] => { const result: Line[] = []; let position = 0; - for (const [id, text] of source.split('\n').entries()) { + for (const [id, text] of source.split("\n").entries()) { result.push({ id, text, @@ -103,30 +108,37 @@ type ErrorPrinterParams = { /** * Colorer for code with error */ - error: Colorer, + error: Colorer; /** * Colorer for context lines of code */ - context: Colorer, -} + context: Colorer; +}; -const getErrorPrinter = ({ error, context, contextLines }: ErrorPrinterParams) => { +const getErrorPrinter = ({ + error, + context, + contextLines, +}: ErrorPrinterParams) => { const displayLine = (line: Line, range: Range) => { // Only the line that contains range.start is underlined in error message // Otherwise error on `while (...) {}` would display the whole loop body, for example - const hasInterval = line.range.start <= range.start && range.start < line.range.end; + const hasInterval = + line.range.start <= range.start && range.start < line.range.end; // Find the line-relative range const mapped = shift(intersect(range, line.range), -line.range.start); // All lines except with error message are displayed in gray if (!hasInterval) { - return [{ - id: line.id, - text: context(line.text), - hasInterval, - startOfError: mapped.start, - }]; + return [ + { + id: line.id, + text: context(line.text), + hasInterval, + startOfError: mapped.start, + }, + ]; } // Source line with error colored @@ -136,7 +148,7 @@ const getErrorPrinter = ({ error, context, contextLines }: ErrorPrinterParams) = line.text.substring(0, mapped.start), error(line.text.substring(mapped.start, mapped.end)), line.text.substring(mapped.end), - ].join(''), + ].join(""), hasInterval: true, startOfError: mapped.start, }; @@ -145,10 +157,10 @@ const getErrorPrinter = ({ error, context, contextLines }: ErrorPrinterParams) = const underline = { id: null, text: [ - repeat(' ', mapped.start), - '^', - repeat('~', Math.max(0, mapped.end - mapped.start - 1)), - ].join(''), + repeat(" ", mapped.start), + "^", + repeat("~", Math.max(0, mapped.end - mapped.start - 1)), + ].join(""), hasInterval: true, startOfError: mapped.start, }; @@ -158,56 +170,59 @@ const getErrorPrinter = ({ error, context, contextLines }: ErrorPrinterParams) = const show = (str: string, range: Range): string => { // Display all lines of source file - const lines = toLines(str).flatMap(line => displayLine(line, range)); - + const lines = toLines(str).flatMap((line) => displayLine(line, range)); + // Find first and lines lines with error message - const firstLineNum = lines.findIndex(line => line.hasInterval); - const lastLineNum = lines.findLastIndex(line => line.hasInterval); + const firstLineNum = lines.findIndex((line) => line.hasInterval); + const lastLineNum = lines.findLastIndex((line) => line.hasInterval); if (firstLineNum === -1 || lastLineNum === -1) { - throwInternalCompilerError(`Interval [${range.start}, ${range.end}[ is empty or out of source bounds (${str.length})`); + throwInternalCompilerError( + `Interval [${range.start}, ${range.end}[ is empty or out of source bounds (${str.length})`, + ); } - + // Expand the line range so that `contextLines` are above and below const rangeStart = Math.max(0, firstLineNum - contextLines); const rangeEnd = Math.min(lines.length - 1, lastLineNum + contextLines); - + // Pick displayed lines out of full list const displayedLines = lines.slice(rangeStart, rangeEnd + 1); - + // Find padding based on the line with largest line number const maxLineId = displayedLines.reduce((acc, line) => { return line.id === null ? acc : Math.max(acc, line.id); }, 1); const lineNumLength = String(maxLineId + 1).length; - + // Add line numbers and cursor to lines const paddedLines = displayedLines.map(({ hasInterval, id, text }) => { - const prefix = hasInterval && id !== null ? '>' : ' '; - const paddedLineNum = id === null - ? repeat(' ', lineNumLength) + ' ' - : String(id + 1).padStart(lineNumLength) + ' |'; + const prefix = hasInterval && id !== null ? ">" : " "; + const paddedLineNum = + id === null + ? repeat(" ", lineNumLength) + " " + : String(id + 1).padStart(lineNumLength) + " |"; return `${prefix} ${paddedLineNum} ${text}`; }); // Add header and concatenate lines const header = `Line ${firstLineNum + 1}, col ${(lines[firstLineNum]?.startOfError ?? 0) + 1}:`; - return [header, ...paddedLines].join('\n') + '\n'; + return [header, ...paddedLines].join("\n") + "\n"; }; const getLineAndColumn = (str: string, range: Range) => { - const prefix = str.substring(0, range.start).split(''); + const prefix = str.substring(0, range.start).split(""); const lineNum = prefix.filter(isEndline).length; const prevLineEndPos = prefix.findLastIndex(isEndline); const lineStartPos = prevLineEndPos === -1 ? 0 : prevLineEndPos + 1; const colNum = range.start - lineStartPos; - + return { offset: range.start, lineNum: lineNum + 1, colNum: colNum + 1, toString: () => show(str, range), }; - } + }; return { show, getLineAndColumn }; }; @@ -215,9 +230,9 @@ const getErrorPrinter = ({ error, context, contextLines }: ErrorPrinterParams) = // Default error printer. Should be initialized in entry point instead const errorPrinter = getErrorPrinter({ // This should be `chalk.red` - error: s => s, + error: (s) => s, // This should be `chalk.gray` - context: s => s, + context: (s) => s, contextLines: 1, }); @@ -261,21 +276,11 @@ export const getSrcInfo = ( * @deprecated */ export const getSrcInfoFromOhm = ( - { - sourceString, - startIdx, - endIdx, - }: RawInterval, + { sourceString, startIdx, endIdx }: RawInterval, file: string | null, origin: ItemOrigin, ): SrcInfo => { - return getSrcInfo( - sourceString, - startIdx, - endIdx, - file, - origin, - ); + return getSrcInfo(sourceString, startIdx, endIdx, file, origin); }; -export const dummySrcInfo: SrcInfo = getSrcInfo('', 0, 0, null, 'user'); +export const dummySrcInfo: SrcInfo = getSrcInfo("", 0, 0, null, "user"); From 8610c982c2669a6c2241f443035da36258ba036f Mon Sep 17 00:00:00 2001 From: verytactical <186486509+verytactical@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:58:31 +0400 Subject: [PATCH 5/5] fix: knip --- src/grammar/src-info.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/grammar/src-info.ts b/src/grammar/src-info.ts index dcbad0a88..4ca54f771 100644 --- a/src/grammar/src-info.ts +++ b/src/grammar/src-info.ts @@ -4,13 +4,13 @@ import { throwInternalCompilerError } from "../errors"; export type ItemOrigin = "stdlib" | "user"; -export type LineAndColumnInfo = { +type LineAndColumnInfo = { lineNum: number; colNum: number; toString(...ranges: number[][]): string; }; -export type Interval = { +type Interval = { contents: string; getLineAndColumnMessage(): string; getLineAndColumn(): LineAndColumnInfo; @@ -236,7 +236,7 @@ const errorPrinter = getErrorPrinter({ contextLines: 1, }); -export const getSrcInfo = ( +const getSrcInfo = ( sourceString: string, startIdx: number, endIdx: number,