@velarscript/web 0.29.0 → 0.29.1

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.
Files changed (49) hide show
  1. package/dist/analysis/component-guidance.d.ts +52 -0
  2. package/dist/analysis/component-guidance.d.ts.map +1 -0
  3. package/dist/analysis/component-guidance.js +103 -0
  4. package/dist/analysis/component-guidance.js.map +1 -0
  5. package/dist/analysis/look-values.d.ts +30 -0
  6. package/dist/analysis/look-values.d.ts.map +1 -0
  7. package/dist/analysis/look-values.js +61 -0
  8. package/dist/analysis/look-values.js.map +1 -0
  9. package/dist/analysis/public-config.d.ts +44 -0
  10. package/dist/analysis/public-config.d.ts.map +1 -0
  11. package/dist/analysis/public-config.js +133 -0
  12. package/dist/analysis/public-config.js.map +1 -0
  13. package/dist/analysis/watch-cycles.d.ts +33 -0
  14. package/dist/analysis/watch-cycles.d.ts.map +1 -1
  15. package/dist/analysis/watch-cycles.js +59 -0
  16. package/dist/analysis/watch-cycles.js.map +1 -1
  17. package/dist/analyzer.d.ts +18 -18
  18. package/dist/analyzer.d.ts.map +1 -1
  19. package/dist/analyzer.js +65 -71
  20. package/dist/analyzer.js.map +1 -1
  21. package/dist/browser-host-runtime.d.ts +23 -0
  22. package/dist/browser-host-runtime.d.ts.map +1 -0
  23. package/dist/browser-host-runtime.js +29 -0
  24. package/dist/browser-host-runtime.js.map +1 -0
  25. package/dist/compiler.d.ts +1 -1
  26. package/dist/compiler.js +6 -6
  27. package/dist/compiler.js.map +1 -1
  28. package/dist/lexer.js +89 -16
  29. package/dist/lexer.js.map +1 -1
  30. package/dist/look.d.ts +1 -1
  31. package/dist/look.d.ts.map +1 -1
  32. package/dist/look.js +5 -3
  33. package/dist/look.js.map +1 -1
  34. package/dist/parser.d.ts +2 -0
  35. package/dist/parser.d.ts.map +1 -1
  36. package/dist/parser.js +23 -25
  37. package/dist/parser.js.map +1 -1
  38. package/dist/runtime.d.ts.map +1 -1
  39. package/dist/runtime.js +12 -11
  40. package/dist/runtime.js.map +1 -1
  41. package/dist/types.d.ts +9 -0
  42. package/dist/types.d.ts.map +1 -1
  43. package/dist/types.js +12 -0
  44. package/dist/types.js.map +1 -1
  45. package/dist/visual-blocks.d.ts +28 -0
  46. package/dist/visual-blocks.d.ts.map +1 -0
  47. package/dist/visual-blocks.js +23 -0
  48. package/dist/visual-blocks.js.map +1 -0
  49. package/package.json +3 -3
@@ -71,6 +71,11 @@ export declare class VelarWebAnalyzer extends Analyzer {
71
71
  private readonly webSourceText;
72
72
  /** D74: only props whose authors wrote a readonly contract receive prop-specific guidance. */
73
73
  private explicitReadonlyPropBindings;
74
+ /** D114 0.29.0 LC-D1: the manifest's `web.publicConfig`, or null when this compile read no project manifest — an empty section is a claim the compile may check, and no manifest is no claim at all. */
75
+ private readonly webPublicConfig;
76
+ private publicConfigNames;
77
+ /** velar/look builder calls this compile refused on their own arguments (D114 0.29.0 LK-I2). */
78
+ private readonly refusedBuilderCalls;
74
79
  constructor(context?: AnalysisContext, extensions?: readonly CompilerAnalysisExtension[]);
75
80
  analyze(program: Program): readonly Diagnostic[];
76
81
  /**
@@ -156,6 +161,8 @@ export declare class VelarWebAnalyzer extends Analyzer {
156
161
  protected markDeclaredBindingReactive(name: string, kind?: "state" | "prop"): void;
157
162
  protected inferExtensionExpression(expression: Expression, _contextualType: ValueType): ValueType | undefined;
158
163
  protected inferExpression(expression: Expression, contextualType?: ValueType): ValueType;
164
+ /** Infers one builder slot and parks the answer in the probe cache, so the call's own analysis reads it back. */
165
+ private probedSlotType;
159
166
  private writableStateName;
160
167
  /**
161
168
  * P2b-5: a `def` that answers markup and answers it with a component element.
@@ -256,24 +263,6 @@ export declare class VelarWebAnalyzer extends Analyzer {
256
263
  * fixed, exactly as two errors on one line are.
257
264
  */
258
265
  private rejectWatchCycle;
259
- /**
260
- * D114 0.28.0 H-D1: the VEL5077 message one plain body statement earns, or
261
- * null when it earns none.
262
- *
263
- * §15 says a watch fires on a *deep* change of its subject, so `watch form:
264
- * form.name = …` and `watch items: items[0].done = …` are the same ring
265
- * `items.append(…)` already is — decided at the top of the body, with no
266
- * condition to end it — and were silent until the runtime's 100-round cap
267
- * stopped them. The rule is therefore stated on the path rather than on the
268
- * spelling: a write whose place is the subject, or any place below it, in an
269
- * assignment, a compound assignment, or a mutating call.
270
- *
271
- * Every existing exclusion stands, because each is answered somewhere else: a
272
- * conditional or nested write is not a plain body statement, a rebinding
273
- * stops the scan in `rejectWatchCycle`, and a sibling path (`watch form.name:`
274
- * writing `form.email`) or a different root fails the step comparison here.
275
- */
276
- private watchSelfWrite;
277
266
  /**
278
267
  * D114 0.28.0 H-D1: the type of the place `steps` below the watched subject,
279
268
  * or null when the walk cannot reach one.
@@ -384,6 +373,15 @@ export declare class VelarWebAnalyzer extends Analyzer {
384
373
  * says so instead of releasing at the wrong moment.
385
374
  */
386
375
  protected ownershipScopeRejection(): string | null;
376
+ /**
377
+ * D114 0.29.0 JX-I2: a component body has no function frame, so a `return` nested
378
+ * inside it — in a `match` arm, an `if`, a `for` — used to earn VEL3003 next to
379
+ * VEL5008 ("exactly one top-level return"), two rules its author can only read as
380
+ * contradicting each other. A lifecycle hook and a watch body are inside the same
381
+ * component and are *not* it: neither returns anything, so a `return` there keeps
382
+ * VEL3003.
383
+ */
384
+ protected extensionOwnsFunctionlessReturn(): boolean;
387
385
  protected invalidExtensionAwaitContext(): boolean;
388
386
  protected invalidExtensionAwaitMessage(): string | null;
389
387
  private componentType;
@@ -449,6 +447,8 @@ export declare class VelarWebAnalyzer extends Analyzer {
449
447
  private checkAnimateBuilderCall;
450
448
  private checkAnimationKeyword;
451
449
  private analyzeKeyframes;
450
+ /** Whether a builder call this compile refused on its own arguments lies inside `sourceSpan`. */
451
+ private refusedBuilderCallWithin;
452
452
  private reportKeyframeSnapshotReads;
453
453
  /**
454
454
  * D104 rule 2 — the wider half of the promise VEL5039 already made. A
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
package/dist/analyzer.js CHANGED
@@ -5,12 +5,15 @@ import { cssTokens } from "./css-tokens.js";
5
5
  import { LOOK_ABSENT_MEDIA_SUBJECTS, LOOK_ARITHMETIC_HINT, LOOK_ANIMATION_DIRECTIONS, LOOK_ANIMATION_EASINGS, LOOK_ANIMATION_FILLS, LOOK_BORDER_STYLE_NAMES, LOOK_BUILDER_NUMERIC_RANGES, LOOK_BUILDER_SIGNATURES, LOOK_BUILDERS, LOOK_EXCLUDED_PROPERTIES, LOOK_HOOKS, LOOK_CSS_WIDE_KEYWORDS, LOOK_COLOR_KEYWORDS, LOOK_LARGE_KEYWORD_SETS, LOOK_LENGTH_BUILDERS, LOOK_MEDIA_LENGTH_UNITS, LOOK_MEDIA_SUBJECTS, LOOK_NUMERIC_TYPE_NAMES, LOOK_NON_ANIMATABLE_PROPERTIES, LOOK_PARTIAL_KEYWORD_PROPERTIES, LOOK_PROPERTIES, LOOK_PROPERTY_KEYWORDS, LOOK_PROPERTY_VALUE_KINDS, LOOK_SHARED_METRIC_KEYWORDS, LOOK_TARGETS, LOOK_TOKEN_NAME_RULE, LOOK_TOKEN_NO_FALLBACK_GUIDANCE, LOOK_UNIT_TYPES, LOOK_UNITLESS_PROPERTIES, isLookTokenName, isLookVarReference, lookOwnKeywords, lookShorthandOverlap, lookShorthandParts, lookTokenReference, lookVarReferenceName, nearestLookName, } from "./look.js";
6
6
  import { collectLookStaticValues, evaluateLookStaticExpression, isLookStaticValue, lookStaticCss } from "./look-static.js";
7
7
  import { keyframeCssValue } from "./keyframes.js";
8
+ import { componentCallRefusal, componentRefHandleRefusal, componentSectionCountDiagnostics, watchedResourceSurfaceRefusal } from "./analysis/component-guidance.js";
9
+ import { foldedLengthPercentage, isLookNumericType, lookAdditiveType } from "./analysis/look-values.js";
10
+ import { collectPublicConfigNames, declaredPublicConfig, publicConfigDiagnostic } from "./analysis/public-config.js";
8
11
  import { byCodeUnit } from "./stable-order.js";
9
12
  import { dynamicChildLeaves, JSX_SCALAR_TEXT_HINT } from "./emitter.js";
10
13
  import { isWebCustomElementName, WEB_ARIA_ATTRIBUTES, WEB_ARIA_ENUMERATED_VALUES, WEB_ARIA_ROLES, WEB_ARIA_ROLE_SYNONYMS, WEB_BOOL_PRESENCE_HTML_ATTRIBUTES, WEB_HTML_ELEMENTS, WEB_MISSPELLED_ATTRIBUTES, WEB_NATIVE_ELEMENTS, } from "./elements.js";
11
14
  import { isWebExpression, isWebJsx, isWebKeyframes, isWebLook, isWebStatement, isWebUnit, } from "./ast.js";
12
15
  import { isWebComponentConstructor, isWebComponentType, isWebComputedExport, isWebNodeType, normalizeWebComponentType, webComponentConstructor, webComponentHandle, webComponentIntrinsic, webComponentName, webNodeType, WEB_EVENT_TYPE_NAMES, WEB_OWNED_TYPE_NAMES, } from "./types.js";
13
- import { collectionMutators, collectReactiveWriters, reactivePathOf, reactivePathRoot, reactiveStepsBelow, reactiveWriteCandidate, statementBindsName, topLevelCall, writerWritesPath, } from "./analysis/watch-cycles.js";
16
+ import { collectionMutators, collectReactiveWriters, finallySelfWrite, reactivePathOf, reactivePathRoot, statementBindsName, topLevelCall, watchSelfWrite, writerWritesPath, } from "./analysis/watch-cycles.js";
14
17
  // The canonical nominal identity of the Web RouteContext record. Route checks
15
18
  // probe with this identity so they succeed in modules that use route() without
16
19
  // importing RouteContext by name.
@@ -1001,9 +1004,6 @@ function firstRelativeCssAssetAddress(source) {
1001
1004
  }
1002
1005
  return null;
1003
1006
  }
1004
- function isLookNumericType(type) {
1005
- return type.kind === "named" && LOOK_NUMERIC_TYPE_NAMES.has(type.name);
1006
- }
1007
1007
  /** True when a property's declared domain includes a spelled visual unit type. */
1008
1008
  function mentionsLookUnitType(type) {
1009
1009
  if (type.kind === "named")
@@ -1021,17 +1021,7 @@ function lookLiteralZero(expression) {
1021
1021
  return lookLiteralZero(expression.operand);
1022
1022
  return isWebUnit(expression) && expression.value === 0;
1023
1023
  }
1024
- function lookAdditiveType(left, right) {
1025
- if (!isLookNumericType(left) || !isLookNumericType(right))
1026
- return null;
1027
- if (semanticTypeIdentity(left) === semanticTypeIdentity(right))
1028
- return left;
1029
- const lengthPercentageNames = new Set(["Length", "Percentage", "LengthPercentage"]);
1030
- if (left.kind === "named" && right.kind === "named"
1031
- && lengthPercentageNames.has(left.name) && lengthPercentageNames.has(right.name))
1032
- return lookLengthPercentage;
1033
- return null;
1034
- }
1024
+ const lookJoin = (left, right) => lookAdditiveType(left, right, semanticTypeIdentity(left) === semanticTypeIdentity(right));
1035
1025
  function containsCssImport(source) {
1036
1026
  for (const token of cssTokens(source)) {
1037
1027
  if (token.kind === "at-keyword" && token.name.toLowerCase() === "import")
@@ -1809,11 +1799,17 @@ export class VelarWebAnalyzer extends Analyzer {
1809
1799
  webSourceText;
1810
1800
  /** D74: only props whose authors wrote a readonly contract receive prop-specific guidance. */
1811
1801
  explicitReadonlyPropBindings = new Map();
1802
+ /** D114 0.29.0 LC-D1: the manifest's `web.publicConfig`, or null when this compile read no project manifest — an empty section is a claim the compile may check, and no manifest is no claim at all. */
1803
+ webPublicConfig;
1804
+ publicConfigNames = new Set();
1805
+ /** velar/look builder calls this compile refused on their own arguments (D114 0.29.0 LK-I2). */
1806
+ refusedBuilderCalls = [];
1812
1807
  constructor(context = {}, extensions = []) {
1813
1808
  super(context, extensions);
1814
1809
  this.webModulePath = context.path ?? null;
1815
1810
  this.webSourceText = context.sourceText ?? "";
1816
1811
  this.resources = context.resources ?? new Map();
1812
+ this.webPublicConfig = declaredPublicConfig(context.extensionProjectConfig?.get("@velarscript/web"));
1817
1813
  const webImports = [...(context.extensionImports?.get("@velarscript/web") ?? [])];
1818
1814
  this.importedLookStaticValues = new Map(webImports.filter((entry) => isLookStaticValue(entry[1])));
1819
1815
  this.importedComputedNames = new Set(webImports.filter(([, value]) => isWebComputedExport(value)).map(([name]) => name));
@@ -1821,6 +1817,7 @@ export class VelarWebAnalyzer extends Analyzer {
1821
1817
  analyze(program) {
1822
1818
  this.lookStaticValues = collectLookStaticValues(program, this.importedLookStaticValues);
1823
1819
  this.lookBuilderNames = collectLookBuilderNames(program);
1820
+ this.publicConfigNames = collectPublicConfigNames(program);
1824
1821
  this.lookImport = collectLookImportSite(program);
1825
1822
  this.lookDeclarations = collectLookDeclarations(program);
1826
1823
  for (const name of collectDerivedReactiveNames(program))
@@ -2226,7 +2223,7 @@ export class VelarWebAnalyzer extends Analyzer {
2226
2223
  this.probedOperandTypes.set(spanIdentity(expression.right.span), right);
2227
2224
  }
2228
2225
  else {
2229
- const additive = expression.operator === "+" || expression.operator === "-" ? lookAdditiveType(left, right) : null;
2226
+ const additive = expression.operator === "+" || expression.operator === "-" ? lookJoin(left, right) : null;
2230
2227
  const result = additive
2231
2228
  ?? ((expression.operator === "*" || expression.operator === "/") && isLookNumericType(left) && right.kind === "number" ? left : null)
2232
2229
  ?? (expression.operator === "*" && left.kind === "number" && isLookNumericType(right) ? right : null);
@@ -2313,11 +2310,23 @@ export class VelarWebAnalyzer extends Analyzer {
2313
2310
  if (retired)
2314
2311
  return RETIRED_ACCESSOR_TYPE;
2315
2312
  }
2313
+ const folded = expression.kind !== "CallExpression" ? null
2314
+ : foldedLengthPercentage(expression, (name) => this.lookBuilderNames.get(name), (argument) => this.probedSlotType(argument), lookJoin);
2316
2315
  const result = super.inferExpression(expression, contextualType);
2317
2316
  if (expression.kind === "CallExpression") {
2318
2317
  this.checkLookBuilderCall(expression);
2318
+ // D114 0.29.0 LC-D1: the manifest this build bakes in, proved against the declared type.
2319
+ const report = publicConfigDiagnostic(expression, result, this.publicConfigNames, this.webPublicConfig, { expandAliases: (type) => this.expandAliases(type), fieldsOf: (identity) => this.fieldsOf(identity), describeType });
2320
+ if (report)
2321
+ this.diagnostics.push(report);
2319
2322
  }
2320
- return result;
2323
+ return folded ?? result;
2324
+ }
2325
+ /** Infers one builder slot and parks the answer in the probe cache, so the call's own analysis reads it back. */
2326
+ probedSlotType(argument) {
2327
+ const inferred = this.inferExpression(argument);
2328
+ this.probedOperandTypes.set(spanIdentity(argument.span), inferred);
2329
+ return this.expandAliases(inferred);
2321
2330
  }
2322
2331
  // A name refers to writable reactive state only when ordinary lexical lookup
2323
2332
  // still resolves it to the state binding; a shadowing local wins instead.
@@ -2452,6 +2461,11 @@ export class VelarWebAnalyzer extends Analyzer {
2452
2461
  this.diagnostics.push(diagnostic("VEL5064", `'${name}' is the reader itself, so watching it watches a value that never changes; declare the derived value — 'computed name = ${name}()' — then 'watch name:'`, expression.span));
2453
2462
  return false;
2454
2463
  }
2464
+ // ST-D1: the resource surface is answered ahead of the frozen rule, because it is a reactive value whose *own* handle never moves.
2465
+ if (name !== null && this.isResourceBinding(name)) {
2466
+ this.diagnostics.push(diagnostic("VEL5064", watchedResourceSurfaceRefusal(name), expression.span));
2467
+ return false;
2468
+ }
2455
2469
  if (this.frozenWatchSubject(expression)) {
2456
2470
  this.diagnostics.push(diagnostic("VEL5064", `This watch subject never changes, so its body can never run${name === null ? "" : ` — '${name}' is not a reactive source`}; watch a 'state', a 'computed', a prop, or a resource field, or move these statements to where they should run`, expression.span));
2457
2471
  return false;
@@ -2519,11 +2533,16 @@ export class VelarWebAnalyzer extends Analyzer {
2519
2533
  for (const statement of body) {
2520
2534
  if (statementBindsName(statement, root))
2521
2535
  return;
2522
- const selfWrite = place === null ? null : this.watchSelfWrite(subject, place, statement, writes);
2536
+ const selfWrite = place === null ? null : watchSelfWrite(subject, place, statement, writes);
2523
2537
  if (selfWrite !== null) {
2524
2538
  this.diagnostics.push(diagnostic("VEL5077", selfWrite, statement.span));
2525
2539
  return;
2526
2540
  }
2541
+ const inFinally = place === null ? null : finallySelfWrite(subject, place, statement, writes, root);
2542
+ if (inFinally !== null) {
2543
+ this.diagnostics.push(diagnostic("VEL5077", inFinally.message, inFinally.span));
2544
+ return;
2545
+ }
2527
2546
  const call = topLevelCall(statement);
2528
2547
  if (call === null)
2529
2548
  continue;
@@ -2550,42 +2569,6 @@ export class VelarWebAnalyzer extends Analyzer {
2550
2569
  return;
2551
2570
  }
2552
2571
  }
2553
- /**
2554
- * D114 0.28.0 H-D1: the VEL5077 message one plain body statement earns, or
2555
- * null when it earns none.
2556
- *
2557
- * §15 says a watch fires on a *deep* change of its subject, so `watch form:
2558
- * form.name = …` and `watch items: items[0].done = …` are the same ring
2559
- * `items.append(…)` already is — decided at the top of the body, with no
2560
- * condition to end it — and were silent until the runtime's 100-round cap
2561
- * stopped them. The rule is therefore stated on the path rather than on the
2562
- * spelling: a write whose place is the subject, or any place below it, in an
2563
- * assignment, a compound assignment, or a mutating call.
2564
- *
2565
- * Every existing exclusion stands, because each is answered somewhere else: a
2566
- * conditional or nested write is not a plain body statement, a rebinding
2567
- * stops the scan in `rejectWatchCycle`, and a sibling path (`watch form.name:`
2568
- * writing `form.email`) or a different root fails the step comparison here.
2569
- */
2570
- watchSelfWrite(subject, place, statement, writes) {
2571
- const write = reactiveWriteCandidate(statement);
2572
- if (write === null)
2573
- return null;
2574
- const steps = reactiveStepsBelow(place, write.place);
2575
- if (steps === null || !writes(steps, write.method))
2576
- return null;
2577
- // A derived value is offered only where it could be declared. A field
2578
- // or an element has no `computed` spelling of its own, so naming one
2579
- // would hand the author a line that does not compile.
2580
- const derived = subject.kind === "IdentifierExpression"
2581
- ? `declare 'computed ${place.text} = ...' instead`
2582
- : "write this value where it is produced instead";
2583
- const head = steps.length === 0
2584
- ? `This watch writes its own subject '${place.text}'`
2585
- : `This watch writes '${write.place.text}', a part of its subject '${place.text}',`;
2586
- return `${head} at the top of its body, so every run re-triggers it and the runtime stops the loop after 100`
2587
- + ` rounds; write the condition that ends it, or watch the input this value follows and ${derived}`;
2588
- }
2589
2572
  /**
2590
2573
  * D114 0.28.0 H-D1: the type of the place `steps` below the watched subject,
2591
2574
  * or null when the walk cannot reach one.
@@ -2907,11 +2890,7 @@ export class VelarWebAnalyzer extends Analyzer {
2907
2890
  inferExtensionCall(callee, arguments_, argumentNames, callSpan) {
2908
2891
  if (!isWebComponentType(callee))
2909
2892
  return undefined;
2910
- const name = webComponentName(callee);
2911
- this.typeError(name ? `Render component '${name}' with JSX` : "Render a Component value with JSX", callSpan);
2912
- if (argumentNames?.some((argument) => argument !== null)) {
2913
- this.typeError("Components use JSX props rather than named call arguments", callSpan);
2914
- }
2893
+ this.typeError(componentCallRefusal(webComponentName(callee), arguments_, argumentNames, this.webSourceText), callSpan);
2915
2894
  for (const argument of arguments_)
2916
2895
  this.inferExpression(argument);
2917
2896
  return webNodeType;
@@ -2982,6 +2961,17 @@ export class VelarWebAnalyzer extends Analyzer {
2982
2961
  }
2983
2962
  return super.ownershipScopeRejection();
2984
2963
  }
2964
+ /**
2965
+ * D114 0.29.0 JX-I2: a component body has no function frame, so a `return` nested
2966
+ * inside it — in a `match` arm, an `if`, a `for` — used to earn VEL3003 next to
2967
+ * VEL5008 ("exactly one top-level return"), two rules its author can only read as
2968
+ * contradicting each other. A lifecycle hook and a watch body are inside the same
2969
+ * component and are *not* it: neither returns anything, so a `return` there keeps
2970
+ * VEL3003.
2971
+ */
2972
+ extensionOwnsFunctionlessReturn() {
2973
+ return this.componentBodyDepth > 0 && this.mountedDepth === 0 && this.cleanupDepth === 0 && this.watchBodyDepth === 0;
2974
+ }
2985
2975
  invalidExtensionAwaitContext() {
2986
2976
  return this.synchronousReactiveDepth > 0 || this.jsxDepth > 0
2987
2977
  || (this.componentStates !== null && this.mountedDepth === 0);
@@ -3179,16 +3169,7 @@ export class VelarWebAnalyzer extends Analyzer {
3179
3169
  this.analyzeStatement(item);
3180
3170
  }
3181
3171
  }
3182
- if (renders !== 1)
3183
- this.diagnostics.push(diagnostic("VEL5008", `Component '${statement.name}' must have exactly one top-level return`, statement.span));
3184
- if (mounted > 1)
3185
- this.diagnostics.push(diagnostic("VEL5009", `Component '${statement.name}' has more than one '@mounted' block`, statement.span));
3186
- if (cleanup > 1)
3187
- this.diagnostics.push(diagnostic("VEL5010", `Component '${statement.name}' has more than one '@cleanup' block`, statement.span));
3188
- if (exposes > 1)
3189
- this.diagnostics.push(diagnostic("VEL5056", `Component '${statement.name}' has more than one expose declaration`, statement.span));
3190
- if (statement.handleType && exposes === 0)
3191
- this.diagnostics.push(diagnostic("VEL5056", `Component '${statement.name}' declares an exposed Handle but does not provide an expose value`, statement.handleType.span));
3172
+ this.diagnostics.push(...componentSectionCountDiagnostics(statement.name, { renders, mounted, cleanup, exposes }, statement.span, statement.handleType?.span ?? null));
3192
3173
  if (renderValue && isWebJsx(renderValue))
3193
3174
  this.validateComponentHost(renderValue, statement);
3194
3175
  this.componentStates = previousStates;
@@ -3412,6 +3393,7 @@ export class VelarWebAnalyzer extends Analyzer {
3412
3393
  // table: `rgba(0, 0, 0, alpha=2)` compiled clean while `rgba(0, 0, 0, 2)`
3413
3394
  // was refused.
3414
3395
  const parameters = LOOK_BUILDER_SIGNATURES.get(builder)?.parameters;
3396
+ const before = this.diagnostics.length;
3415
3397
  for (const [index, argument] of expression.arguments.entries()) {
3416
3398
  const named = expression.argumentNames?.[index] ?? null;
3417
3399
  const position = named === null ? index : parameters?.indexOf(named) ?? -1;
@@ -3462,6 +3444,9 @@ export class VelarWebAnalyzer extends Analyzer {
3462
3444
  if (builder === "filters" && expression.arguments.length > 64) {
3463
3445
  this.diagnostics.push(diagnostic("VEL5042", "filters cannot compose more than 64 values", expression.span));
3464
3446
  }
3447
+ // D114 0.29.0 LK-I2: a call its own argument check refused is recorded so a `keyframes:` stop can drop the consequence. The record is the call rather than the code, because a bad token name and a stop's one-declaration rule are two facts about one value (D103-2) and both are still reported.
3448
+ if (this.diagnostics.length > before)
3449
+ this.refusedBuilderCalls.push(expression.span);
3465
3450
  }
3466
3451
  /**
3467
3452
  * D103 rules 1 and 5 — what a checked token reference has to be at the site
@@ -3602,7 +3587,11 @@ export class VelarWebAnalyzer extends Analyzer {
3602
3587
  const expected = LOOK_PROPERTY_TYPES.get(entry.name) ?? stringType;
3603
3588
  const actual = this.inferExpression(entry.value, expected);
3604
3589
  this.reportKeyframeSnapshotReads(entry.value);
3605
- if (keyframeCssValue(entry.value, this.lookStaticValues) === null) {
3590
+ // LK-I2: a builder that failed its own argument check has already been told what
3591
+ // is wrong with it, and "does not resolve to static CSS" is only the consequence —
3592
+ // a sentence that sends its author looking for a rule against named arguments in
3593
+ // a stop, which there is not (`spread=2px` in range compiles).
3594
+ if (keyframeCssValue(entry.value, this.lookStaticValues) === null && !this.refusedBuilderCallWithin(entry.value.span)) {
3606
3595
  this.diagnostics.push(diagnostic("VEL5060", "A keyframe value must resolve to static CSS from literals, unit values, arithmetic, velar/look builders, or const bindings — local or imported — that hold any of those, and the text it resolves to must read as one declaration value: no ';', '{', '}', or '@' outside a string, with parentheses, strings, and comments all closed", entry.value.span));
3607
3596
  }
3608
3597
  if (mentionsLookUnitType(expected) && lookLiteralZero(entry.value))
@@ -3614,6 +3603,10 @@ export class VelarWebAnalyzer extends Analyzer {
3614
3603
  }
3615
3604
  }
3616
3605
  }
3606
+ /** Whether a builder call this compile refused on its own arguments lies inside `sourceSpan`. */
3607
+ refusedBuilderCallWithin(sourceSpan) {
3608
+ return this.refusedBuilderCalls.some((call) => call.start >= sourceSpan.start && call.end <= sourceSpan.end);
3609
+ }
3617
3610
  reportKeyframeSnapshotReads(expression) {
3618
3611
  const visit = (value) => {
3619
3612
  if (Array.isArray(value)) {
@@ -4374,7 +4367,8 @@ export class VelarWebAnalyzer extends Analyzer {
4374
4367
  }
4375
4368
  const handle = webComponentHandle(component);
4376
4369
  if (!handle) {
4377
- this.diagnostics.push(diagnostic("VEL5057", `Component '${expression.tag}' does not expose a Handle`, attribute.span));
4370
+ const stored = nonOptional(this.expandAliases(this.lookup(value.name)?.declaredType ?? unknownType));
4371
+ this.diagnostics.push(diagnostic("VEL5057", componentRefHandleRefusal(expression.tag, component, stored), attribute.span));
4378
4372
  return;
4379
4373
  }
4380
4374
  const bindingType = this.lookup(value.name).type;