@elaraai/east-diagnostics 1.0.90 → 1.0.91

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/README.md CHANGED
@@ -40,7 +40,7 @@ like any linter.
40
40
  - **`no-relative-src-import`** - Importing *another* package's internals via `../src/…` or a deep `@elaraai/x/src` path instead of its published name. (A package importing its **own** `src` relatively — e.g. a spec's `../src/index.js` — is exempt; it cannot import its own published name.)
41
41
  - **`no-let-const-in-expression`** - `$.let`/`$.const` used anywhere other than a `const`/`let` initializer, a bare statement, a `return`, or a concise arrow body (e.g. a struct-field value, array element, call argument, or chain target buries the declaration in an expression).
42
42
  - **`no-unexecuted-east-expression`** - A bare East expression statement that is never executed with `$( … )` or bound.
43
- - **`no-reinlined-east-binding`** - An East `Expr` bound to a JS `const`/`let` and reused inside a block is re-inlined per use — bind it once with `$.let`/`$.const`.
43
+ - **`no-reinlined-east-binding`** - An East `Expr` bound to a JS `const`/`let` and read twice inside one East body, or read inside a per-element callback, a `$.for`/`$.while` body or a nested `East.function`, is re-inlined — and re-evaluated — at each read; bind it once with `$.let`/`$.const`. One read per exclusive arm (`.ifElse`, `$.if … .else`, a `match` arm) and a `$.const` read anywhere stay silent.
44
44
  - **`prefer-jsx-over-factory-call`** - In a `.tsx` file, a factory's `Foo.Root(...)` whose result is a JSX element — author it with the `<Foo>` tag instead.
45
45
  - **`no-untracked-east-data`** - A bare JS `const` literal consumed in an East-typed position inside a block — bind it with `$.const`/`$.let`.
46
46
 
@@ -4,6 +4,8 @@
4
4
  */
5
5
  import type * as ts from "typescript";
6
6
  import type { RuleContext, TsModule } from "./types.js";
7
+ /** `East.function(...)` / `East.asyncFunction(...)` — the classic East block root. */
8
+ export declare function isEastFunctionCall(node: ts.Node, t: TsModule): node is ts.CallExpression;
7
9
  /** True for an arrow/function whose first parameter is an East `BlockBuilder` —
8
10
  * the shape of every East block callback: `East.function`'s `$ => …`, the JSX
9
11
  * `<Reactive>{$ => …}}`, `ui(…, $ => …)`, a `.map(($, x) => …)` body. Keying on
@@ -1 +1 @@
1
- {"version":3,"file":"block-scope.d.ts","sourceRoot":"","sources":["../../src/block-scope.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAexD;;;;sEAIsE;AACtE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAM/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,EAAE,CAAC,IAAI,GAAG,SAAS,CAWxF;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAEzE;AAED;4DAC4D;AAC5D,wBAAgB,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAclE"}
1
+ {"version":3,"file":"block-scope.d.ts","sourceRoot":"","sources":["../../src/block-scope.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGxD,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,cAAc,CASxF;AAED;;;;sEAIsE;AACtE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAM/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,EAAE,CAAC,IAAI,GAAG,SAAS,CAWxF;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAEzE;AAED;4DAC4D;AAC5D,wBAAgB,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAclE"}
@@ -1,6 +1,6 @@
1
1
  import { isBlockBuilderType } from "./east-type.js";
2
2
  /** `East.function(...)` / `East.asyncFunction(...)` — the classic East block root. */
3
- function isEastFunctionCall(node, t) {
3
+ export function isEastFunctionCall(node, t) {
4
4
  if (!t.isCallExpression(node))
5
5
  return false;
6
6
  const callee = node.expression;
@@ -1 +1 @@
1
- {"version":3,"file":"block-scope.js","sourceRoot":"","sources":["../../src/block-scope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block-scope.js","sourceRoot":"","sources":["../../src/block-scope.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,13 @@
1
1
  import type { EastRule } from "../types.js";
2
+ /** Methods of the East expression classes (and the `East.Array` / `East.Set` / `East.Dict`
3
+ * generators) whose callback body runs per element, per key or per iteration. The spec pins the
4
+ * partition: every callback-taking method of the Expr classes is here or in `ONCE_METHODS`. */
5
+ export declare const REPEATING_METHODS: ReadonlySet<string>;
6
+ /** Callback-taking methods whose body runs ONCE per call: a default producer, a single-key upsert
7
+ * or merge, a conditional, a handler. */
8
+ export declare const ONCE_METHODS: ReadonlySet<string>;
9
+ /** The `BlockBuilder` loop statements: their body runs per iteration. The other statement bodies
10
+ * (`if` / `else` / `elseIf` / `match` / `try` / `catch` / `finally`) run at most once. */
11
+ export declare const LOOP_METHODS: ReadonlySet<string>;
2
12
  export declare const noReinlinedEastBinding: EastRule;
3
13
  //# sourceMappingURL=no-reinlined-east-binding.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"no-reinlined-east-binding.d.ts","sourceRoot":"","sources":["../../../src/rules/no-reinlined-east-binding.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAsB5C,eAAO,MAAM,sBAAsB,EAAE,QAuDpC,CAAC"}
1
+ {"version":3,"file":"no-reinlined-east-binding.d.ts","sourceRoot":"","sources":["../../../src/rules/no-reinlined-east-binding.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAyB,MAAM,aAAa,CAAC;AA2BnE;;+FAE+F;AAC/F,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAQhD,CAAC;AAEH;yCACyC;AACzC,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAE3C,CAAC;AAEH;0FAC0F;AAC1F,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAA6B,CAAC;AAqD3E,eAAO,MAAM,sBAAsB,EAAE,QAmEpC,CAAC"}
@@ -1,25 +1,104 @@
1
- import { isEastExprType } from "../east-type.js";
1
+ import { isBlockBuilderType, isEastExprType } from "../east-type.js";
2
2
  import { matchBlockBuilderCall } from "../block-builder.js";
3
- import { enclosingBlockScope } from "../block-scope.js";
3
+ import { enclosingBlockScope, isEastFunctionCall } from "../block-scope.js";
4
4
  const NAME = "no-reinlined-east-binding";
5
5
  const CODE = 990010;
6
- // An East `Expr` is a value tree, not a slot. Bound to a JS `const`/`let` and
7
- // referenced more than once inside the same East block, it is *re-inlined* at
8
- // each use — the tree is duplicated, so it is re-evaluated per use and (for
9
- // mutable values) gets a fresh identity each time. `$.let`/`$.const` introduce
10
- // a single block binding evaluated once and referenced by name, which is the
11
- // only way to get single-evaluation + shared identity. So multi-use JS bindings
12
- // of an `Expr` are an error, not a style nit.
6
+ // An East `Expr` is a value tree, not a slot. Bound to a JS `const`/`let` and read more than once
7
+ // inside one East body, it is *re-inlined* at each read — the tree is duplicated, so it is
8
+ // re-evaluated per read and (for mutable values) gets a fresh identity each time. Read once inside a
9
+ // body that RUNS REPEATEDLY — a per-element callback, a `$.for`/`$.while` body, a nested
10
+ // `East.function` — it is re-evaluated every time that body runs. `$.let`/`$.const` introduce a
11
+ // single block binding evaluated once and referenced by name, which is the only way to get
12
+ // single-evaluation + shared identity. So such JS bindings of an `Expr` are an error, not a style
13
+ // nit. (The python builder is held to the same reading since #1312 removed its trace-time pass.)
13
14
  //
14
- // Scoped to the hazard: a single use is a harmless alias / single-pass argument,
15
- // and inline composition (`Stack.VStack([A(), B(), …])`) never binds, so neither
16
- // trips. Re-inlining only duplicates within one East block tree, so the count is
17
- // bucketed per enclosing East block scope (an `East.function` body or, for JSX
18
- // authoring, a `<Reactive>{$ => …}}` / `ui(…)` BlockBuilder callback).
15
+ // Scoped to the hazard, so a correct program is never asked to change:
16
+ // - a single read is a harmless alias / single-pass argument, and inline composition
17
+ // (`Stack.VStack([A(), B(), …])`) never binds, so neither trips;
18
+ // - reads are counted per enclosing function: two reads in the body that bound the value, or two
19
+ // inside one arm, are two evaluations; one read in each of two EXCLUSIVE arms — `.ifElse(() => a,
20
+ // () => b)`, `$.if(…).else(…)`, the arms of `$.match` / `.match` — is at most one, and is not
21
+ // flagged (binding a guarded partial read above its guard would raise on the very path the guard
22
+ // excludes);
23
+ // - a read inside a body the rule cannot classify counts as once-only and stays silent.
24
+ /** Methods of the East expression classes (and the `East.Array` / `East.Set` / `East.Dict`
25
+ * generators) whose callback body runs per element, per key or per iteration. The spec pins the
26
+ * partition: every callback-taking method of the Expr classes is here or in `ONCE_METHODS`. */
27
+ export const REPEATING_METHODS = new Set([
28
+ "map", "filter", "filterMap", "firstMap", "flatMap", "flattenToArray", "flattenToSet", "flattenToDict",
29
+ "forEach", "reduce", "scan", "mapReduce", "groupReduce", "groupBy", "groupSize", "groupSum", "groupMean",
30
+ "groupEvery", "groupSome", "groupMaximum", "groupMinimum", "groupToArrays", "groupToSets", "groupToDicts",
31
+ "groupFindAll", "groupFindFirst", "groupFindMaximum", "groupFindMinimum", "toDict", "toSet", "toArray",
32
+ "toTree", "sort", "sortInPlace", "isSorted", "findFirst", "findAll", "findMaximum", "findMinimum",
33
+ "findSortedFirst", "findSortedLast", "findSortedRange", "mergeAll", "unionInPlace", "mapRows", "some",
34
+ "every", "sum", "mean", "maximum", "minimum", "getKeys", "generate",
35
+ ]);
36
+ /** Callback-taking methods whose body runs ONCE per call: a default producer, a single-key upsert
37
+ * or merge, a conditional, a handler. */
38
+ export const ONCE_METHODS = new Set([
39
+ "get", "getOrInsert", "insertOrUpdate", "merge", "match", "matchTag", "unwrap", "ifElse", "and", "or", "update", "if", "try",
40
+ ]);
41
+ /** The `BlockBuilder` loop statements: their body runs per iteration. The other statement bodies
42
+ * (`if` / `else` / `elseIf` / `match` / `try` / `catch` / `finally`) run at most once. */
43
+ export const LOOP_METHODS = new Set(["for", "while"]);
44
+ function isFunctionLike(node, t) {
45
+ return t.isArrowFunction(node) || t.isFunctionExpression(node) || t.isFunctionDeclaration(node) || t.isMethodDeclaration(node);
46
+ }
47
+ /** The innermost function (arrow, function expression or declaration, method) enclosing `node`. */
48
+ function enclosingFunction(node, t) {
49
+ let current = node.parent;
50
+ while (current !== undefined && !isFunctionLike(current, t))
51
+ current = current.parent;
52
+ return current;
53
+ }
54
+ /** How often `fn` — a function handed to a call — runs per run of the code around the call:
55
+ * `"callback"` (per element), `"loop body"` (per iteration), `"nested function"` (per call of the
56
+ * function it builds), or undefined for a body that runs at most once, or one the rule cannot
57
+ * classify. */
58
+ function hostKind(fn, ctx) {
59
+ const t = ctx.ts;
60
+ const call = fn.parent;
61
+ if (call === undefined || !t.isCallExpression(call) || !call.arguments.some((arg) => arg === fn))
62
+ return undefined;
63
+ const callee = call.expression; // read before the guard below narrows `call` away
64
+ if (isEastFunctionCall(call, t))
65
+ return "nested function";
66
+ if (!t.isPropertyAccessExpression(callee))
67
+ return undefined;
68
+ const method = callee.name.text;
69
+ const receiver = callee.expression;
70
+ if (LOOP_METHODS.has(method)) {
71
+ return isBlockBuilderType(ctx.checker.getTypeAtLocation(receiver)) ? "loop body" : undefined;
72
+ }
73
+ if (!REPEATING_METHODS.has(method))
74
+ return undefined;
75
+ if (isEastExprType(ctx.checker.getTypeAtLocation(receiver)))
76
+ return "callback";
77
+ // the namespace generators: `East.Array.generate(n, T, ($, i) => …)` and kin
78
+ if (t.isPropertyAccessExpression(receiver) && t.isIdentifier(receiver.expression) && receiver.expression.text === "East") {
79
+ return "callback";
80
+ }
81
+ return undefined;
82
+ }
83
+ /** The outermost repeatedly-running function between the declaration's own function (exclusive)
84
+ * and `use` — the one that multiplies the read the most — or undefined. */
85
+ function repeatingHostBetween(use, declFunction, ctx) {
86
+ let found;
87
+ let current = use.parent;
88
+ while (current !== undefined && current !== declFunction) {
89
+ if (isFunctionLike(current, ctx.ts)) {
90
+ const kind = hostKind(current, ctx);
91
+ if (kind !== undefined)
92
+ found = kind;
93
+ }
94
+ current = current.parent;
95
+ }
96
+ return found;
97
+ }
19
98
  export const noReinlinedEastBinding = {
20
99
  name: NAME,
21
100
  code: CODE,
22
- description: "An East Expr bound to a JS const/let and reused inside an East block is re-inlined per use — bind it once with $.let/$.const.",
101
+ description: "An East Expr bound to a JS const/let and read twice inside one East body, or read inside a per-element callback, a loop body or a nested East.function, is re-inlined — and re-evaluated — at each read; bind it once with $.let/$.const.",
23
102
  check(node, ctx) {
24
103
  const t = ctx.ts;
25
104
  if (!t.isVariableDeclaration(node))
@@ -46,32 +125,44 @@ export const noReinlinedEastBinding = {
46
125
  if (declSymbol === undefined)
47
126
  return;
48
127
  const name = node.name.text;
49
- const perBody = new Map();
128
+ const declFunction = enclosingFunction(node, t);
129
+ // reads per enclosing function (an exclusive arm is a function of its own)
130
+ const perFunction = new Map();
131
+ let repeating;
50
132
  const visit = (n) => {
51
- if (t.isIdentifier(n) && n !== node.name && n.text === name) {
52
- if (ctx.checker.getSymbolAtLocation(n) === declSymbol) {
53
- const body = enclosingBlockScope(n, ctx);
54
- if (body !== undefined)
55
- perBody.set(body, (perBody.get(body) ?? 0) + 1);
133
+ if (t.isIdentifier(n) && n !== node.name && n.text === name && ctx.checker.getSymbolAtLocation(n) === declSymbol) {
134
+ // a read outside every East block scope re-inlines into nothing
135
+ if (enclosingBlockScope(n, ctx) !== undefined) {
136
+ const multiplied = repeatingHostBetween(n, declFunction, ctx);
137
+ if (multiplied !== undefined) {
138
+ repeating ??= multiplied;
139
+ }
140
+ else {
141
+ const bucket = enclosingFunction(n, t) ?? ctx.sourceFile;
142
+ perFunction.set(bucket, (perFunction.get(bucket) ?? 0) + 1);
143
+ }
56
144
  }
57
145
  }
58
146
  t.forEachChild(n, visit);
59
147
  };
60
148
  visit(ctx.sourceFile);
61
- let maxInBody = 0;
62
- for (const count of perBody.values())
63
- if (count > maxInBody)
64
- maxInBody = count;
65
- if (maxInBody < 2)
149
+ let worst = 0;
150
+ for (const count of perFunction.values())
151
+ if (count > worst)
152
+ worst = count;
153
+ if (worst < 2 && repeating === undefined)
66
154
  return;
67
155
  const sf = ctx.sourceFile;
68
156
  const start = node.getStart(sf);
157
+ const messageText = worst >= 2
158
+ ? `This East expression is bound to a JS \`const\`/\`let\` and read ${worst} times inside one East body, so it is re-inlined — and re-evaluated, with a fresh identity for mutable values — at each read. Bind it once with \`$.const\`/\`$.let\`.`
159
+ : `This East expression is bound to a JS \`const\`/\`let\` outside a ${repeating} and read inside it, so it is re-inlined there — and re-evaluated every time the ${repeating} runs. Bind it once with \`$.const\`/\`$.let\` before the call.`;
69
160
  ctx.report({
70
161
  ruleName: NAME,
71
162
  code: CODE,
72
163
  start,
73
164
  length: node.getEnd() - start,
74
- messageText: "This East expression is bound to a JS `const`/`let` and used more than once inside an East block, so it is re-inlined — and re-evaluated, with a fresh identity for mutable values — at each use. Bind it once with `$.const`/`$.let`.",
165
+ messageText,
75
166
  category: "error",
76
167
  });
77
168
  },
@@ -1 +1 @@
1
- {"version":3,"file":"no-reinlined-east-binding.js","sourceRoot":"","sources":["../../../src/rules/no-reinlined-east-binding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"no-reinlined-east-binding.js","sourceRoot":"","sources":["../../../src/rules/no-reinlined-east-binding.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elaraai/east-diagnostics",
3
- "version": "1.0.90",
3
+ "version": "1.0.91",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "description": "East-aware diagnostic rules over the TypeScript checker — one shared engine for the editor (tsserver plugin), the agent (headless daemon), and CI.",
@@ -44,8 +44,8 @@
44
44
  "devDependencies": {
45
45
  "@types/node": "^22.18.1",
46
46
  "typescript": "~5.9.2",
47
- "@elaraai/east": "1.0.90",
48
- "@elaraai/e3": "1.0.90"
47
+ "@elaraai/east": "1.0.91",
48
+ "@elaraai/e3": "1.0.91"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsc",