@flatkit/compiler 0.19.8 → 0.19.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/analysis.js +1 -1
- package/dist/{chunk-C7TYJ6ZA.js → chunk-2NAWPQKH.js} +2 -2
- package/dist/{chunk-AMSWZXQA.js → chunk-AJKZ7C3H.js} +4 -1
- package/dist/chunk-AJKZ7C3H.js.map +1 -0
- package/dist/cli/flatc.js +2 -2
- package/dist/index.js +2 -2
- package/package.json +4 -4
- package/dist/chunk-AMSWZXQA.js.map +0 -1
- /package/dist/{chunk-C7TYJ6ZA.js.map → chunk-2NAWPQKH.js.map} +0 -0
package/dist/analysis.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
docHasErrors,
|
|
3
3
|
lintDocReport
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AJKZ7C3H.js";
|
|
5
5
|
import {
|
|
6
6
|
compileFlatpack,
|
|
7
7
|
packToJSON
|
|
@@ -492,4 +492,4 @@ function run(argv) {
|
|
|
492
492
|
export {
|
|
493
493
|
run
|
|
494
494
|
};
|
|
495
|
-
//# sourceMappingURL=chunk-
|
|
495
|
+
//# sourceMappingURL=chunk-2NAWPQKH.js.map
|
|
@@ -41,6 +41,7 @@ function lint(src, ctx = {}) {
|
|
|
41
41
|
for (const v of ctx.variables ?? []) variables.add(v);
|
|
42
42
|
const knownIds = /* @__PURE__ */ new Set([...STD_IDS, ...STD_CONSTANTS, ...variables]);
|
|
43
43
|
const knownFns = new Set(STD_FUNCTIONS);
|
|
44
|
+
knownFns.add("velocity");
|
|
44
45
|
for (const u of units) {
|
|
45
46
|
if (u.kind === "func") knownFns.add(u.func.name);
|
|
46
47
|
else if (u.kind === "use") for (const name of packageFunctionNames(u.name)) knownFns.add(name);
|
|
@@ -403,6 +404,8 @@ function docModifierWarnings(doc) {
|
|
|
403
404
|
}
|
|
404
405
|
};
|
|
405
406
|
visit(contextLayers(doc, editPath).flatMap((l) => l.items));
|
|
407
|
+
if (/\bvelocity\s*\(/.test(scopeProgram(doc, editPath)))
|
|
408
|
+
out.push({ scope: label, diag: { line: 1, col: 1, message: "velocity() is only valid inside a spring/smooth target, not a plain expression" } });
|
|
406
409
|
}
|
|
407
410
|
return out;
|
|
408
411
|
}
|
|
@@ -433,4 +436,4 @@ export {
|
|
|
433
436
|
lintDocReport,
|
|
434
437
|
docHasErrors
|
|
435
438
|
};
|
|
436
|
-
//# sourceMappingURL=chunk-
|
|
439
|
+
//# sourceMappingURL=chunk-AJKZ7C3H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lint.ts","../src/scopeProgram.ts","../src/programDoc.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────────────────────────────\n// lint.ts — linter for the FlatInk Script language (batch L3).\n//\n// Builds on the parser (dsl.ts) for syntax errors + positions, then adds\n// SEMANTIC validation, ~free and PURE:\n// • each expression is compiled (compileExpr) → expression syntax error;\n// • referenced functions / member objects / identifiers are checked against\n// the standard environment (expr.ts) + the known variables → \"unknown\";\n// • `go to \"label\"` is checked against the set of known labels.\n//\n// Tolerant and kid-friendly: a variable is \"known\" if it is declared\n// (`let`) OR simply assigned (`x = …`) somewhere in the source, or provided\n// by the caller (document global variables). Labels are only checked\n// if the caller provides their list (otherwise we don't know the universe).\n// ─────────────────────────────────────────────────────────────────────────────\nimport { analyzeExpr, STD_CONSTANTS, STD_FUNCTIONS, STD_IDS, STD_OBJECTS } from '@flatkit/engine/expr'\nimport { packageFunctionNames } from '@flatkit/engine/stdlib'\nimport { parseUnits, type Diagnostic, type ScriptUnit } from '@flatkit/engine/dsl'\nimport type { Action } from '@flatkit/engine/actions'\n\nexport type LintContext = {\n /** Known variables in addition to those declared/assigned in the source. */\n variables?: Iterable<string>\n /** Known labels (timeline). Absent = we don't check `go to \"…\"`. */\n labels?: Iterable<string>\n /** Known functions in addition to those defined in the source. */\n functions?: Iterable<string>\n /** Scene objects referenceable by name (`Hero.x`) — in addition to mouse/keys. */\n objects?: Iterable<string>\n}\n\n/** Collects the names of ASSIGNED variables (setVar) + loop vars, inside action bodies. */\nfunction collectAssigned(actions: Action[], into: Set<string>): void {\n for (const a of actions) {\n if (a.do === 'setVar') into.add(a.name)\n else if (a.do === 'if') {\n collectAssigned(a.then, into)\n if (a.else) collectAssigned(a.else, into)\n } else if (a.do === 'repeat') collectAssigned(a.body, into)\n else if (a.do === 'repeatRange') { into.add(a.var); collectAssigned(a.body, into) } // i is known in the body\n }\n}\n\n/** Locally known variables: `let` declarations + every assigned variable. */\nexport function localVariables(units: ScriptUnit[]): Set<string> {\n const vars = new Set<string>()\n for (const u of units) {\n if (u.kind === 'declare') vars.add(u.name)\n else if (u.kind === 'event' || u.kind === 'frameActions') collectAssigned(u.body, vars)\n else if (u.kind === 'each') vars.add(u.as) // the index is known in the each bindings\n else if (u.kind === 'interactor') { if (u.varX) vars.add(u.varX); if (u.varY) vars.add(u.varY) } // drag writes these variables\n else if (u.kind === 'drop') collectAssigned(u.body, vars)\n else if (u.kind === 'func') { for (const p of u.func.params) vars.add(p); if (u.func.kind === 'proc') collectAssigned(u.func.body, vars) } // params + assignments\n }\n return vars\n}\n\n/** Detects a `text(` call (whole word) in an expression → only allowed in a `send` payload. */\nconst TEXT_CALL = /\\btext\\s*\\(/\n\n/** A bare assignment (`x =`, `a[i] =`; NOT ==/<=/>=/!=) left inside an expression: the tell-tale of a\n * SECOND statement crammed onto one line (FlatInk ends a statement at the newline, so it got swallowed). */\nconst SECOND_ASSIGN = /[\\w\\]]\\s*=(?![=])/\n\n/** Analyze a DSL source and return all diagnostics (syntax + semantic). */\nexport function lint(src: string, ctx: LintContext = {}): Diagnostic[] {\n const { units, diagnostics, sites } = parseUnits(src)\n const out: Diagnostic[] = [...diagnostics]\n\n const variables = localVariables(units)\n for (const v of ctx.variables ?? []) variables.add(v)\n const knownIds = new Set<string>([...STD_IDS, ...STD_CONSTANTS, ...variables])\n const knownFns = new Set(STD_FUNCTIONS)\n knownFns.add('velocity') // valid inside a spring/smooth target (resolved by the modifier advance); NOT a stdlib\n for (const u of units) {\n if (u.kind === 'func') knownFns.add(u.func.name) // user-defined functions\n else if (u.kind === 'use') for (const name of packageFunctionNames(u.name)) knownFns.add(name) // package functions (bare + qualified)\n }\n for (const f of ctx.functions ?? []) knownFns.add(f)\n const knownObjs = new Set(STD_OBJECTS)\n for (const o of ctx.objects ?? []) knownObjs.add(o) // scene objects (Hero.x…)\n const labels = ctx.labels ? new Set(ctx.labels) : null\n\n for (const s of sites) {\n if (s.kind === 'expr') {\n // `text(…)` is valid ONLY as a `send` payload (consumed by the parser, never\n // exposed as an expression site). Seeing it here = out-of-context use → dedicated error.\n if (TEXT_CALL.test(s.text)) {\n out.push({ line: s.line, col: s.col, message: 'text(\"…\") is only allowed as an argument to \"send\"' })\n continue\n }\n const a = analyzeExpr(s.text)\n if (!a.ok) {\n // #1 footgun: two statements on one line. The 2nd `channel = …` got swallowed into this\n // expression → a cryptic \"unexpected character =\". Detect the leftover assignment and say so.\n const message = SECOND_ASSIGN.test(s.text)\n ? 'two statements on one line — put each on its own line (FlatInk ends a statement at the newline)'\n : `invalid expression: ${a.error}`\n out.push({ line: s.line, col: s.col, message })\n continue\n }\n for (const fn of a.refs.calls) if (!knownFns.has(fn)) out.push({ line: s.line, col: s.col, message: `unknown function \"${fn}\"` })\n for (const o of a.refs.members)\n if (!knownObjs.has(o)) out.push({ line: s.line, col: s.col, message: `unknown object \"${o}\" (expected: ${[...knownObjs].join(', ')})` })\n for (const id of a.refs.ids)\n if (!knownIds.has(id))\n out.push({ line: s.line, col: s.col, message: `unknown variable \"${id}\"${variables.size ? '' : ' — declare it with \"let\"'}` })\n } else if (labels && !labels.has(s.name)) {\n out.push({ line: s.line, col: s.col, message: `unknown label \"${s.name}\"` })\n }\n }\n\n return out.sort((a, b) => a.line - b.line || a.col - b.col)\n}\n\n/**\n * Lint report ready to feed back to a generator (LLM/CLI): `''` = no issue (the code passes),\n * otherwise one `line:col: message` line per diagnostic. Primitive of the \"generate → lint →\n * fix\" loop: the language fits in few tokens, robustness comes from this feedback, not from context.\n */\nexport function lintReport(src: string, ctx: LintContext = {}): string {\n return lint(src, ctx).map((d) => `${d.line}:${d.col}: ${d.message}`).join('\\n')\n}\n","// ─────────────────────────────────────────────────────────────────────────────\n// scopeProgram.ts — the \"unified file\" of a scope (the Scene, or a Symbol).\n//\n// Vision: one file = one scope. All the code of a scope fits in ONE text:\n// var … (global variables, root only)\n// when loaded {} (lifecycle of the scope's timeline)\n// every frame {}\n// object \"name\" {} (one block per scripted object of the scope)\n//\n// This is the `.flatink` structure WITHOUT the geometry (which stays visual). This module\n// ONLY deals with the text: splitting the `object` blocks from the rest, and formatting a block.\n// The wiring to the Doc (a single commit) lives in the store, which reuses these functions\n// + scriptDoc/dsl. Pure, no DOM, testable.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** End of the block opened at `open` (index of the matching `}`), ignoring strings and comments. -1 if unclosed. */\nfunction matchBrace(s: string, open: number): number {\n let depth = 0\n for (let i = open; i < s.length; i++) {\n const c = s[i]\n if (c === '\"') { i++; while (i < s.length && s[i] !== '\"') { if (s[i] === '\\\\') i++; i++ }; continue }\n if (c === '/' && s[i + 1] === '/') { while (i < s.length && s[i] !== '\\n') i++; continue }\n if (c === '{') depth++\n else if (c === '}') { depth--; if (depth === 0) return i }\n }\n return -1\n}\n\n/** Splits a scope file: the `object \"name\" { … }` blocks on one side, the REST (var + lifecycle) on the other. */\nexport function splitScopeProgram(text: string): { rest: string; objects: { name: string; body: string }[] } {\n let rest = ''\n let i = 0\n const objects: { name: string; body: string }[] = []\n while (i < text.length) {\n const m = /object\\s+\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\{/.exec(text.slice(i))\n if (!m) { rest += text.slice(i); break }\n const start = i + m.index\n rest += text.slice(i, start)\n const ob = start + m[0].length - 1 // the opening brace\n const oc = matchBrace(text, ob)\n if (oc < 0) { rest += text.slice(start); break } // unclosed block → left to the rest (diagnostic downstream)\n objects.push({ name: m[1].replace(/\\\\(.)/g, (_, c) => (c === 'n' ? '\\n' : c)), body: text.slice(ob + 1, oc) })\n i = oc + 1\n }\n return { rest, objects }\n}\n\n/** LINTABLE regions of a scope file (the \"rest\" gaps + the `object` bodies), with their\n * 1-based start line in the original text — to lint each piece as pure DSL and\n * reproject the positions. The `object` keyword and its braces are NOT DSL: we skip them. */\nexport function scopeRegions(text: string): { body: string; line: number }[] {\n const lineAt = (off: number) => text.slice(0, off).split('\\n').length\n const regions: { body: string; line: number }[] = []\n let i = 0\n let restStart = 0\n while (i < text.length) {\n const m = /object\\s+\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\{/.exec(text.slice(i))\n if (!m) break\n const start = i + m.index\n const gap = text.slice(restStart, start)\n if (gap.trim()) regions.push({ body: gap, line: lineAt(restStart) })\n const ob = start + m[0].length - 1\n const oc = matchBrace(text, ob)\n if (oc < 0) break\n regions.push({ body: text.slice(ob + 1, oc), line: lineAt(ob + 1) })\n i = oc + 1\n restStart = i\n }\n const tail = text.slice(restStart)\n if (tail.trim()) regions.push({ body: tail, line: lineAt(restStart) })\n return regions\n}\n\nconst esc = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')\nconst indent = (body: string) => body.split('\\n').map((l) => (l.trim() ? ' ' + l : l)).join('\\n')\n\n/** Formats an `object \"name\" { … }` block (body already in DSL). */\nexport function formatObjectBlock(name: string, body: string): string {\n const inner = body.trim()\n return `object \"${esc(name)}\" {\\n${inner ? indent(inner) + '\\n' : ''}}`\n}\n\n/** Assembles a scope file: rest (var + lifecycle) then the object blocks, separated by a blank line. */\nexport function joinScopeProgram(rest: string, objects: { name: string; body: string }[]): string {\n const parts: string[] = []\n if (rest.trim()) parts.push(rest.trim())\n for (const o of objects) if (o.body.trim()) parts.push(formatObjectBlock(o.name, o.body))\n return parts.length ? parts.join('\\n\\n') + '\\n' : ''\n}\n","// -----------------------------------------------------------------------------\n// programDoc.ts — PURE bridge Doc <-> \"scope program\" (text) + lint of a whole Doc.\n//\n// Both the editor AND the CLI need to rebuild the DSL text of a scope (to display it,\n// or to lint it) and to assemble the lint context (variables/labels/functions/objects)\n// FROM a Doc — without depending on the React store. Everything lives here, pure and testable:\n// • `scopeProgram` : Doc fragments -> program text of a scope (round-trip via printUnits);\n// • `docLintContext` : Doc + scope -> LintContext (known names);\n// • `lintDoc` / report : semantic lint of ALL the scopes of a Doc (scene + symbols).\n// -> the CLI gains a `flatc --check`, the editor stops duplicating the logic.\n// -----------------------------------------------------------------------------\nimport type { Doc, EditFrame, Group, Instance } from '@flatkit/types'\nimport { printUnits, type Diagnostic } from '@flatkit/engine/dsl'\nimport { joinScopeProgram, scopeRegions } from './scopeProgram'\nimport { functionsToUnits, importsToUnits, objectToUnits, timelineToUnits, variablesToUnits } from '@flatkit/engine/scriptDoc'\nimport { contextLayers, getScopeTimeline, isContainer, isGroup, isText, isImage, isPoseable, isRegion } from '@flatkit/engine/layers'\nimport { importedFunctions } from '@flatkit/engine/stdlib'\nimport { EXPR_CHANNELS } from '@flatkit/engine/timeline'\nimport { objectNames } from '@flatkit/engine/sceneRefs'\nimport { itemBBox, dropZoneBounds } from '@flatkit/engine/groups'\nimport { makePathSampler } from '@flatkit/engine/path'\nimport { bboxIntersects } from '@flatkit/engine/bbox'\nimport { lint, localVariables, type LintContext } from './lint'\nimport { parseUnits } from '@flatkit/engine/dsl'\nimport type { Item, Layer, ParamDef, SymbolDef, Text } from '@flatkit/types'\n\n/** Rebuilds the \"program\" text of a scope (imports + variables + functions + scene cycle\n * + one `object \"Name\" { … }` block per scripted container with a unique name). Pure, round-trip via printUnits. */\nexport function scopeProgram(doc: Doc, editPath: EditFrame[] = []): string {\n const atRoot = editPath.length === 0\n const items = contextLayers(doc, editPath).flatMap((l) => l.items)\n const nameCount = new Map<string, number>()\n for (const it of items) if (isContainer(it) && it.name) nameCount.set(it.name, (nameCount.get(it.name) ?? 0) + 1)\n const scripted = (it: Group | Instance) => !!doc.interactions?.some((i) => i.targetId === it.id) || !!doc.interactors?.some((i) => i.targetId === it.id) || !!(it.expressions && Object.keys(it.expressions).length)\n const objects = items\n .filter((it): it is Group | Instance => isContainer(it) && !!it.name && nameCount.get(it.name) === 1 && scripted(it))\n .map((it) => ({ name: it.name, body: printUnits(objectToUnits(it.id, doc.interactions, it.expressions, doc.interactors)) }))\n const imports = atRoot ? printUnits(importsToUnits(doc.imports)) : ''\n const funcs = atRoot ? printUnits(functionsToUnits(doc.functions)) : ''\n const globals = atRoot ? printUnits(variablesToUnits(doc.variables)) : ''\n const scene = printUnits(timelineToUnits(getScopeTimeline(doc, editPath)))\n const head = [imports, globals, funcs, scene].filter((t) => t.trim()).join('\\n\\n')\n return joinScopeProgram(head, objects)\n}\n\n/** Lint context of a scope: known names (variables, labels, functions, objects) drawn from the Doc.\n * `extraVars` = variables assigned in the OTHER scopes (FlatInk variables are GLOBAL -> known\n * everywhere; avoids a false \"unknown variable\" on a var written elsewhere, e.g. generated by `match`). */\nexport function docLintContext(doc: Doc, editPath: EditFrame[] = [], extraVars?: Iterable<string>): LintContext {\n return {\n // A symbol's own `params` (and state params) are injected into its instance scope at runtime, so they are\n // valid variables in ITS `expr` -- add them, but ONLY to that symbol's scope (resolved from `editPath`),\n // never globally, so a param named in symbol A can't mask a real typo of the same name in symbol B.\n variables: [...Object.keys(doc.variables ?? {}), ...(extraVars ?? []), ...scopeSymbolParams(doc, editPath)],\n labels: (getScopeTimeline(doc, editPath)?.labels ?? []).map((l) => l.name),\n functions: [...(doc.functions ?? []).map((f) => f.name), ...importedFunctions(doc.imports).map((f) => f.name)],\n objects: objectNames(contextLayers(doc, editPath)),\n }\n}\n\n/** Names exposed as variables by the symbol of `editPath` (its `params` + state params), or `[]` for the\n * scene scope / an unresolved path. Mirrors the per-instance scope the runtime and `--preview` build. */\nfunction scopeSymbolParams(doc: Doc, editPath: EditFrame[]): string[] {\n const frame = [...editPath].reverse().find((f): f is Extract<EditFrame, { kind: 'symbol' }> => f.kind === 'symbol')\n const sym = frame ? doc.symbols.find((s) => s.id === frame.symbolId) : undefined\n if (!sym) return []\n return [...(sym.params ?? []).map((p) => p.name), ...(sym.states ?? []).map((s) => s.param)]\n}\n\n/** All the scopes of a Doc: the scene (root) + each symbol of the library. */\nfunction scopes(doc: Doc): { label: string; editPath: EditFrame[] }[] {\n return [{ label: 'scene', editPath: [] }, ...doc.symbols.map((s) => ({ label: s.name, editPath: [{ kind: 'symbol' as const, symbolId: s.id, name: s.name }] }))]\n}\n\n/** Union of the variables ASSIGNED in ALL the scopes (scene + symbols). FlatInk variables are\n * global -> a var written in one scope is legitimate in the others (cross-scope reads). */\nexport function allScopeVariables(doc: Doc): string[] {\n const set = new Set<string>()\n for (const { editPath } of scopes(doc))\n for (const r of scopeRegions(scopeProgram(doc, editPath)))\n for (const v of localVariables(parseUnits(r.body).units)) set.add(v)\n return [...set]\n}\n\n/** Readable name of an item by id (for the messages). */\nfunction itemNameById(doc: Doc, id: string): string | null {\n let found: string | null = null\n const walk = (layers: { items: import('@flatkit/types').Item[] }[]) => {\n for (const l of layers) for (const it of l.items) {\n if (found) return\n if ('name' in it && it.id === id) { found = it.name ?? null; return }\n if (isGroup(it)) walk(it.layers)\n }\n }\n walk(doc.layers)\n return found\n}\n\nconst escapeRe = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&')\n\n/** STRUCTURAL warnings (non-blocking) of a Doc: phantom drop zones, dead variables. */\nexport function docStructureWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n // (a) `when dropped on X` whose zone X does not exist (no item named so) -> the handler can never fire.\n const names = new Set(objectNames(doc.layers))\n for (const it of doc.interactions ?? []) {\n if (it.event === 'drop' && it.over && !names.has(it.over)) {\n const who = itemNameById(doc, it.targetId) ?? it.targetId\n out.push({ scope: 'scene', diag: { line: 1, col: 1, severity: 'warning', message: `unknown drop zone \"${it.over}\" (object \"${who}\") — no item of the scene carries this name` } })\n }\n }\n // (b) global variable never referenced (declared but not found in any scope) -> probably dead.\n const names0 = Object.keys(doc.variables ?? {})\n if (names0.length) {\n // Modifier targets are NOT emitted into scopeProgram (to avoid double-linting them, cf. docModifierWarnings),\n // so collect them here too — else a global used ONLY by a `spring`/`smooth` target reads as \"never used\".\n const modTargets: string[] = []\n const collectMods = (items: Item[]): void => {\n for (const it of items) {\n if (isPoseable(it) && it.modifiers) for (const ch of EXPR_CHANNELS) { const mm = it.modifiers[ch]; if (mm) modTargets.push(mm.target) }\n if (isGroup(it)) for (const l of it.layers) collectMods(l.items)\n }\n }\n for (const l of doc.layers) collectMods(l.items)\n for (const s of doc.symbols ?? []) for (const l of s.layers) collectMods(l.items)\n const allText = [...scopes(doc).map(({ editPath }) => scopeProgram(doc, editPath)), ...modTargets].join('\\n')\n for (const name of names0) {\n const m = allText.match(new RegExp(`(?<![\\\\w-])${escapeRe(name)}(?![\\\\w-])`, 'g'))\n if ((m?.length ?? 0) <= 1) out.push({ scope: 'scene', diag: { line: 1, col: 1, severity: 'warning', message: `global variable \"${name}\" never used (declared, but neither read nor written)` } })\n }\n }\n // (c) raw `time` in a channel expression + a SHORT looping timeline → ambient motion JUMPS on each loop\n // (`time = frame/fps` resets to 0 every `durationFrames`). The monotone `clock` never wraps.\n const dur = doc.timeline?.durationFrames ?? 60\n const fps = doc.timeline?.fps ?? 24\n if (dur <= 120) { // ≤ 5 s @24fps: short enough that the reset is visible as a periodic jump\n let usesTime = false\n const scan = (layers: Layer[]) => {\n for (const l of layers) for (const it of l.items) {\n if (isPoseable(it) && it.expressions) for (const k in it.expressions) if (/\\btime\\b/.test(it.expressions[k as keyof typeof it.expressions] ?? '')) usesTime = true\n if (isGroup(it)) scan(it.layers)\n }\n }\n scan(doc.layers)\n if (usesTime) {\n const secs = Math.round((dur / fps) * 10) / 10\n out.push(warn(`a channel expression uses \\`time\\`, but the timeline loops every ${secs}s (durationFrames ${dur}) — \\`time\\` resets each loop, so the motion jumps. Use the monotone \\`clock\\` (never wraps), drive it by \\`frame/${dur}\\`, or set a longer \\`timeline\\`.`))\n }\n }\n out.push(...docPaintParamWarnings(doc))\n out.push(...docLayoutWarnings(doc))\n return out\n}\n\n/** A scope's declared `color` param names (the only params usable as a paint color). */\nconst colorParamNames = (params?: ParamDef[]): Set<string> => new Set((params ?? []).filter((p) => p.type === 'color').map((p) => p.name))\n\n/**\n * A `color` param used as a paint (`fill`/`stroke`, a gradient **stop** `0:teinte@…`, or a `tint`) that the\n * owning symbol does NOT declare → a SILENT \"dead recolor\" (it falls back to the literal hex, the picker does\n * nothing). Warns per scope, with the param scoped to ITS symbol (the scene declares none). Mirrors how the\n * lint now knows a symbol's params in its `expr`. Non-blocking (a warning), so it never breaks a build.\n */\nexport function docPaintParamWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const checkScope = (scope: string, layers: Layer[], known: Set<string>) => {\n const flag = (param: string, where: string, who?: string) => {\n if (known.has(param)) return\n const hint = known.size ? `declared color params: ${[...known].join(', ')}` : 'this scope declares no color params'\n out.push({ scope, diag: { line: 1, col: 1, severity: 'warning', message: `unknown color param \"${param}\" in ${where}${who ? ` (${who})` : ''} — ${hint}` } })\n }\n const visit = (it: Item) => {\n const who = 'name' in it ? it.name : undefined\n if (isRegion(it)) {\n if (it.fillParam) flag(it.fillParam, 'a fill', who)\n if (it.strokeParam) flag(it.strokeParam, 'a stroke', who)\n const stops = it.paint && it.paint.type !== 'solid' ? it.paint.stops : []\n for (const s of stops) if (s.param) flag(s.param, 'a gradient stop', who)\n }\n if (isPoseable(it) && it.tint?.param) flag(it.tint.param, 'a tint', who)\n if (isGroup(it)) for (const l of it.layers) for (const c of l.items) visit(c) // a group is the same scope; an instance is a separate symbol (linted on its own pass)\n }\n for (const l of layers) for (const it of l.items) visit(it)\n }\n checkScope('scene', doc.layers, new Set())\n for (const s of doc.symbols) checkScope(s.name, s.layers, colorParamNames((s as SymbolDef).params))\n return out\n}\n\nconst warn = (message: string): { scope: string; diag: Diagnostic } => ({ scope: 'scene', diag: { line: 1, col: 1, severity: 'warning', message } })\nconst itemLabel = (it: Item): string => ('name' in it && it.name ? it.name : 'kind' in it ? it.kind : 'path')\n/** Estimated width of the longest line (approximate metric, without canvas). */\nfunction estTextWidth(t: Text): number {\n const advance = (t.weight && t.weight >= 700 ? 0.56 : 0.52) * t.size // mean advance of a proportional glyph\n let longest = 0\n for (const line of t.content.split('\\n')) longest = Math.max(longest, line.length)\n return longest * advance\n}\n\n/** LAYOUT warnings (non-blocking): canvas overflow, text too wide, overlapping hitboxes.\n * Approximate but without canvas — catches \"blind\" positioning bugs before the render. */\nexport function docLayoutWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const W = doc.width, H = doc.height\n const TOL = 8 // overflow tolerance (px) before alerting\n const r0 = (n: number) => Math.round(n)\n\n // (c) TEXT/IMAGE clipped at the canvas edge. Precise to avoid noise: we ignore `path`/groups\n // (decor that \"bleeds\" on purpose), objects driven by an expression (dynamic position ->\n // misleading static bbox), and items PARKED entirely off-screen (\"hidden\" pattern).\n const dynamicPos = (it: Item) => 'expressions' in it && it.expressions && (it.expressions.x != null || it.expressions.y != null)\n for (const layer of doc.layers) {\n for (const it of layer.items) {\n if (!(isText(it) || isImage(it)) || dynamicPos(it) || (isText(it) && it.textPath)) continue // path-laid text → §(f), not a box\n const b = itemBBox(doc, it)\n if (!b) continue\n const visible = b.maxX > 0 && b.minX < W && b.maxY > 0 && b.minY < H // overlaps the canvas (not parked off-screen)\n const clipped = b.minX < -TOL || b.minY < -TOL || b.maxX > W + TOL || b.maxY > H + TOL\n if (visible && clipped) {\n out.push(warn(`\"${itemLabel(it)}\" clipped at the canvas edge: bbox [${r0(b.minX)},${r0(b.minY)} -> ${r0(b.maxX)},${r0(b.maxY)}] outside 0,0 -> ${W},${H}`))\n }\n }\n }\n\n // (d) Text (without `wrap`) whose estimated width makes it OVERFLOW THE CANVAS -> instruction clipped.\n // (We do NOT compare against `box.w`: without wrap, a text overflows its box harmlessly as long as it\n // fits in the canvas — it is the canvas edge that clips.) Top-level only (x = world).\n for (const it of doc.layers.flatMap((l) => l.items)) {\n if (!isText(it) || it.wrap || it.textPath || dynamicPos(it)) continue\n const estW = estTextWidth(it)\n const left = it.align === 'left' ? 0 : it.align === 'right' ? it.box.w - estW : it.box.w / 2 - estW / 2\n const wl = it.transform.e + left, wr = wl + estW // left/right edge of the content in world coords\n if (wr > W + TOL || wl < -TOL) {\n out.push(warn(`text \"${it.content.slice(0, 24)}${it.content.length > 24 ? '…' : ''}\" overflows the canvas (estimated ~${r0(estW)} px, edge ${r0(wl)}->${r0(wr)} outside 0->${W}) — add \"wrap\"`))\n }\n }\n\n // (f) Text laid ALONG a path whose estimated run is longer than the path -> trailing glyphs dropped at\n // render (mirrors the canvas-overflow warning, but for the curve). Position-independent -> recurse.\n const pathTexts: Text[] = []\n const walkPathTexts = (layers: Layer[]) => { for (const l of layers) for (const it of l.items) { if (isText(it) && it.textPath) pathTexts.push(it); else if (isGroup(it)) walkPathTexts(it.layers) } }\n walkPathTexts(doc.layers)\n for (const it of pathTexts) {\n const L = makePathSampler(it.textPath!.path).length\n if (L <= 0) continue\n const advance = (it.weight && it.weight >= 700 ? 0.56 : 0.52) * it.size // same metric as estTextWidth\n const glyphs = [...it.content].length\n const eff = Math.max(advance + (it.textPath!.spacing ?? 0), 1) // mirror the renderer's per-glyph floor\n const estW = glyphs * eff\n if (estW > L + TOL) out.push(warn(`text \"${it.content.slice(0, 24)}${it.content.length > 24 ? '…' : ''}\" overflows its path (~${r0(estW)}px > ${r0(L)}px) — trailing glyphs are dropped`))\n }\n\n // (e) Drop zones (`hitbox`) that overlap -> ambiguous drop.\n const zones: { name: string; b: NonNullable<ReturnType<typeof dropZoneBounds>> }[] = []\n const collectZones = (layers: Layer[]) => {\n for (const l of layers) for (const it of l.items) {\n if (isGroup(it) && it.hitbox && it.name) { const b = dropZoneBounds(doc, it.name); if (b) zones.push({ name: it.name, b }) }\n if (isGroup(it)) collectZones(it.layers)\n }\n }\n collectZones(doc.layers)\n for (let i = 0; i < zones.length; i++) for (let j = i + 1; j < zones.length; j++) {\n if (bboxIntersects(zones[i].b, zones[j].b)) out.push(warn(`overlapping hitboxes: \"${zones[i].name}\" and \"${zones[j].name}\" -> ambiguous drop`))\n }\n return out\n}\n\n/** Semantic lint of a whole Doc (all the scopes) -> diagnostics labeled by scope.\n * The scope program contains `object` blocks (outside DSL) -> we lint each region\n * separately and re-project the lines (like the editor, cf. CodeEditor.lintFile).\n * Adds the structural warnings (phantom drop zones, dead variables). */\nexport function lintDoc(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const allVars = allScopeVariables(doc) // computed ONCE (global vars -> known in all the scopes)\n for (const { label, editPath } of scopes(doc)) {\n const ctx = docLintContext(doc, editPath, allVars)\n for (const r of scopeRegions(scopeProgram(doc, editPath))) for (const d of lint(r.body, ctx)) out.push({ scope: label, diag: { ...d, line: d.line + r.line - 1 } })\n }\n out.push(...docStructureWarnings(doc))\n out.push(...docModifierWarnings(doc))\n return out\n}\n\n/** Lint each stateful channel modifier's TARGET expression with its scope's known names (a symbol's params\n * included) — so a typo'd `spring rotation \"crochetXX\"` surfaces as \"unknown variable\" at `--check` time,\n * not a silent NaN at runtime. Also flags out-of-range spring damping (clamped at runtime, but worth noting). */\nexport function docModifierWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const allVars = allScopeVariables(doc)\n for (const { label, editPath } of scopes(doc)) {\n const ctx = docLintContext(doc, editPath, allVars)\n const visit = (items: Item[]): void => {\n for (const it of items) {\n if (isPoseable(it) && it.modifiers) for (const ch of EXPR_CHANNELS) {\n const m = it.modifiers[ch]\n if (!m) continue\n for (const d of lint(`${ch} = ${m.target}`, ctx)) out.push({ scope: label, diag: { ...d, line: 1, col: 1, message: `${m.kind} ${ch}: ${d.message}` } })\n if (m.kind === 'spring' && !(m.damping > 0 && m.damping < 1)) out.push({ scope: label, diag: { line: 1, col: 1, severity: 'warning', message: `spring ${ch}: damping ${m.damping} should be in (0,1) — clamped at runtime` } })\n }\n if (isGroup(it)) for (const l of it.layers) visit(l.items) // a group shares the scope; instances are linted on their own symbol pass\n }\n }\n visit(contextLayers(doc, editPath).flatMap((l) => l.items))\n // `velocity()` is valid ONLY in a modifier target (resolved by the player's stateful advance). scopeProgram\n // emits the scope's REGULAR expressions but NOT modifier targets, so any velocity() here is a misuse.\n if (/\\bvelocity\\s*\\(/.test(scopeProgram(doc, editPath)))\n out.push({ scope: label, diag: { line: 1, col: 1, message: 'velocity() is only valid inside a spring/smooth target, not a plain expression' } })\n }\n return out\n}\n\nconst sev = (d: Diagnostic) => (d.severity === 'warning' ? 'warning' : 'error')\n\n/** Lint report of a Doc ready to display: `''` = no issue, otherwise `[scope] line:col: level: message`. */\nexport function lintDocReport(doc: Doc): string {\n return lintDoc(doc).map(({ scope, diag }) => `[${scope}] ${diag.line}:${diag.col}: ${sev(diag)}: ${diag.message}`).join('\\n')\n}\n\n/** `true` if the Doc has at least one ERROR (warnings alone do not block). */\nexport function docHasErrors(doc: Doc): boolean {\n return lintDoc(doc).some(({ diag }) => sev(diag) === 'error')\n}\n"],"mappings":"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","names":["parseUnits"]}
|
package/dist/cli/flatc.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
run
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2NAWPQKH.js";
|
|
4
4
|
import {
|
|
5
5
|
allScopeVariables,
|
|
6
6
|
docHasErrors,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
scopeProgram,
|
|
18
18
|
scopeRegions,
|
|
19
19
|
splitScopeProgram
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-AJKZ7C3H.js";
|
|
21
21
|
import {
|
|
22
22
|
compileFlatpack,
|
|
23
23
|
packToJSON
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flatkit/compiler",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.9",
|
|
4
4
|
"description": "The FlatInk language (parser + AST) and compiler (.flatink → .flatpack). Ships the flatc CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Zwyk Studio",
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"bin"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@flatkit/
|
|
49
|
-
"@flatkit/
|
|
50
|
-
"@flatkit/
|
|
48
|
+
"@flatkit/player": "0.19.9",
|
|
49
|
+
"@flatkit/engine": "0.19.9",
|
|
50
|
+
"@flatkit/types": "0.19.9"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"skia-canvas": "^3.0.8"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lint.ts","../src/scopeProgram.ts","../src/programDoc.ts"],"sourcesContent":["// ─────────────────────────────────────────────────────────────────────────────\n// lint.ts — linter for the FlatInk Script language (batch L3).\n//\n// Builds on the parser (dsl.ts) for syntax errors + positions, then adds\n// SEMANTIC validation, ~free and PURE:\n// • each expression is compiled (compileExpr) → expression syntax error;\n// • referenced functions / member objects / identifiers are checked against\n// the standard environment (expr.ts) + the known variables → \"unknown\";\n// • `go to \"label\"` is checked against the set of known labels.\n//\n// Tolerant and kid-friendly: a variable is \"known\" if it is declared\n// (`let`) OR simply assigned (`x = …`) somewhere in the source, or provided\n// by the caller (document global variables). Labels are only checked\n// if the caller provides their list (otherwise we don't know the universe).\n// ─────────────────────────────────────────────────────────────────────────────\nimport { analyzeExpr, STD_CONSTANTS, STD_FUNCTIONS, STD_IDS, STD_OBJECTS } from '@flatkit/engine/expr'\nimport { packageFunctionNames } from '@flatkit/engine/stdlib'\nimport { parseUnits, type Diagnostic, type ScriptUnit } from '@flatkit/engine/dsl'\nimport type { Action } from '@flatkit/engine/actions'\n\nexport type LintContext = {\n /** Known variables in addition to those declared/assigned in the source. */\n variables?: Iterable<string>\n /** Known labels (timeline). Absent = we don't check `go to \"…\"`. */\n labels?: Iterable<string>\n /** Known functions in addition to those defined in the source. */\n functions?: Iterable<string>\n /** Scene objects referenceable by name (`Hero.x`) — in addition to mouse/keys. */\n objects?: Iterable<string>\n}\n\n/** Collects the names of ASSIGNED variables (setVar) + loop vars, inside action bodies. */\nfunction collectAssigned(actions: Action[], into: Set<string>): void {\n for (const a of actions) {\n if (a.do === 'setVar') into.add(a.name)\n else if (a.do === 'if') {\n collectAssigned(a.then, into)\n if (a.else) collectAssigned(a.else, into)\n } else if (a.do === 'repeat') collectAssigned(a.body, into)\n else if (a.do === 'repeatRange') { into.add(a.var); collectAssigned(a.body, into) } // i is known in the body\n }\n}\n\n/** Locally known variables: `let` declarations + every assigned variable. */\nexport function localVariables(units: ScriptUnit[]): Set<string> {\n const vars = new Set<string>()\n for (const u of units) {\n if (u.kind === 'declare') vars.add(u.name)\n else if (u.kind === 'event' || u.kind === 'frameActions') collectAssigned(u.body, vars)\n else if (u.kind === 'each') vars.add(u.as) // the index is known in the each bindings\n else if (u.kind === 'interactor') { if (u.varX) vars.add(u.varX); if (u.varY) vars.add(u.varY) } // drag writes these variables\n else if (u.kind === 'drop') collectAssigned(u.body, vars)\n else if (u.kind === 'func') { for (const p of u.func.params) vars.add(p); if (u.func.kind === 'proc') collectAssigned(u.func.body, vars) } // params + assignments\n }\n return vars\n}\n\n/** Detects a `text(` call (whole word) in an expression → only allowed in a `send` payload. */\nconst TEXT_CALL = /\\btext\\s*\\(/\n\n/** A bare assignment (`x =`, `a[i] =`; NOT ==/<=/>=/!=) left inside an expression: the tell-tale of a\n * SECOND statement crammed onto one line (FlatInk ends a statement at the newline, so it got swallowed). */\nconst SECOND_ASSIGN = /[\\w\\]]\\s*=(?![=])/\n\n/** Analyze a DSL source and return all diagnostics (syntax + semantic). */\nexport function lint(src: string, ctx: LintContext = {}): Diagnostic[] {\n const { units, diagnostics, sites } = parseUnits(src)\n const out: Diagnostic[] = [...diagnostics]\n\n const variables = localVariables(units)\n for (const v of ctx.variables ?? []) variables.add(v)\n const knownIds = new Set<string>([...STD_IDS, ...STD_CONSTANTS, ...variables])\n const knownFns = new Set(STD_FUNCTIONS)\n for (const u of units) {\n if (u.kind === 'func') knownFns.add(u.func.name) // user-defined functions\n else if (u.kind === 'use') for (const name of packageFunctionNames(u.name)) knownFns.add(name) // package functions (bare + qualified)\n }\n for (const f of ctx.functions ?? []) knownFns.add(f)\n const knownObjs = new Set(STD_OBJECTS)\n for (const o of ctx.objects ?? []) knownObjs.add(o) // scene objects (Hero.x…)\n const labels = ctx.labels ? new Set(ctx.labels) : null\n\n for (const s of sites) {\n if (s.kind === 'expr') {\n // `text(…)` is valid ONLY as a `send` payload (consumed by the parser, never\n // exposed as an expression site). Seeing it here = out-of-context use → dedicated error.\n if (TEXT_CALL.test(s.text)) {\n out.push({ line: s.line, col: s.col, message: 'text(\"…\") is only allowed as an argument to \"send\"' })\n continue\n }\n const a = analyzeExpr(s.text)\n if (!a.ok) {\n // #1 footgun: two statements on one line. The 2nd `channel = …` got swallowed into this\n // expression → a cryptic \"unexpected character =\". Detect the leftover assignment and say so.\n const message = SECOND_ASSIGN.test(s.text)\n ? 'two statements on one line — put each on its own line (FlatInk ends a statement at the newline)'\n : `invalid expression: ${a.error}`\n out.push({ line: s.line, col: s.col, message })\n continue\n }\n for (const fn of a.refs.calls) if (!knownFns.has(fn)) out.push({ line: s.line, col: s.col, message: `unknown function \"${fn}\"` })\n for (const o of a.refs.members)\n if (!knownObjs.has(o)) out.push({ line: s.line, col: s.col, message: `unknown object \"${o}\" (expected: ${[...knownObjs].join(', ')})` })\n for (const id of a.refs.ids)\n if (!knownIds.has(id))\n out.push({ line: s.line, col: s.col, message: `unknown variable \"${id}\"${variables.size ? '' : ' — declare it with \"let\"'}` })\n } else if (labels && !labels.has(s.name)) {\n out.push({ line: s.line, col: s.col, message: `unknown label \"${s.name}\"` })\n }\n }\n\n return out.sort((a, b) => a.line - b.line || a.col - b.col)\n}\n\n/**\n * Lint report ready to feed back to a generator (LLM/CLI): `''` = no issue (the code passes),\n * otherwise one `line:col: message` line per diagnostic. Primitive of the \"generate → lint →\n * fix\" loop: the language fits in few tokens, robustness comes from this feedback, not from context.\n */\nexport function lintReport(src: string, ctx: LintContext = {}): string {\n return lint(src, ctx).map((d) => `${d.line}:${d.col}: ${d.message}`).join('\\n')\n}\n","// ─────────────────────────────────────────────────────────────────────────────\n// scopeProgram.ts — the \"unified file\" of a scope (the Scene, or a Symbol).\n//\n// Vision: one file = one scope. All the code of a scope fits in ONE text:\n// var … (global variables, root only)\n// when loaded {} (lifecycle of the scope's timeline)\n// every frame {}\n// object \"name\" {} (one block per scripted object of the scope)\n//\n// This is the `.flatink` structure WITHOUT the geometry (which stays visual). This module\n// ONLY deals with the text: splitting the `object` blocks from the rest, and formatting a block.\n// The wiring to the Doc (a single commit) lives in the store, which reuses these functions\n// + scriptDoc/dsl. Pure, no DOM, testable.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** End of the block opened at `open` (index of the matching `}`), ignoring strings and comments. -1 if unclosed. */\nfunction matchBrace(s: string, open: number): number {\n let depth = 0\n for (let i = open; i < s.length; i++) {\n const c = s[i]\n if (c === '\"') { i++; while (i < s.length && s[i] !== '\"') { if (s[i] === '\\\\') i++; i++ }; continue }\n if (c === '/' && s[i + 1] === '/') { while (i < s.length && s[i] !== '\\n') i++; continue }\n if (c === '{') depth++\n else if (c === '}') { depth--; if (depth === 0) return i }\n }\n return -1\n}\n\n/** Splits a scope file: the `object \"name\" { … }` blocks on one side, the REST (var + lifecycle) on the other. */\nexport function splitScopeProgram(text: string): { rest: string; objects: { name: string; body: string }[] } {\n let rest = ''\n let i = 0\n const objects: { name: string; body: string }[] = []\n while (i < text.length) {\n const m = /object\\s+\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\{/.exec(text.slice(i))\n if (!m) { rest += text.slice(i); break }\n const start = i + m.index\n rest += text.slice(i, start)\n const ob = start + m[0].length - 1 // the opening brace\n const oc = matchBrace(text, ob)\n if (oc < 0) { rest += text.slice(start); break } // unclosed block → left to the rest (diagnostic downstream)\n objects.push({ name: m[1].replace(/\\\\(.)/g, (_, c) => (c === 'n' ? '\\n' : c)), body: text.slice(ob + 1, oc) })\n i = oc + 1\n }\n return { rest, objects }\n}\n\n/** LINTABLE regions of a scope file (the \"rest\" gaps + the `object` bodies), with their\n * 1-based start line in the original text — to lint each piece as pure DSL and\n * reproject the positions. The `object` keyword and its braces are NOT DSL: we skip them. */\nexport function scopeRegions(text: string): { body: string; line: number }[] {\n const lineAt = (off: number) => text.slice(0, off).split('\\n').length\n const regions: { body: string; line: number }[] = []\n let i = 0\n let restStart = 0\n while (i < text.length) {\n const m = /object\\s+\"((?:[^\"\\\\]|\\\\.)*)\"\\s*\\{/.exec(text.slice(i))\n if (!m) break\n const start = i + m.index\n const gap = text.slice(restStart, start)\n if (gap.trim()) regions.push({ body: gap, line: lineAt(restStart) })\n const ob = start + m[0].length - 1\n const oc = matchBrace(text, ob)\n if (oc < 0) break\n regions.push({ body: text.slice(ob + 1, oc), line: lineAt(ob + 1) })\n i = oc + 1\n restStart = i\n }\n const tail = text.slice(restStart)\n if (tail.trim()) regions.push({ body: tail, line: lineAt(restStart) })\n return regions\n}\n\nconst esc = (s: string) => s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')\nconst indent = (body: string) => body.split('\\n').map((l) => (l.trim() ? ' ' + l : l)).join('\\n')\n\n/** Formats an `object \"name\" { … }` block (body already in DSL). */\nexport function formatObjectBlock(name: string, body: string): string {\n const inner = body.trim()\n return `object \"${esc(name)}\" {\\n${inner ? indent(inner) + '\\n' : ''}}`\n}\n\n/** Assembles a scope file: rest (var + lifecycle) then the object blocks, separated by a blank line. */\nexport function joinScopeProgram(rest: string, objects: { name: string; body: string }[]): string {\n const parts: string[] = []\n if (rest.trim()) parts.push(rest.trim())\n for (const o of objects) if (o.body.trim()) parts.push(formatObjectBlock(o.name, o.body))\n return parts.length ? parts.join('\\n\\n') + '\\n' : ''\n}\n","// -----------------------------------------------------------------------------\n// programDoc.ts — PURE bridge Doc <-> \"scope program\" (text) + lint of a whole Doc.\n//\n// Both the editor AND the CLI need to rebuild the DSL text of a scope (to display it,\n// or to lint it) and to assemble the lint context (variables/labels/functions/objects)\n// FROM a Doc — without depending on the React store. Everything lives here, pure and testable:\n// • `scopeProgram` : Doc fragments -> program text of a scope (round-trip via printUnits);\n// • `docLintContext` : Doc + scope -> LintContext (known names);\n// • `lintDoc` / report : semantic lint of ALL the scopes of a Doc (scene + symbols).\n// -> the CLI gains a `flatc --check`, the editor stops duplicating the logic.\n// -----------------------------------------------------------------------------\nimport type { Doc, EditFrame, Group, Instance } from '@flatkit/types'\nimport { printUnits, type Diagnostic } from '@flatkit/engine/dsl'\nimport { joinScopeProgram, scopeRegions } from './scopeProgram'\nimport { functionsToUnits, importsToUnits, objectToUnits, timelineToUnits, variablesToUnits } from '@flatkit/engine/scriptDoc'\nimport { contextLayers, getScopeTimeline, isContainer, isGroup, isText, isImage, isPoseable, isRegion } from '@flatkit/engine/layers'\nimport { importedFunctions } from '@flatkit/engine/stdlib'\nimport { EXPR_CHANNELS } from '@flatkit/engine/timeline'\nimport { objectNames } from '@flatkit/engine/sceneRefs'\nimport { itemBBox, dropZoneBounds } from '@flatkit/engine/groups'\nimport { makePathSampler } from '@flatkit/engine/path'\nimport { bboxIntersects } from '@flatkit/engine/bbox'\nimport { lint, localVariables, type LintContext } from './lint'\nimport { parseUnits } from '@flatkit/engine/dsl'\nimport type { Item, Layer, ParamDef, SymbolDef, Text } from '@flatkit/types'\n\n/** Rebuilds the \"program\" text of a scope (imports + variables + functions + scene cycle\n * + one `object \"Name\" { … }` block per scripted container with a unique name). Pure, round-trip via printUnits. */\nexport function scopeProgram(doc: Doc, editPath: EditFrame[] = []): string {\n const atRoot = editPath.length === 0\n const items = contextLayers(doc, editPath).flatMap((l) => l.items)\n const nameCount = new Map<string, number>()\n for (const it of items) if (isContainer(it) && it.name) nameCount.set(it.name, (nameCount.get(it.name) ?? 0) + 1)\n const scripted = (it: Group | Instance) => !!doc.interactions?.some((i) => i.targetId === it.id) || !!doc.interactors?.some((i) => i.targetId === it.id) || !!(it.expressions && Object.keys(it.expressions).length)\n const objects = items\n .filter((it): it is Group | Instance => isContainer(it) && !!it.name && nameCount.get(it.name) === 1 && scripted(it))\n .map((it) => ({ name: it.name, body: printUnits(objectToUnits(it.id, doc.interactions, it.expressions, doc.interactors)) }))\n const imports = atRoot ? printUnits(importsToUnits(doc.imports)) : ''\n const funcs = atRoot ? printUnits(functionsToUnits(doc.functions)) : ''\n const globals = atRoot ? printUnits(variablesToUnits(doc.variables)) : ''\n const scene = printUnits(timelineToUnits(getScopeTimeline(doc, editPath)))\n const head = [imports, globals, funcs, scene].filter((t) => t.trim()).join('\\n\\n')\n return joinScopeProgram(head, objects)\n}\n\n/** Lint context of a scope: known names (variables, labels, functions, objects) drawn from the Doc.\n * `extraVars` = variables assigned in the OTHER scopes (FlatInk variables are GLOBAL -> known\n * everywhere; avoids a false \"unknown variable\" on a var written elsewhere, e.g. generated by `match`). */\nexport function docLintContext(doc: Doc, editPath: EditFrame[] = [], extraVars?: Iterable<string>): LintContext {\n return {\n // A symbol's own `params` (and state params) are injected into its instance scope at runtime, so they are\n // valid variables in ITS `expr` -- add them, but ONLY to that symbol's scope (resolved from `editPath`),\n // never globally, so a param named in symbol A can't mask a real typo of the same name in symbol B.\n variables: [...Object.keys(doc.variables ?? {}), ...(extraVars ?? []), ...scopeSymbolParams(doc, editPath)],\n labels: (getScopeTimeline(doc, editPath)?.labels ?? []).map((l) => l.name),\n functions: [...(doc.functions ?? []).map((f) => f.name), ...importedFunctions(doc.imports).map((f) => f.name)],\n objects: objectNames(contextLayers(doc, editPath)),\n }\n}\n\n/** Names exposed as variables by the symbol of `editPath` (its `params` + state params), or `[]` for the\n * scene scope / an unresolved path. Mirrors the per-instance scope the runtime and `--preview` build. */\nfunction scopeSymbolParams(doc: Doc, editPath: EditFrame[]): string[] {\n const frame = [...editPath].reverse().find((f): f is Extract<EditFrame, { kind: 'symbol' }> => f.kind === 'symbol')\n const sym = frame ? doc.symbols.find((s) => s.id === frame.symbolId) : undefined\n if (!sym) return []\n return [...(sym.params ?? []).map((p) => p.name), ...(sym.states ?? []).map((s) => s.param)]\n}\n\n/** All the scopes of a Doc: the scene (root) + each symbol of the library. */\nfunction scopes(doc: Doc): { label: string; editPath: EditFrame[] }[] {\n return [{ label: 'scene', editPath: [] }, ...doc.symbols.map((s) => ({ label: s.name, editPath: [{ kind: 'symbol' as const, symbolId: s.id, name: s.name }] }))]\n}\n\n/** Union of the variables ASSIGNED in ALL the scopes (scene + symbols). FlatInk variables are\n * global -> a var written in one scope is legitimate in the others (cross-scope reads). */\nexport function allScopeVariables(doc: Doc): string[] {\n const set = new Set<string>()\n for (const { editPath } of scopes(doc))\n for (const r of scopeRegions(scopeProgram(doc, editPath)))\n for (const v of localVariables(parseUnits(r.body).units)) set.add(v)\n return [...set]\n}\n\n/** Readable name of an item by id (for the messages). */\nfunction itemNameById(doc: Doc, id: string): string | null {\n let found: string | null = null\n const walk = (layers: { items: import('@flatkit/types').Item[] }[]) => {\n for (const l of layers) for (const it of l.items) {\n if (found) return\n if ('name' in it && it.id === id) { found = it.name ?? null; return }\n if (isGroup(it)) walk(it.layers)\n }\n }\n walk(doc.layers)\n return found\n}\n\nconst escapeRe = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&')\n\n/** STRUCTURAL warnings (non-blocking) of a Doc: phantom drop zones, dead variables. */\nexport function docStructureWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n // (a) `when dropped on X` whose zone X does not exist (no item named so) -> the handler can never fire.\n const names = new Set(objectNames(doc.layers))\n for (const it of doc.interactions ?? []) {\n if (it.event === 'drop' && it.over && !names.has(it.over)) {\n const who = itemNameById(doc, it.targetId) ?? it.targetId\n out.push({ scope: 'scene', diag: { line: 1, col: 1, severity: 'warning', message: `unknown drop zone \"${it.over}\" (object \"${who}\") — no item of the scene carries this name` } })\n }\n }\n // (b) global variable never referenced (declared but not found in any scope) -> probably dead.\n const names0 = Object.keys(doc.variables ?? {})\n if (names0.length) {\n // Modifier targets are NOT emitted into scopeProgram (to avoid double-linting them, cf. docModifierWarnings),\n // so collect them here too — else a global used ONLY by a `spring`/`smooth` target reads as \"never used\".\n const modTargets: string[] = []\n const collectMods = (items: Item[]): void => {\n for (const it of items) {\n if (isPoseable(it) && it.modifiers) for (const ch of EXPR_CHANNELS) { const mm = it.modifiers[ch]; if (mm) modTargets.push(mm.target) }\n if (isGroup(it)) for (const l of it.layers) collectMods(l.items)\n }\n }\n for (const l of doc.layers) collectMods(l.items)\n for (const s of doc.symbols ?? []) for (const l of s.layers) collectMods(l.items)\n const allText = [...scopes(doc).map(({ editPath }) => scopeProgram(doc, editPath)), ...modTargets].join('\\n')\n for (const name of names0) {\n const m = allText.match(new RegExp(`(?<![\\\\w-])${escapeRe(name)}(?![\\\\w-])`, 'g'))\n if ((m?.length ?? 0) <= 1) out.push({ scope: 'scene', diag: { line: 1, col: 1, severity: 'warning', message: `global variable \"${name}\" never used (declared, but neither read nor written)` } })\n }\n }\n // (c) raw `time` in a channel expression + a SHORT looping timeline → ambient motion JUMPS on each loop\n // (`time = frame/fps` resets to 0 every `durationFrames`). The monotone `clock` never wraps.\n const dur = doc.timeline?.durationFrames ?? 60\n const fps = doc.timeline?.fps ?? 24\n if (dur <= 120) { // ≤ 5 s @24fps: short enough that the reset is visible as a periodic jump\n let usesTime = false\n const scan = (layers: Layer[]) => {\n for (const l of layers) for (const it of l.items) {\n if (isPoseable(it) && it.expressions) for (const k in it.expressions) if (/\\btime\\b/.test(it.expressions[k as keyof typeof it.expressions] ?? '')) usesTime = true\n if (isGroup(it)) scan(it.layers)\n }\n }\n scan(doc.layers)\n if (usesTime) {\n const secs = Math.round((dur / fps) * 10) / 10\n out.push(warn(`a channel expression uses \\`time\\`, but the timeline loops every ${secs}s (durationFrames ${dur}) — \\`time\\` resets each loop, so the motion jumps. Use the monotone \\`clock\\` (never wraps), drive it by \\`frame/${dur}\\`, or set a longer \\`timeline\\`.`))\n }\n }\n out.push(...docPaintParamWarnings(doc))\n out.push(...docLayoutWarnings(doc))\n return out\n}\n\n/** A scope's declared `color` param names (the only params usable as a paint color). */\nconst colorParamNames = (params?: ParamDef[]): Set<string> => new Set((params ?? []).filter((p) => p.type === 'color').map((p) => p.name))\n\n/**\n * A `color` param used as a paint (`fill`/`stroke`, a gradient **stop** `0:teinte@…`, or a `tint`) that the\n * owning symbol does NOT declare → a SILENT \"dead recolor\" (it falls back to the literal hex, the picker does\n * nothing). Warns per scope, with the param scoped to ITS symbol (the scene declares none). Mirrors how the\n * lint now knows a symbol's params in its `expr`. Non-blocking (a warning), so it never breaks a build.\n */\nexport function docPaintParamWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const checkScope = (scope: string, layers: Layer[], known: Set<string>) => {\n const flag = (param: string, where: string, who?: string) => {\n if (known.has(param)) return\n const hint = known.size ? `declared color params: ${[...known].join(', ')}` : 'this scope declares no color params'\n out.push({ scope, diag: { line: 1, col: 1, severity: 'warning', message: `unknown color param \"${param}\" in ${where}${who ? ` (${who})` : ''} — ${hint}` } })\n }\n const visit = (it: Item) => {\n const who = 'name' in it ? it.name : undefined\n if (isRegion(it)) {\n if (it.fillParam) flag(it.fillParam, 'a fill', who)\n if (it.strokeParam) flag(it.strokeParam, 'a stroke', who)\n const stops = it.paint && it.paint.type !== 'solid' ? it.paint.stops : []\n for (const s of stops) if (s.param) flag(s.param, 'a gradient stop', who)\n }\n if (isPoseable(it) && it.tint?.param) flag(it.tint.param, 'a tint', who)\n if (isGroup(it)) for (const l of it.layers) for (const c of l.items) visit(c) // a group is the same scope; an instance is a separate symbol (linted on its own pass)\n }\n for (const l of layers) for (const it of l.items) visit(it)\n }\n checkScope('scene', doc.layers, new Set())\n for (const s of doc.symbols) checkScope(s.name, s.layers, colorParamNames((s as SymbolDef).params))\n return out\n}\n\nconst warn = (message: string): { scope: string; diag: Diagnostic } => ({ scope: 'scene', diag: { line: 1, col: 1, severity: 'warning', message } })\nconst itemLabel = (it: Item): string => ('name' in it && it.name ? it.name : 'kind' in it ? it.kind : 'path')\n/** Estimated width of the longest line (approximate metric, without canvas). */\nfunction estTextWidth(t: Text): number {\n const advance = (t.weight && t.weight >= 700 ? 0.56 : 0.52) * t.size // mean advance of a proportional glyph\n let longest = 0\n for (const line of t.content.split('\\n')) longest = Math.max(longest, line.length)\n return longest * advance\n}\n\n/** LAYOUT warnings (non-blocking): canvas overflow, text too wide, overlapping hitboxes.\n * Approximate but without canvas — catches \"blind\" positioning bugs before the render. */\nexport function docLayoutWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const W = doc.width, H = doc.height\n const TOL = 8 // overflow tolerance (px) before alerting\n const r0 = (n: number) => Math.round(n)\n\n // (c) TEXT/IMAGE clipped at the canvas edge. Precise to avoid noise: we ignore `path`/groups\n // (decor that \"bleeds\" on purpose), objects driven by an expression (dynamic position ->\n // misleading static bbox), and items PARKED entirely off-screen (\"hidden\" pattern).\n const dynamicPos = (it: Item) => 'expressions' in it && it.expressions && (it.expressions.x != null || it.expressions.y != null)\n for (const layer of doc.layers) {\n for (const it of layer.items) {\n if (!(isText(it) || isImage(it)) || dynamicPos(it) || (isText(it) && it.textPath)) continue // path-laid text → §(f), not a box\n const b = itemBBox(doc, it)\n if (!b) continue\n const visible = b.maxX > 0 && b.minX < W && b.maxY > 0 && b.minY < H // overlaps the canvas (not parked off-screen)\n const clipped = b.minX < -TOL || b.minY < -TOL || b.maxX > W + TOL || b.maxY > H + TOL\n if (visible && clipped) {\n out.push(warn(`\"${itemLabel(it)}\" clipped at the canvas edge: bbox [${r0(b.minX)},${r0(b.minY)} -> ${r0(b.maxX)},${r0(b.maxY)}] outside 0,0 -> ${W},${H}`))\n }\n }\n }\n\n // (d) Text (without `wrap`) whose estimated width makes it OVERFLOW THE CANVAS -> instruction clipped.\n // (We do NOT compare against `box.w`: without wrap, a text overflows its box harmlessly as long as it\n // fits in the canvas — it is the canvas edge that clips.) Top-level only (x = world).\n for (const it of doc.layers.flatMap((l) => l.items)) {\n if (!isText(it) || it.wrap || it.textPath || dynamicPos(it)) continue\n const estW = estTextWidth(it)\n const left = it.align === 'left' ? 0 : it.align === 'right' ? it.box.w - estW : it.box.w / 2 - estW / 2\n const wl = it.transform.e + left, wr = wl + estW // left/right edge of the content in world coords\n if (wr > W + TOL || wl < -TOL) {\n out.push(warn(`text \"${it.content.slice(0, 24)}${it.content.length > 24 ? '…' : ''}\" overflows the canvas (estimated ~${r0(estW)} px, edge ${r0(wl)}->${r0(wr)} outside 0->${W}) — add \"wrap\"`))\n }\n }\n\n // (f) Text laid ALONG a path whose estimated run is longer than the path -> trailing glyphs dropped at\n // render (mirrors the canvas-overflow warning, but for the curve). Position-independent -> recurse.\n const pathTexts: Text[] = []\n const walkPathTexts = (layers: Layer[]) => { for (const l of layers) for (const it of l.items) { if (isText(it) && it.textPath) pathTexts.push(it); else if (isGroup(it)) walkPathTexts(it.layers) } }\n walkPathTexts(doc.layers)\n for (const it of pathTexts) {\n const L = makePathSampler(it.textPath!.path).length\n if (L <= 0) continue\n const advance = (it.weight && it.weight >= 700 ? 0.56 : 0.52) * it.size // same metric as estTextWidth\n const glyphs = [...it.content].length\n const eff = Math.max(advance + (it.textPath!.spacing ?? 0), 1) // mirror the renderer's per-glyph floor\n const estW = glyphs * eff\n if (estW > L + TOL) out.push(warn(`text \"${it.content.slice(0, 24)}${it.content.length > 24 ? '…' : ''}\" overflows its path (~${r0(estW)}px > ${r0(L)}px) — trailing glyphs are dropped`))\n }\n\n // (e) Drop zones (`hitbox`) that overlap -> ambiguous drop.\n const zones: { name: string; b: NonNullable<ReturnType<typeof dropZoneBounds>> }[] = []\n const collectZones = (layers: Layer[]) => {\n for (const l of layers) for (const it of l.items) {\n if (isGroup(it) && it.hitbox && it.name) { const b = dropZoneBounds(doc, it.name); if (b) zones.push({ name: it.name, b }) }\n if (isGroup(it)) collectZones(it.layers)\n }\n }\n collectZones(doc.layers)\n for (let i = 0; i < zones.length; i++) for (let j = i + 1; j < zones.length; j++) {\n if (bboxIntersects(zones[i].b, zones[j].b)) out.push(warn(`overlapping hitboxes: \"${zones[i].name}\" and \"${zones[j].name}\" -> ambiguous drop`))\n }\n return out\n}\n\n/** Semantic lint of a whole Doc (all the scopes) -> diagnostics labeled by scope.\n * The scope program contains `object` blocks (outside DSL) -> we lint each region\n * separately and re-project the lines (like the editor, cf. CodeEditor.lintFile).\n * Adds the structural warnings (phantom drop zones, dead variables). */\nexport function lintDoc(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const allVars = allScopeVariables(doc) // computed ONCE (global vars -> known in all the scopes)\n for (const { label, editPath } of scopes(doc)) {\n const ctx = docLintContext(doc, editPath, allVars)\n for (const r of scopeRegions(scopeProgram(doc, editPath))) for (const d of lint(r.body, ctx)) out.push({ scope: label, diag: { ...d, line: d.line + r.line - 1 } })\n }\n out.push(...docStructureWarnings(doc))\n out.push(...docModifierWarnings(doc))\n return out\n}\n\n/** Lint each stateful channel modifier's TARGET expression with its scope's known names (a symbol's params\n * included) — so a typo'd `spring rotation \"crochetXX\"` surfaces as \"unknown variable\" at `--check` time,\n * not a silent NaN at runtime. Also flags out-of-range spring damping (clamped at runtime, but worth noting). */\nexport function docModifierWarnings(doc: Doc): { scope: string; diag: Diagnostic }[] {\n const out: { scope: string; diag: Diagnostic }[] = []\n const allVars = allScopeVariables(doc)\n for (const { label, editPath } of scopes(doc)) {\n const ctx = docLintContext(doc, editPath, allVars)\n const visit = (items: Item[]): void => {\n for (const it of items) {\n if (isPoseable(it) && it.modifiers) for (const ch of EXPR_CHANNELS) {\n const m = it.modifiers[ch]\n if (!m) continue\n for (const d of lint(`${ch} = ${m.target}`, ctx)) out.push({ scope: label, diag: { ...d, line: 1, col: 1, message: `${m.kind} ${ch}: ${d.message}` } })\n if (m.kind === 'spring' && !(m.damping > 0 && m.damping < 1)) out.push({ scope: label, diag: { line: 1, col: 1, severity: 'warning', message: `spring ${ch}: damping ${m.damping} should be in (0,1) — clamped at runtime` } })\n }\n if (isGroup(it)) for (const l of it.layers) visit(l.items) // a group shares the scope; instances are linted on their own symbol pass\n }\n }\n visit(contextLayers(doc, editPath).flatMap((l) => l.items))\n }\n return out\n}\n\nconst sev = (d: Diagnostic) => (d.severity === 'warning' ? 'warning' : 'error')\n\n/** Lint report of a Doc ready to display: `''` = no issue, otherwise `[scope] line:col: level: message`. */\nexport function lintDocReport(doc: Doc): string {\n return lintDoc(doc).map(({ scope, diag }) => `[${scope}] ${diag.line}:${diag.col}: ${sev(diag)}: ${diag.message}`).join('\\n')\n}\n\n/** `true` if the Doc has at least one ERROR (warnings alone do not block). */\nexport function docHasErrors(doc: Doc): boolean {\n return lintDoc(doc).some(({ diag }) => sev(diag) === 'error')\n}\n"],"mappings":"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","names":["parseUnits"]}
|
|
File without changes
|