@monimesl/dot-script-parser 0.1.0-alpha.8 → 0.1.0-alpha.9

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/index.d.ts CHANGED
@@ -1,10 +1,6 @@
1
1
  import "oxc-parser";
2
2
  import { SourceError } from "@monimesl/dot-core";
3
3
  //#region src/globals.d.ts
4
- /**
5
- * Which of `names` a module reads without declaring or importing them at its top level. The
6
- * compiler imports those for the module, so a dot's code can use framework functions as globals.
7
- */
8
4
  export declare function unboundReferences(source: string, names: readonly string[], file?: string): string[];
9
5
  //#endregion
10
6
  //#region src/dot.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/globals.ts","../src/dot.ts","../src/errors.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts","../src/ast/page/types.ts","../src/ast/page/parse.ts"],"mappings":";;;;;;;wBAcgB,kBACd,gBACA,0BACA;;;UCZe;WACN;WACA;aAAqB;aAAwB;;;wBAGxC,eAAe,gBAAgB,gBAAkB;;;qBCPpD,yBAAyB;WAClB;;;;cCJP;cAEA;KAoBD;KAEA;WAAyB;WAA0B,OAAO;;KAE1D;WAA4B;WAA6B;;KAEzD;WACD;WACA,QAAQ;WACR,UAAU;;KAGT,wBAAwB;KAExB;WACD;WACA,UAAU;WACV,UAAU;;KAGT,yBAAyB;KAEzB;WACD;WACA,UAAU;WACV,MAAM;WACN,OAAO;;KAGN;WACD;WACA,MAAM;WACN,YAAY;WACZ,WAAW;;KAGV,WACV,cAAc,iBAAiB,aAAa,gBAAgB,iBAAiB;;;wBCpD/D,gBAAgB,iBAAiB;;;UCPhC;WAEN;WAEA,YAAY,SAAS;;UAGf;WACN;WACA;WACA;WACA;WAEA,gBAAgB,SAAS;;;;wBCFpB,iBAAiB,gBAAgB,gBAAoB;wBAarD,iBAAiB,gBAAgB,gBAAyB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/globals.ts","../src/dot.ts","../src/errors.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts","../src/ast/page/types.ts","../src/ast/page/parse.ts"],"mappings":";;;wBAWgB,kBACd,gBACA,0BACA;;;UCTe;WACN;WACA;aAAqB;aAAwB;;;wBAGxC,eAAe,gBAAgB,gBAAkB;;;qBCPpD,yBAAyB;WAClB;;;;cCJP;cAEA;KAoBD;KAEP;WAAyB;WAA0B,OAAO;;KAE1D;WAA4B;WAA6B;;KAEzD;WACM;WACA,QAAQ;WACR,UAAU;;KAGT,wBAAwB;KAE/B;WACM;WACA,UAAU;WACV,UAAU;;KAGT,yBAAyB;KAEhC;WACM;WACA,UAAU;WACV,MAAM;WACN,OAAO;;KAGb;WACM;WACA,MAAM;WACN,YAAY;WACZ,WAAW;;KAGV,WACV,cAAc,iBAAiB,aAAa,gBAAgB,iBAAiB;;;wBCpD/D,gBAAgB,iBAAiB;;;UCPhC;WAEN;WAEA,YAAY,SAAS;;UAGf;WACN;WACA;WACA;WACA;WAEA,gBAAgB,SAAS;;;;wBCFpB,iBAAiB,gBAAgB,gBAAoB;wBAarD,iBAAiB,gBAAgB,gBAAyB"}
package/dist/index.js CHANGED
@@ -74,10 +74,6 @@ function fileName(path) {
74
74
  }
75
75
  //#endregion
76
76
  //#region src/globals.ts
77
- /**
78
- * Which of `names` a module reads without declaring or importing them at its top level. The
79
- * compiler imports those for the module, so a dot's code can use framework functions as globals.
80
- */
81
77
  function unboundReferences(source, names, file = "module.ts") {
82
78
  const program = parseModule(source, file);
83
79
  const bound = topLevelBindings(program);
@@ -91,10 +87,10 @@ function topLevelBindings(program) {
91
87
  const declaration = withoutExport(statement);
92
88
  switch (declaration?.type) {
93
89
  case "ImportDeclaration":
94
- declaration.specifiers.forEach((specifier) => names.add(specifier.local.name));
90
+ for (const specifier of declaration.specifiers) names.add(specifier.local.name);
95
91
  break;
96
92
  case "VariableDeclaration":
97
- declaration.declarations.forEach((declarator) => collectPatternNames(declarator.id, names));
93
+ for (const declarator of declaration.declarations) collectPatternNames(declarator.id, names);
98
94
  break;
99
95
  case "FunctionDeclaration":
100
96
  case "ClassDeclaration": if (declaration.id) names.add(declaration.id.name);
@@ -111,10 +107,10 @@ function collectPatternNames(pattern, names) {
111
107
  names.add(pattern.name);
112
108
  break;
113
109
  case "ObjectPattern":
114
- pattern.properties.forEach((property) => visit(property.type === "RestElement" ? property.argument : property.value));
110
+ for (const property of pattern.properties) visit(property.type === "RestElement" ? property.argument : property.value);
115
111
  break;
116
112
  case "ArrayPattern":
117
- pattern.elements.forEach(visit);
113
+ for (const element of pattern.elements) visit(element);
118
114
  break;
119
115
  case "RestElement":
120
116
  visit(pattern.argument);
@@ -152,7 +148,7 @@ function parseStateModule(source, file = "state.ts") {
152
148
  if (!exported) return failAt("state.ts must have a default export", source, 0, file);
153
149
  const properties = resolvedProperties(program, exported);
154
150
  return {
155
- keys: properties?.map((property) => property.name) ?? null,
151
+ keys: namesOf(properties),
156
152
  keyOffsets: offsetsOf(properties ?? [])
157
153
  };
158
154
  }
@@ -172,7 +168,7 @@ function parseLogicModule(source, file = "controller.ts") {
172
168
  case "hooks":
173
169
  if (value.type !== "ObjectExpression") break;
174
170
  for (const hook of staticProperties(value)) {
175
- if (!HOOKS.has(hook.name)) failAt(`Unknown page hook \`${hook.name}\`. Page hooks: ${PAGE_HOOKS.join(", ")}`, source, hook.start, file);
171
+ if (!HOOKS.has(hook.name)) failAt(`Unknown page hook \`${hook.name}\`. The hooks are ${PAGE_HOOKS.join(", ")}`, source, hook.start, file);
176
172
  hooks.push(hook.name);
177
173
  }
178
174
  break;
@@ -185,8 +181,8 @@ function parseLogicModule(source, file = "controller.ts") {
185
181
  default: if (isFunction(value)) failAt(`\`${name}\` must go in \`mutations\` or \`actions\``, source, start, file);
186
182
  else failAt(`Unknown option \`${name}\`. definePage takes id, initialState, configs, hooks, mutations and actions`, source, start, file);
187
183
  }
188
- const mutationNames = mutations?.map((property) => property.name) ?? null;
189
- const actionNames = actions?.map((property) => property.name) ?? null;
184
+ const mutationNames = namesOf(mutations);
185
+ const actionNames = namesOf(actions);
190
186
  const clash = mutationNames?.find((name) => actionNames?.includes(name));
191
187
  if (clash) failAt(`\`${clash}\` is both a mutation and an action`, source, options.start, file);
192
188
  return {
@@ -206,6 +202,9 @@ function resolvedProperties(program, node) {
206
202
  const properties = staticProperties(object);
207
203
  return properties.length === object.properties.length ? properties : null;
208
204
  }
205
+ function namesOf(properties) {
206
+ return properties?.map((property) => property.name) ?? null;
207
+ }
209
208
  function offsetsOf(properties) {
210
209
  const offsets = {};
211
210
  for (const property of properties) offsets[property.name] = property.start;
@@ -226,8 +225,8 @@ function resolveObject(program, node) {
226
225
  /** Reads a page id, which must be a string literal made of safe characters. */
227
226
  function pageId(node, source, file) {
228
227
  const value = unwrapExpression(node);
229
- if (value.type !== "Literal" || typeof value.value !== "string") return failAt("A page id must be a string literal", source, node.start, file);
230
- if (!isPageId(value.value)) return failAt(`Invalid page id "${value.value}". Use letters, digits, "-" and "_", with "/" between segments`, source, node.start, file);
228
+ if (value.type !== "Literal" || typeof value.value !== "string") return failAt("A page id must be written as a string, such as 'cart'", source, node.start, file);
229
+ if (!isPageId(value.value)) return failAt(`"${value.value}" isn't a valid page id. Use letters, digits, "-" and "_", with "/" between folders`, source, node.start, file);
231
230
  return value.value;
232
231
  }
233
232
  //#endregion
@@ -235,10 +234,10 @@ function pageId(node, source, file) {
235
234
  function parseDotModule(source, file = "dot.ts") {
236
235
  const options = defineCall(parseModule(source, file), source, file, "defineDot");
237
236
  const pagesProperty = staticProperties(options).find((property) => property.name === "pages");
238
- if (!pagesProperty) return failAt("defineDot needs `pages`: the dot's page folders, starting page first", source, options.start, file);
237
+ if (!pagesProperty) return failAt("defineDot needs `pages`: the page folders, with the first page first", source, options.start, file);
239
238
  const { value, start } = pagesProperty;
240
239
  const array = unwrapExpression(value);
241
- if (array.type !== "ArrayExpression") return failAt("`pages` must be an array of page folders", source, start, file);
240
+ if (array.type !== "ArrayExpression") return failAt("`pages` must be a list of page folders", source, start, file);
242
241
  if (array.elements.length === 0) return failAt("`pages` needs at least one page", source, start, file);
243
242
  const pages = array.elements.map((element) => {
244
243
  if (!element || element.type === "SpreadElement") return failAt("`pages` must list each page folder as a string", source, element?.start ?? start, file);
@@ -283,11 +282,11 @@ const BINARY_OPERATORS = [
283
282
  //#endregion
284
283
  //#region src/ast/expression/parse.ts
285
284
  function parseExpression(source) {
286
- if (source.trim().length === 0) failAt("Empty expression", source, 0);
285
+ if (source.trim().length === 0) failAt("The binding is empty", source, 0);
287
286
  const { program, errors } = parseSync("binding.js", source, { preserveParens: false });
288
287
  failOnSyntaxError(errors, source);
289
288
  const [statement, extra] = program.body;
290
- if (!statement || extra || statement.type !== "ExpressionStatement") return failAt("Expected a single expression statement", source, statement?.start ?? 0);
289
+ if (!statement || extra || statement.type !== "ExpressionStatement") return failAt("A binding must be one expression", source, statement?.start ?? 0);
291
290
  return convert(statement.expression, source);
292
291
  }
293
292
  function convert(node, source) {
@@ -342,13 +341,13 @@ function convert(node, source) {
342
341
  alternate: convert(node.alternate, source)
343
342
  };
344
343
  case "CallExpression":
345
- case "NewExpression": return failAt("Function calls are currently not allowed in bindings", source, node.start);
344
+ case "NewExpression": return failAt("Bindings can't call functions", source, node.start);
346
345
  case "AssignmentExpression":
347
- case "UpdateExpression": return failAt("Update expressions are currently not allowed in bindings", source, node.start);
346
+ case "UpdateExpression": return failAt("Bindings can't change values", source, node.start);
348
347
  }
349
348
  let detail = "";
350
349
  if ("operator" in node) detail = ` \`${node.operator}\``;
351
- return failAt(`Unsupported syntax in binding: ${node.type}${detail}`, source, node.start);
350
+ return failAt(`Bindings can't use ${node.type}${detail}`, source, node.start);
352
351
  }
353
352
  function isOneOf(list, value) {
354
353
  return list.includes(value);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/errors.ts","../src/module.ts","../src/globals.ts","../src/ast/page/parse.ts","../src/dot.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts"],"sourcesContent":["import type { Expression, ObjectExpression, Program, PropertyKey } from 'oxc-parser';\n\ntype TopLevelStatement = Program['body'][number];\n\nfunction propertyName(key: PropertyKey): string | null {\n if (key.type === 'Identifier') {\n return key.name;\n }\n if (key.type === 'Literal' && typeof key.value === 'string') {\n return key.value;\n }\n return null;\n}\n\nexport function unwrapExpression(node: Expression): Expression {\n while (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression' ||\n node.type === 'TSNonNullExpression'\n ) {\n node = node.expression;\n }\n return node;\n}\n\nexport interface StaticProperty {\n readonly name: string;\n readonly value: Expression;\n readonly start: number;\n}\n\n// The properties of an object literal whose names are written out, skipping computed ones.\nexport function staticProperties(object: ObjectExpression): StaticProperty[] {\n const properties: StaticProperty[] = [];\n for (const property of object.properties) {\n if (property.type !== 'Property' || property.computed) {\n continue;\n }\n const name = propertyName(property.key);\n if (name !== null) {\n properties.push({ name, value: property.value, start: property.start });\n }\n }\n return properties;\n}\n\n// The declaration inside `export const ...` and the like; other statements as they are.\nexport function withoutExport(statement: TopLevelStatement): TopLevelStatement | null {\n if (statement.type === 'ExportNamedDeclaration') {\n return statement.declaration;\n }\n return statement;\n}\n","import type { OxcError } from 'oxc-parser';\nimport { locationAt, SourceError } from '@monimesl/dot-core';\n\nexport class ScriptParseError extends SourceError {\n override readonly name = 'ScriptParseError';\n}\n\nexport function failAt(reason: string, source: string, offset: number, file?: string): never {\n throw new ScriptParseError(reason, file, locationAt(source, offset));\n}\n\nexport function failOnSyntaxError(\n errors: readonly OxcError[],\n source: string,\n file?: string,\n): void {\n const [error] = errors;\n if (error) {\n failAt(error.message, source, error.labels[0]?.start ?? 0, file);\n }\n}\n","import { parseSync } from 'oxc-parser';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport { unwrapExpression } from './utils';\nimport { failAt, failOnSyntaxError } from './errors';\n\nexport function parseModule(source: string, file: string): Program {\n const { program, errors } = parseSync(file, source, { lang: 'ts', sourceType: 'module' });\n failOnSyntaxError(errors, source, file);\n return program;\n}\n\nexport function defaultExport(program: Program): Expression | undefined {\n for (const statement of program.body) {\n if (statement.type !== 'ExportDefaultDeclaration') {\n continue;\n }\n const { declaration } = statement;\n switch (declaration.type) {\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n case 'TSInterfaceDeclaration':\n return undefined;\n default:\n return declaration;\n }\n }\n return undefined;\n}\n\nexport function defineCall(\n program: Program,\n source: string,\n file: string,\n callee: string,\n): ObjectExpression {\n const exported = defaultExport(program);\n const call = exported && unwrapExpression(exported);\n const options = call?.type === 'CallExpression' ? call.arguments[0] : undefined;\n if (\n call?.type !== 'CallExpression' ||\n call.callee.type !== 'Identifier' ||\n call.callee.name !== callee ||\n options?.type !== 'ObjectExpression'\n ) {\n return failAt(\n `${fileName(file)} must \\`export default ${callee}({ ... })\\``,\n source,\n exported?.start ?? 0,\n file,\n );\n }\n return options;\n}\n\n// The last segment of a path, with either separator.\nfunction fileName(path: string): string {\n const lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\\\'));\n return path.slice(lastSeparator + 1);\n}\n","import type { Program } from 'oxc-parser';\n\nimport { parseModule } from './module';\nimport { withoutExport } from './utils';\n\ninterface Node {\n readonly type: string;\n readonly [key: string]: unknown;\n}\n\n/**\n * Which of `names` a module reads without declaring or importing them at its top level. The\n * compiler imports those for the module, so a dot's code can use framework functions as globals.\n */\nexport function unboundReferences(\n source: string,\n names: readonly string[],\n file = 'module.ts',\n): string[] {\n const program = parseModule(source, file);\n const bound = topLevelBindings(program);\n const references = new Set<string>();\n collectReferences(program as unknown as Node, null, '', references);\n return names.filter((name) => references.has(name) && !bound.has(name));\n}\n\nfunction topLevelBindings(program: Program): Set<string> {\n const names = new Set<string>();\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n switch (declaration?.type) {\n case 'ImportDeclaration':\n declaration.specifiers.forEach((specifier) => names.add(specifier.local.name));\n break;\n case 'VariableDeclaration':\n declaration.declarations.forEach((declarator) =>\n collectPatternNames(declarator.id as unknown as Node, names),\n );\n break;\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n if (declaration.id) {\n names.add(declaration.id.name);\n }\n break;\n }\n }\n return names;\n}\n\nfunction collectPatternNames(pattern: Node, names: Set<string>): void {\n const visit = (child: unknown) => {\n if (isNode(child)) {\n collectPatternNames(child, names);\n }\n };\n switch (pattern.type) {\n case 'Identifier':\n names.add(pattern.name as string);\n break;\n case 'ObjectPattern':\n (pattern.properties as Node[]).forEach((property) =>\n visit(property.type === 'RestElement' ? property.argument : property.value),\n );\n break;\n case 'ArrayPattern':\n (pattern.elements as unknown[]).forEach(visit);\n break;\n case 'RestElement':\n visit(pattern.argument);\n break;\n case 'AssignmentPattern':\n visit(pattern.left);\n break;\n }\n}\n\nfunction collectReferences(node: Node, parent: Node | null, key: string, out: Set<string>): void {\n if (node.type === 'ImportDeclaration') {\n return;\n }\n if (node.type === 'Identifier' && isReference(parent, key)) {\n out.add(node.name as string);\n }\n for (const [childKey, value] of Object.entries(node)) {\n for (const child of Array.isArray(value) ? value : [value]) {\n if (isNode(child)) {\n collectReferences(child, node, childKey, out);\n }\n }\n }\n}\n\n/** False for identifiers that name a property or label rather than refer to a variable. */\nfunction isReference(parent: Node | null, key: string): boolean {\n switch (parent?.type) {\n case 'MemberExpression':\n return key !== 'property' || parent.computed === true;\n case 'Property':\n case 'MethodDefinition':\n case 'PropertyDefinition':\n return key !== 'key' || parent.computed === true;\n case 'LabeledStatement':\n case 'BreakStatement':\n case 'ContinueStatement':\n return key !== 'label';\n default:\n return true;\n }\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof (value as Node | null)?.type === 'string';\n}\n","import { isPageId, PAGE_HOOKS } from '@monimesl/dot-core';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport type { PageModule, PageStateModule } from './types';\nimport { failAt } from '../../errors';\nimport { defaultExport, defineCall, parseModule } from '../../module';\nimport type { StaticProperty } from '../../utils';\nimport { staticProperties, unwrapExpression, withoutExport } from '../../utils';\n\nconst HOOKS = new Set<string>(PAGE_HOOKS);\n\nexport function parseStateModule(source: string, file = 'state.ts'): PageStateModule {\n const program = parseModule(source, file);\n const exported = defaultExport(program);\n if (!exported) {\n return failAt('state.ts must have a default export', source, 0, file);\n }\n const properties = resolvedProperties(program, exported);\n return {\n keys: properties?.map((property) => property.name) ?? null,\n keyOffsets: offsetsOf(properties ?? []),\n };\n}\n\nexport function parseLogicModule(source: string, file = 'controller.ts'): PageModule {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'definePage');\n let id: string | null = null;\n let mutations: StaticProperty[] | null = [];\n let actions: StaticProperty[] | null = [];\n const hooks: string[] = [];\n for (const { name, value, start } of staticProperties(options)) {\n switch (name) {\n case 'initialState':\n case 'configs':\n break;\n case 'id':\n id = pageId(value, source, file);\n break;\n case 'hooks':\n if (value.type !== 'ObjectExpression') {\n break;\n }\n for (const hook of staticProperties(value)) {\n if (!HOOKS.has(hook.name)) {\n failAt(\n `Unknown page hook \\`${hook.name}\\`. Page hooks: ${PAGE_HOOKS.join(', ')}`,\n source,\n hook.start,\n file,\n );\n }\n hooks.push(hook.name);\n }\n break;\n case 'mutations':\n mutations = resolvedProperties(program, value);\n break;\n case 'actions':\n actions = resolvedProperties(program, value);\n break;\n default:\n if (isFunction(value)) {\n failAt(`\\`${name}\\` must go in \\`mutations\\` or \\`actions\\``, source, start, file);\n } else {\n failAt(\n `Unknown option \\`${name}\\`. definePage takes id, initialState, configs, hooks, mutations and actions`,\n source,\n start,\n file,\n );\n }\n }\n }\n const mutationNames = mutations?.map((property) => property.name) ?? null;\n const actionNames = actions?.map((property) => property.name) ?? null;\n const clash = mutationNames?.find((name) => actionNames?.includes(name));\n if (clash) {\n failAt(`\\`${clash}\\` is both a mutation and an action`, source, options.start, file);\n }\n return {\n id,\n mutations: mutationNames,\n actions: actionNames,\n hooks,\n handlerOffsets: offsetsOf([...(mutations ?? []), ...(actions ?? [])]),\n };\n}\n\nfunction isFunction(node: Expression): boolean {\n return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n// The properties of the object literal `node` is or names, or null when they cannot all be read\n// statically.\nfunction resolvedProperties(program: Program, node: Expression): StaticProperty[] | null {\n const object = resolveObject(program, node);\n if (!object) {\n return null;\n }\n const properties = staticProperties(object);\n return properties.length === object.properties.length ? properties : null;\n}\n\nfunction offsetsOf(properties: readonly StaticProperty[]): Record<string, number> {\n const offsets: Record<string, number> = {};\n for (const property of properties) {\n offsets[property.name] = property.start;\n }\n return offsets;\n}\n\n/** Follows `export default state` back to `const state = { ... }`. */\nfunction resolveObject(program: Program, node: Expression): ObjectExpression | null {\n const target = unwrapExpression(node);\n if (target.type === 'ObjectExpression') {\n return target;\n }\n if (target.type !== 'Identifier') {\n return null;\n }\n\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n if (declaration?.type !== 'VariableDeclaration' || declaration.kind !== 'const') {\n continue;\n }\n for (const declarator of declaration.declarations) {\n if (declarator.id.type === 'Identifier' && declarator.id.name === target.name) {\n return declarator.init ? resolveObject(program, declarator.init) : null;\n }\n }\n }\n return null;\n}\n\n/** Reads a page id, which must be a string literal made of safe characters. */\nexport function pageId(node: Expression, source: string, file: string): string {\n const value = unwrapExpression(node);\n if (value.type !== 'Literal' || typeof value.value !== 'string') {\n return failAt('A page id must be a string literal', source, node.start, file);\n }\n if (!isPageId(value.value)) {\n return failAt(\n `Invalid page id \"${value.value}\". Use letters, digits, \"-\" and \"_\", with \"/\" between segments`,\n source,\n node.start,\n file,\n );\n }\n return value.value;\n}\n","import { failAt } from './errors';\nimport { pageId } from './ast/page/parse';\nimport { defineCall, parseModule } from './module';\nimport { staticProperties, unwrapExpression } from './utils';\n\nexport interface DotModuleIR {\n readonly pages: readonly string[];\n readonly lastPage: { readonly start: number; readonly end: number };\n}\n\nexport function parseDotModule(source: string, file = 'dot.ts'): DotModuleIR {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'defineDot');\n const pagesProperty = staticProperties(options).find((property) => property.name === 'pages');\n if (!pagesProperty) {\n return failAt(\n \"defineDot needs `pages`: the dot's page folders, starting page first\",\n source,\n options.start,\n file,\n );\n }\n const { value, start } = pagesProperty;\n const array = unwrapExpression(value);\n if (array.type !== 'ArrayExpression') {\n return failAt('`pages` must be an array of page folders', source, start, file);\n }\n if (array.elements.length === 0) {\n return failAt('`pages` needs at least one page', source, start, file);\n }\n const pages = array.elements.map((element) => {\n if (!element || element.type === 'SpreadElement') {\n return failAt(\n '`pages` must list each page folder as a string',\n source,\n element?.start ?? start,\n file,\n );\n }\n return pageId(element, source, file);\n });\n const last = array.elements.at(-1)!;\n return { pages, lastPage: { start: last.start, end: last.end } };\n}\n","export const UNARY_OPERATORS = ['!', '-', '+', 'typeof'] as const;\n\nexport const BINARY_OPERATORS = [\n '==',\n '!=',\n '===',\n '!==',\n '<',\n '<=',\n '>',\n '>=',\n '+',\n '-',\n '*',\n '/',\n '%',\n '**',\n '&&',\n '||',\n '??',\n] as const;\n\nexport type LiteralValue = string | number | boolean | null;\n\nexport type LiteralNode = { readonly type: 'Literal'; readonly value: LiteralValue };\n\nexport type IdentifierNode = { readonly type: 'Identifier'; readonly name: string };\n\nexport type MemberNode = {\n readonly type: 'Member';\n readonly object: ExprNode;\n readonly property: ExprNode;\n};\n\nexport type UnaryOperator = (typeof UNARY_OPERATORS)[number];\n\nexport type UnaryExprNode = {\n readonly type: 'Unary';\n readonly operator: UnaryOperator;\n readonly argument: ExprNode;\n};\n\nexport type BinaryOperator = (typeof BINARY_OPERATORS)[number];\n\nexport type BinaryExprNode = {\n readonly type: 'Binary';\n readonly operator: BinaryOperator;\n readonly left: ExprNode;\n readonly right: ExprNode;\n};\n\nexport type ConditionalExprNode = {\n readonly type: 'Conditional';\n readonly test: ExprNode;\n readonly consequent: ExprNode;\n readonly alternate: ExprNode;\n};\n\nexport type ExprNode =\n LiteralNode | IdentifierNode | MemberNode | UnaryExprNode | BinaryExprNode | ConditionalExprNode;\n","import type { Expression } from 'oxc-parser';\nimport { parseSync } from 'oxc-parser';\n\nimport { failAt, failOnSyntaxError } from '../../errors';\nimport { BINARY_OPERATORS, type ExprNode, UNARY_OPERATORS } from './types';\n\n// Parses the body of a binding (`{{ }}`) into an expression tree.\nexport function parseExpression(source: string): ExprNode {\n if (source.trim().length === 0) {\n failAt('Empty expression', source, 0);\n }\n const { program, errors } = parseSync('binding.js', source, { preserveParens: false });\n failOnSyntaxError(errors, source);\n const [statement, extra] = program.body;\n if (!statement || extra || statement.type !== 'ExpressionStatement') {\n return failAt('Expected a single expression statement', source, statement?.start ?? 0);\n }\n return convert(statement.expression, source);\n}\n\nfunction convert(node: Expression, source: string): ExprNode {\n switch (node.type) {\n case 'Literal':\n if (typeof node.value === 'bigint' || node.value instanceof RegExp) {\n break;\n }\n return { type: 'Literal', value: node.value };\n case 'Identifier':\n return { type: 'Identifier', name: node.name };\n case 'MemberExpression': {\n if (node.object.type === 'Super' || node.property.type === 'PrivateIdentifier') {\n break;\n }\n const object = convert(node.object, source);\n if (node.computed) {\n return { type: 'Member', object, property: convert(node.property, source) };\n }\n return { type: 'Member', object, property: { type: 'Literal', value: node.property.name } };\n }\n case 'UnaryExpression': {\n if (!isOneOf(UNARY_OPERATORS, node.operator)) {\n break;\n }\n return { type: 'Unary', operator: node.operator, argument: convert(node.argument, source) };\n }\n case 'BinaryExpression':\n case 'LogicalExpression': {\n if (node.left.type === 'PrivateIdentifier' || !isOneOf(BINARY_OPERATORS, node.operator)) {\n break;\n }\n return {\n type: 'Binary',\n operator: node.operator,\n left: convert(node.left, source),\n right: convert(node.right, source),\n };\n }\n case 'ConditionalExpression': {\n return {\n type: 'Conditional',\n test: convert(node.test, source),\n consequent: convert(node.consequent, source),\n alternate: convert(node.alternate, source),\n };\n }\n case 'CallExpression':\n case 'NewExpression':\n return failAt('Function calls are currently not allowed in bindings', source, node.start);\n case 'AssignmentExpression':\n case 'UpdateExpression':\n return failAt('Update expressions are currently not allowed in bindings', source, node.start);\n }\n let detail = '';\n if ('operator' in node) {\n detail = ` \\`${node.operator}\\``;\n }\n return failAt(`Unsupported syntax in binding: ${node.type}${detail}`, source, node.start);\n}\n\nfunction isOneOf<T extends string>(list: readonly T[], value: string): value is T {\n return (list as readonly string[]).includes(value);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/utils.ts","../src/errors.ts","../src/module.ts","../src/globals.ts","../src/ast/page/parse.ts","../src/dot.ts","../src/ast/expression/types.ts","../src/ast/expression/parse.ts"],"sourcesContent":["import type { Expression, ObjectExpression, Program, PropertyKey } from 'oxc-parser';\n\ntype TopLevelStatement = Program['body'][number];\n\nfunction propertyName(key: PropertyKey): string | null {\n if (key.type === 'Identifier') {\n return key.name;\n }\n if (key.type === 'Literal' && typeof key.value === 'string') {\n return key.value;\n }\n return null;\n}\n\nexport function unwrapExpression(node: Expression): Expression {\n while (\n node.type === 'TSAsExpression' ||\n node.type === 'TSSatisfiesExpression' ||\n node.type === 'TSNonNullExpression'\n ) {\n node = node.expression;\n }\n return node;\n}\n\nexport interface StaticProperty {\n readonly name: string;\n readonly value: Expression;\n readonly start: number;\n}\n\n// The properties of an object literal whose names are written out, skipping computed ones.\nexport function staticProperties(object: ObjectExpression): StaticProperty[] {\n const properties: StaticProperty[] = [];\n for (const property of object.properties) {\n if (property.type !== 'Property' || property.computed) {\n continue;\n }\n const name = propertyName(property.key);\n if (name !== null) {\n properties.push({ name, value: property.value, start: property.start });\n }\n }\n return properties;\n}\n\n// The declaration inside `export const ...` and the like; other statements as they are.\nexport function withoutExport(statement: TopLevelStatement): TopLevelStatement | null {\n if (statement.type === 'ExportNamedDeclaration') {\n return statement.declaration;\n }\n return statement;\n}\n","import type { OxcError } from 'oxc-parser';\nimport { locationAt, SourceError } from '@monimesl/dot-core';\n\nexport class ScriptParseError extends SourceError {\n override readonly name = 'ScriptParseError';\n}\n\nexport function failAt(reason: string, source: string, offset: number, file?: string): never {\n throw new ScriptParseError(reason, file, locationAt(source, offset));\n}\n\nexport function failOnSyntaxError(\n errors: readonly OxcError[],\n source: string,\n file?: string,\n): void {\n const [error] = errors;\n if (error) {\n failAt(error.message, source, error.labels[0]?.start ?? 0, file);\n }\n}\n","import { parseSync } from 'oxc-parser';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport { unwrapExpression } from './utils';\nimport { failAt, failOnSyntaxError } from './errors';\n\nexport function parseModule(source: string, file: string): Program {\n const { program, errors } = parseSync(file, source, { lang: 'ts', sourceType: 'module' });\n failOnSyntaxError(errors, source, file);\n return program;\n}\n\nexport function defaultExport(program: Program): Expression | undefined {\n for (const statement of program.body) {\n if (statement.type !== 'ExportDefaultDeclaration') {\n continue;\n }\n const { declaration } = statement;\n switch (declaration.type) {\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n case 'TSInterfaceDeclaration':\n return undefined;\n default:\n return declaration;\n }\n }\n return undefined;\n}\n\nexport function defineCall(\n program: Program,\n source: string,\n file: string,\n callee: string,\n): ObjectExpression {\n const exported = defaultExport(program);\n const call = exported && unwrapExpression(exported);\n const options = call?.type === 'CallExpression' ? call.arguments[0] : undefined;\n if (\n call?.type !== 'CallExpression' ||\n call.callee.type !== 'Identifier' ||\n call.callee.name !== callee ||\n options?.type !== 'ObjectExpression'\n ) {\n return failAt(\n `${fileName(file)} must \\`export default ${callee}({ ... })\\``,\n source,\n exported?.start ?? 0,\n file,\n );\n }\n return options;\n}\n\n// The last segment of a path, with either separator.\nfunction fileName(path: string): string {\n const lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\\\'));\n return path.slice(lastSeparator + 1);\n}\n","import type { Program } from 'oxc-parser';\n\nimport { parseModule } from './module';\nimport { withoutExport } from './utils';\n\ninterface Node {\n readonly type: string;\n readonly [key: string]: unknown;\n}\n\n// Which of `names` a module reads without binding them at top level, for the compiler to import.\nexport function unboundReferences(\n source: string,\n names: readonly string[],\n file = 'module.ts',\n): string[] {\n const program = parseModule(source, file);\n const bound = topLevelBindings(program);\n const references = new Set<string>();\n collectReferences(program as unknown as Node, null, '', references);\n return names.filter((name) => references.has(name) && !bound.has(name));\n}\n\nfunction topLevelBindings(program: Program): Set<string> {\n const names = new Set<string>();\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n switch (declaration?.type) {\n case 'ImportDeclaration':\n for (const specifier of declaration.specifiers) {\n names.add(specifier.local.name);\n }\n break;\n case 'VariableDeclaration':\n for (const declarator of declaration.declarations) {\n collectPatternNames(declarator.id as unknown as Node, names);\n }\n break;\n case 'FunctionDeclaration':\n case 'ClassDeclaration':\n if (declaration.id) {\n names.add(declaration.id.name);\n }\n break;\n }\n }\n return names;\n}\n\nfunction collectPatternNames(pattern: Node, names: Set<string>): void {\n const visit = (child: unknown) => {\n if (isNode(child)) {\n collectPatternNames(child, names);\n }\n };\n switch (pattern.type) {\n case 'Identifier':\n names.add(pattern.name as string);\n break;\n case 'ObjectPattern':\n for (const property of pattern.properties as Node[]) {\n visit(property.type === 'RestElement' ? property.argument : property.value);\n }\n break;\n case 'ArrayPattern':\n for (const element of pattern.elements as unknown[]) {\n visit(element);\n }\n break;\n case 'RestElement':\n visit(pattern.argument);\n break;\n case 'AssignmentPattern':\n visit(pattern.left);\n break;\n }\n}\n\nfunction collectReferences(node: Node, parent: Node | null, key: string, out: Set<string>): void {\n if (node.type === 'ImportDeclaration') {\n return;\n }\n if (node.type === 'Identifier' && isReference(parent, key)) {\n out.add(node.name as string);\n }\n for (const [childKey, value] of Object.entries(node)) {\n for (const child of Array.isArray(value) ? value : [value]) {\n if (isNode(child)) {\n collectReferences(child, node, childKey, out);\n }\n }\n }\n}\n\n/** False for identifiers that name a property or label rather than refer to a variable. */\nfunction isReference(parent: Node | null, key: string): boolean {\n switch (parent?.type) {\n case 'MemberExpression':\n return key !== 'property' || parent.computed === true;\n case 'Property':\n case 'MethodDefinition':\n case 'PropertyDefinition':\n return key !== 'key' || parent.computed === true;\n case 'LabeledStatement':\n case 'BreakStatement':\n case 'ContinueStatement':\n return key !== 'label';\n default:\n return true;\n }\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof (value as Node | null)?.type === 'string';\n}\n","import { isPageId, PAGE_HOOKS } from '@monimesl/dot-core';\nimport type { Expression, ObjectExpression, Program } from 'oxc-parser';\n\nimport type { PageModule, PageStateModule } from './types';\nimport { failAt } from '../../errors';\nimport { defaultExport, defineCall, parseModule } from '../../module';\nimport type { StaticProperty } from '../../utils';\nimport { staticProperties, unwrapExpression, withoutExport } from '../../utils';\n\nconst HOOKS = new Set<string>(PAGE_HOOKS);\n\nexport function parseStateModule(source: string, file = 'state.ts'): PageStateModule {\n const program = parseModule(source, file);\n const exported = defaultExport(program);\n if (!exported) {\n return failAt('state.ts must have a default export', source, 0, file);\n }\n const properties = resolvedProperties(program, exported);\n return {\n keys: namesOf(properties),\n keyOffsets: offsetsOf(properties ?? []),\n };\n}\n\nexport function parseLogicModule(source: string, file = 'controller.ts'): PageModule {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'definePage');\n let id: string | null = null;\n let mutations: StaticProperty[] | null = [];\n let actions: StaticProperty[] | null = [];\n const hooks: string[] = [];\n for (const { name, value, start } of staticProperties(options)) {\n switch (name) {\n case 'initialState':\n case 'configs':\n break;\n case 'id':\n id = pageId(value, source, file);\n break;\n case 'hooks':\n if (value.type !== 'ObjectExpression') {\n break;\n }\n for (const hook of staticProperties(value)) {\n if (!HOOKS.has(hook.name)) {\n failAt(\n `Unknown page hook \\`${hook.name}\\`. The hooks are ${PAGE_HOOKS.join(', ')}`,\n source,\n hook.start,\n file,\n );\n }\n hooks.push(hook.name);\n }\n break;\n case 'mutations':\n mutations = resolvedProperties(program, value);\n break;\n case 'actions':\n actions = resolvedProperties(program, value);\n break;\n default:\n if (isFunction(value)) {\n failAt(`\\`${name}\\` must go in \\`mutations\\` or \\`actions\\``, source, start, file);\n } else {\n failAt(\n `Unknown option \\`${name}\\`. definePage takes id, initialState, configs, hooks, mutations and actions`,\n source,\n start,\n file,\n );\n }\n }\n }\n const mutationNames = namesOf(mutations);\n const actionNames = namesOf(actions);\n const clash = mutationNames?.find((name) => actionNames?.includes(name));\n if (clash) {\n failAt(`\\`${clash}\\` is both a mutation and an action`, source, options.start, file);\n }\n return {\n id,\n mutations: mutationNames,\n actions: actionNames,\n hooks,\n handlerOffsets: offsetsOf([...(mutations ?? []), ...(actions ?? [])]),\n };\n}\n\nfunction isFunction(node: Expression): boolean {\n return node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';\n}\n\n// The properties of the object literal `node` is or names, or null when they cannot all be read\n// statically.\nfunction resolvedProperties(program: Program, node: Expression): StaticProperty[] | null {\n const object = resolveObject(program, node);\n if (!object) {\n return null;\n }\n const properties = staticProperties(object);\n return properties.length === object.properties.length ? properties : null;\n}\n\nfunction namesOf(properties: readonly StaticProperty[] | null): string[] | null {\n return properties?.map((property) => property.name) ?? null;\n}\n\nfunction offsetsOf(properties: readonly StaticProperty[]): Record<string, number> {\n const offsets: Record<string, number> = {};\n for (const property of properties) {\n offsets[property.name] = property.start;\n }\n return offsets;\n}\n\n/** Follows `export default state` back to `const state = { ... }`. */\nfunction resolveObject(program: Program, node: Expression): ObjectExpression | null {\n const target = unwrapExpression(node);\n if (target.type === 'ObjectExpression') {\n return target;\n }\n if (target.type !== 'Identifier') {\n return null;\n }\n\n for (const statement of program.body) {\n const declaration = withoutExport(statement);\n if (declaration?.type !== 'VariableDeclaration' || declaration.kind !== 'const') {\n continue;\n }\n for (const declarator of declaration.declarations) {\n if (declarator.id.type === 'Identifier' && declarator.id.name === target.name) {\n return declarator.init ? resolveObject(program, declarator.init) : null;\n }\n }\n }\n return null;\n}\n\n/** Reads a page id, which must be a string literal made of safe characters. */\nexport function pageId(node: Expression, source: string, file: string): string {\n const value = unwrapExpression(node);\n if (value.type !== 'Literal' || typeof value.value !== 'string') {\n return failAt(\n \"A page id must be written as a string, such as 'cart'\",\n source,\n node.start,\n file,\n );\n }\n if (!isPageId(value.value)) {\n return failAt(\n `\"${value.value}\" isn't a valid page id. Use letters, digits, \"-\" and \"_\", with \"/\" between folders`,\n source,\n node.start,\n file,\n );\n }\n return value.value;\n}\n","import { failAt } from './errors';\nimport { pageId } from './ast/page/parse';\nimport { defineCall, parseModule } from './module';\nimport { staticProperties, unwrapExpression } from './utils';\n\nexport interface DotModuleIR {\n readonly pages: readonly string[];\n readonly lastPage: { readonly start: number; readonly end: number };\n}\n\nexport function parseDotModule(source: string, file = 'dot.ts'): DotModuleIR {\n const program = parseModule(source, file);\n const options = defineCall(program, source, file, 'defineDot');\n const pagesProperty = staticProperties(options).find((property) => property.name === 'pages');\n if (!pagesProperty) {\n return failAt(\n 'defineDot needs `pages`: the page folders, with the first page first',\n source,\n options.start,\n file,\n );\n }\n const { value, start } = pagesProperty;\n const array = unwrapExpression(value);\n if (array.type !== 'ArrayExpression') {\n return failAt('`pages` must be a list of page folders', source, start, file);\n }\n if (array.elements.length === 0) {\n return failAt('`pages` needs at least one page', source, start, file);\n }\n const pages = array.elements.map((element) => {\n if (!element || element.type === 'SpreadElement') {\n return failAt(\n '`pages` must list each page folder as a string',\n source,\n element?.start ?? start,\n file,\n );\n }\n return pageId(element, source, file);\n });\n const last = array.elements.at(-1)!;\n return { pages, lastPage: { start: last.start, end: last.end } };\n}\n","export const UNARY_OPERATORS = ['!', '-', '+', 'typeof'] as const;\n\nexport const BINARY_OPERATORS = [\n '==',\n '!=',\n '===',\n '!==',\n '<',\n '<=',\n '>',\n '>=',\n '+',\n '-',\n '*',\n '/',\n '%',\n '**',\n '&&',\n '||',\n '??',\n] as const;\n\nexport type LiteralValue = string | number | boolean | null;\n\ntype LiteralNode = { readonly type: 'Literal'; readonly value: LiteralValue };\n\ntype IdentifierNode = { readonly type: 'Identifier'; readonly name: string };\n\ntype MemberNode = {\n readonly type: 'Member';\n readonly object: ExprNode;\n readonly property: ExprNode;\n};\n\nexport type UnaryOperator = (typeof UNARY_OPERATORS)[number];\n\ntype UnaryExprNode = {\n readonly type: 'Unary';\n readonly operator: UnaryOperator;\n readonly argument: ExprNode;\n};\n\nexport type BinaryOperator = (typeof BINARY_OPERATORS)[number];\n\ntype BinaryExprNode = {\n readonly type: 'Binary';\n readonly operator: BinaryOperator;\n readonly left: ExprNode;\n readonly right: ExprNode;\n};\n\ntype ConditionalExprNode = {\n readonly type: 'Conditional';\n readonly test: ExprNode;\n readonly consequent: ExprNode;\n readonly alternate: ExprNode;\n};\n\nexport type ExprNode =\n LiteralNode | IdentifierNode | MemberNode | UnaryExprNode | BinaryExprNode | ConditionalExprNode;\n","import type { Expression } from 'oxc-parser';\nimport { parseSync } from 'oxc-parser';\n\nimport { failAt, failOnSyntaxError } from '../../errors';\nimport { BINARY_OPERATORS, type ExprNode, UNARY_OPERATORS } from './types';\n\n// Parses the body of a binding (`{{ }}`) into an expression tree.\nexport function parseExpression(source: string): ExprNode {\n if (source.trim().length === 0) {\n failAt('The binding is empty', source, 0);\n }\n const { program, errors } = parseSync('binding.js', source, { preserveParens: false });\n failOnSyntaxError(errors, source);\n const [statement, extra] = program.body;\n if (!statement || extra || statement.type !== 'ExpressionStatement') {\n return failAt('A binding must be one expression', source, statement?.start ?? 0);\n }\n return convert(statement.expression, source);\n}\n\nfunction convert(node: Expression, source: string): ExprNode {\n switch (node.type) {\n case 'Literal':\n if (typeof node.value === 'bigint' || node.value instanceof RegExp) {\n break;\n }\n return { type: 'Literal', value: node.value };\n case 'Identifier':\n return { type: 'Identifier', name: node.name };\n case 'MemberExpression': {\n if (node.object.type === 'Super' || node.property.type === 'PrivateIdentifier') {\n break;\n }\n const object = convert(node.object, source);\n if (node.computed) {\n return { type: 'Member', object, property: convert(node.property, source) };\n }\n return { type: 'Member', object, property: { type: 'Literal', value: node.property.name } };\n }\n case 'UnaryExpression':\n if (!isOneOf(UNARY_OPERATORS, node.operator)) {\n break;\n }\n return { type: 'Unary', operator: node.operator, argument: convert(node.argument, source) };\n case 'BinaryExpression':\n case 'LogicalExpression':\n if (node.left.type === 'PrivateIdentifier' || !isOneOf(BINARY_OPERATORS, node.operator)) {\n break;\n }\n return {\n type: 'Binary',\n operator: node.operator,\n left: convert(node.left, source),\n right: convert(node.right, source),\n };\n case 'ConditionalExpression':\n return {\n type: 'Conditional',\n test: convert(node.test, source),\n consequent: convert(node.consequent, source),\n alternate: convert(node.alternate, source),\n };\n case 'CallExpression':\n case 'NewExpression':\n return failAt(\"Bindings can't call functions\", source, node.start);\n case 'AssignmentExpression':\n case 'UpdateExpression':\n return failAt(\"Bindings can't change values\", source, node.start);\n }\n let detail = '';\n if ('operator' in node) {\n detail = ` \\`${node.operator}\\``;\n }\n return failAt(`Bindings can't use ${node.type}${detail}`, source, node.start);\n}\n\nfunction isOneOf<T extends string>(list: readonly T[], value: string): value is T {\n return (list as readonly string[]).includes(value);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monimesl/dot-script-parser",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "Dot page script parser: page state and logic -> intermediary representation",
5
5
  "type": "module",
6
6
  "repository": {
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "oxc-parser": "^0.151.0",
35
- "@monimesl/dot-core": "0.1.0-alpha.8"
35
+ "@monimesl/dot-core": "0.1.0-alpha.9"
36
36
  },
37
37
  "publishConfig": {
38
38
  "access": "public"