wrec 0.30.2 → 0.31.0
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 +1 -1
- package/dist/{wrec-DEac2MyH.js → wrec-C03zEU8-.js} +57 -44
- package/dist/wrec-ssr.es.js +1 -1
- package/dist/wrec.es.js +1 -1
- package/package.json +1 -1
- package/scripts/lint.js +69 -33
package/README.md
CHANGED
|
@@ -167,7 +167,7 @@ var f = () => /* @__PURE__ */ new Map(), p = new Set([
|
|
|
167
167
|
whenDefined: () => Promise.reject(/* @__PURE__ */ Error("customElements is not available in this environment"))
|
|
168
168
|
}, g = class extends Error {}, _ = /([a-zA-Z-]+)\s*:\s*([^;}]+)/g, v = "a-zA-Z_$", y = `[${v}][${v + "0-9"}]*`, b = RegExp(`this\\.(${y})\\s*\\(`, "g"), x = /<!--\s*(.*?)\s*-->/, S = /<(\w+)(?:\s[^>]*)?>((?:[^<]|<(?!\w))*?)<\/\1>/g, C = RegExp(`^this\\.${y}$`), w = RegExp(`this\\.${y}(\\.${y})*`, "g"), T = RegExp(`this\\.${y}(\\.${y})*`), E = 5;
|
|
169
169
|
function D(e) {
|
|
170
|
-
return e instanceof HTMLButtonElement || e instanceof HTMLFieldSetElement || e instanceof HTMLInputElement || e instanceof HTMLSelectElement || e instanceof HTMLTextAreaElement || e instanceof
|
|
170
|
+
return e instanceof HTMLButtonElement || e instanceof HTMLFieldSetElement || e instanceof HTMLInputElement || e instanceof HTMLSelectElement || e instanceof HTMLTextAreaElement || e instanceof G;
|
|
171
171
|
}
|
|
172
172
|
function O(e, t, n) {
|
|
173
173
|
let r = document.createElement(e);
|
|
@@ -188,46 +188,49 @@ function N(e, t) {
|
|
|
188
188
|
}), n;
|
|
189
189
|
}
|
|
190
190
|
function P(e) {
|
|
191
|
+
return e instanceof HTMLInputElement && e.type === "checkbox";
|
|
192
|
+
}
|
|
193
|
+
function F(e) {
|
|
191
194
|
let t = typeof e;
|
|
192
195
|
return t === "string" || t === "number" || t === "boolean";
|
|
193
196
|
}
|
|
194
|
-
function
|
|
197
|
+
function I(e) {
|
|
195
198
|
return e.localName === "textarea";
|
|
196
199
|
}
|
|
197
|
-
function
|
|
200
|
+
function L(e) {
|
|
198
201
|
let { localName: t } = e;
|
|
199
202
|
return t === "input" || t === "select";
|
|
200
203
|
}
|
|
201
|
-
var
|
|
202
|
-
function
|
|
204
|
+
var R = (e) => e.replace(/<!--[\s\S]*?-->/g, "");
|
|
205
|
+
function z(e, t, n, r) {
|
|
203
206
|
return e.slice(0, t) + r + e.slice(t + n);
|
|
204
207
|
}
|
|
205
|
-
function
|
|
208
|
+
function B(e) {
|
|
206
209
|
let t = Number(e);
|
|
207
210
|
if (isNaN(t)) throw new g(`can't convert "${e}" to a number`);
|
|
208
211
|
return t;
|
|
209
212
|
}
|
|
210
|
-
function
|
|
213
|
+
function V(e, t, n) {
|
|
211
214
|
let [r, i] = t.split(":");
|
|
212
|
-
if (
|
|
215
|
+
if (F(n)) if (typeof n == "boolean") {
|
|
213
216
|
n ? e.setAttribute(r, r) : e.removeAttribute(r);
|
|
214
|
-
let t =
|
|
217
|
+
let t = G.getPropName(r);
|
|
215
218
|
e[t] = n;
|
|
216
219
|
} else {
|
|
217
220
|
let i = e.getAttribute(t), a = String(n);
|
|
218
|
-
i !== a && (e.setAttribute(r, a), r === "value" &&
|
|
221
|
+
i !== a && (e.setAttribute(r, a), r === "value" && L(e) && (e.value = a));
|
|
219
222
|
}
|
|
220
223
|
else {
|
|
221
|
-
let r =
|
|
224
|
+
let r = G.getPropName(t);
|
|
222
225
|
e[r] = n;
|
|
223
226
|
}
|
|
224
227
|
}
|
|
225
|
-
function
|
|
228
|
+
function H(e, t, n) {
|
|
226
229
|
let [r, i] = t.split(":");
|
|
227
|
-
e instanceof CSSStyleRule ? e.style.setProperty(r, n) : (
|
|
230
|
+
e instanceof CSSStyleRule ? e.style.setProperty(r, n) : (V(e, r, n), r === "value" && L(e) && (e.value = n));
|
|
228
231
|
}
|
|
229
|
-
var
|
|
230
|
-
async function
|
|
232
|
+
var U = (e) => typeof e == "string" ? [e] : e;
|
|
233
|
+
async function W(e) {
|
|
231
234
|
let t = /* @__PURE__ */ new Set();
|
|
232
235
|
for (let n of j(e.content)) {
|
|
233
236
|
let { localName: e } = n;
|
|
@@ -243,7 +246,7 @@ async function U(e) {
|
|
|
243
246
|
}
|
|
244
247
|
return Promise.all([...t].map(async (e) => Promise.race([h.whenDefined(e), n(e)])));
|
|
245
248
|
}
|
|
246
|
-
var
|
|
249
|
+
var G = class e extends m {
|
|
247
250
|
static {
|
|
248
251
|
this.attrToPropMap = /* @__PURE__ */ new Map();
|
|
249
252
|
}
|
|
@@ -316,7 +319,7 @@ var W = class e extends m {
|
|
|
316
319
|
}
|
|
317
320
|
async #d() {
|
|
318
321
|
let e = this.#n, { template: t } = e;
|
|
319
|
-
t || (t = e.template = document.createElement("template"), t.innerHTML = e.buildHTML()), await
|
|
322
|
+
t || (t = e.template = document.createElement("template"), t.innerHTML = e.buildHTML()), await W(t), this.shadowRoot.replaceChildren(t.content.cloneNode(!0));
|
|
320
323
|
}
|
|
321
324
|
static buildHTML() {
|
|
322
325
|
let e = "<style>\n :host([hidden]) { display: none; }";
|
|
@@ -354,7 +357,7 @@ var W = class e extends m {
|
|
|
354
357
|
return this[u];
|
|
355
358
|
},
|
|
356
359
|
set(e) {
|
|
357
|
-
n.computed && !this.#t.has(t) && this.#F(null, t, "is a computed property and cannot be set directly"), c === Number && typeof e == "string" && (e =
|
|
360
|
+
n.computed && !this.#t.has(t) && this.#F(null, t, "is a computed property and cannot be set directly"), c === Number && typeof e == "string" && (e = B(e));
|
|
358
361
|
let r = this[u];
|
|
359
362
|
if (e === r) return;
|
|
360
363
|
this.#q(t, c, e), this[u] = e;
|
|
@@ -400,7 +403,12 @@ var W = class e extends m {
|
|
|
400
403
|
if (a) {
|
|
401
404
|
let i = this[a];
|
|
402
405
|
i === void 0 && this.#I(t, r, a);
|
|
403
|
-
let [o, s] = r.split(":"), c = e.getPropName(o)
|
|
406
|
+
let [o, s] = r.split(":"), c = e.getPropName(o);
|
|
407
|
+
if (o === "checked" && P(t)) {
|
|
408
|
+
let { type: e } = this.#n.properties[a];
|
|
409
|
+
e !== Boolean && this.#F(t, r, `refers to property "${a}" whose type is not Boolean`);
|
|
410
|
+
}
|
|
411
|
+
let l = this.#T(a);
|
|
404
412
|
n && t.#T(c) || (t[c] = i), o === "value" && (s ? (t["on" + s] === void 0 && this.#F(t, r, "refers to an unsupported event name"), t.setAttribute(o, this[a])) : s = "change"), n && !l && t.#c.set(e.getPropName(o), a);
|
|
405
413
|
}
|
|
406
414
|
this.#N(i, t, r);
|
|
@@ -418,7 +426,7 @@ var W = class e extends m {
|
|
|
418
426
|
if (t instanceof HTMLElement) this.#V(t, e);
|
|
419
427
|
else if (!(t instanceof CSSStyleRule)) {
|
|
420
428
|
let { element: n, attrName: r } = t;
|
|
421
|
-
n instanceof CSSStyleRule ? n.style.setProperty(r, e) :
|
|
429
|
+
n instanceof CSSStyleRule ? n.style.setProperty(r, e) : H(n, r, e);
|
|
422
430
|
}
|
|
423
431
|
}
|
|
424
432
|
if (r.size > 0) {
|
|
@@ -444,7 +452,7 @@ var W = class e extends m {
|
|
|
444
452
|
}
|
|
445
453
|
} else {
|
|
446
454
|
let t = "";
|
|
447
|
-
if (
|
|
455
|
+
if (I(e)) {
|
|
448
456
|
this.#N(e.textContent, e);
|
|
449
457
|
let n = e.textContent?.match(x);
|
|
450
458
|
n && (t = n[1]);
|
|
@@ -454,7 +462,7 @@ var W = class e extends m {
|
|
|
454
462
|
}
|
|
455
463
|
if (t) {
|
|
456
464
|
let n = this.#O(e, t);
|
|
457
|
-
n &&
|
|
465
|
+
n && I(e) ? e.textContent = this[n] : this.#N(t, e);
|
|
458
466
|
}
|
|
459
467
|
}
|
|
460
468
|
}
|
|
@@ -474,7 +482,7 @@ var W = class e extends m {
|
|
|
474
482
|
this.#i = t, this.#a = new FormData(), this.#s = this.attachInternals(), this.#s.setFormValue(this.#a);
|
|
475
483
|
for (let [e, n] of Object.entries(t)) {
|
|
476
484
|
let t = this[e];
|
|
477
|
-
|
|
485
|
+
F(t) && this.setFormValue(n, String(t));
|
|
478
486
|
}
|
|
479
487
|
let r = Object.keys(this.#n.properties), i = this.#o;
|
|
480
488
|
for (let e of r) i[e] = this[e];
|
|
@@ -540,15 +548,20 @@ var W = class e extends m {
|
|
|
540
548
|
if (n.length !== 1) return;
|
|
541
549
|
let [r] = n;
|
|
542
550
|
if (!C.test(r)) return;
|
|
543
|
-
let i =
|
|
544
|
-
if (!(
|
|
545
|
-
|
|
546
|
-
let
|
|
547
|
-
e.addEventListener(
|
|
551
|
+
let i = P(e), a = L(e) || I(e), [o, s] = (t ?? "").split(":");
|
|
552
|
+
if (!(a && o === "value" || i && o === "checked" || I(e))) return;
|
|
553
|
+
s ? e["on" + s] === void 0 && this.#F(e, t, "refers to an unsupported event name") : s = "change";
|
|
554
|
+
let c = M(r);
|
|
555
|
+
e.addEventListener(s, (e) => {
|
|
548
556
|
let { target: t } = e;
|
|
549
557
|
if (!t) return;
|
|
550
|
-
let
|
|
551
|
-
|
|
558
|
+
let { type: n } = this.#n.properties[c];
|
|
559
|
+
if (o === "checked") this[c] = t.checked;
|
|
560
|
+
else {
|
|
561
|
+
let e = t.value;
|
|
562
|
+
this[c] = n === Number ? B(e) : e;
|
|
563
|
+
}
|
|
564
|
+
this.#k(c);
|
|
552
565
|
});
|
|
553
566
|
}
|
|
554
567
|
#C(e) {
|
|
@@ -607,7 +620,7 @@ var W = class e extends m {
|
|
|
607
620
|
for (let t of a.matchAll(b)) {
|
|
608
621
|
let r = t[1];
|
|
609
622
|
if (typeof this[r] != "function") throw new g(`property ${e} computed calls non-method ${r}`);
|
|
610
|
-
for (let [e, t] of Object.entries(n.properties))
|
|
623
|
+
for (let [e, t] of Object.entries(n.properties)) U(t.usedBy)?.includes(r) && i(e, a);
|
|
611
624
|
}
|
|
612
625
|
}
|
|
613
626
|
#M(e, t) {
|
|
@@ -623,7 +636,7 @@ var W = class e extends m {
|
|
|
623
636
|
let r = this.#G(t, n, e);
|
|
624
637
|
if (!r) {
|
|
625
638
|
let r = e.replaceAll("this..", "this.");
|
|
626
|
-
n ?
|
|
639
|
+
n ? H(t, n, r) : "textContent" in t && (t.textContent = r);
|
|
627
640
|
return;
|
|
628
641
|
}
|
|
629
642
|
let i = this.#n;
|
|
@@ -643,7 +656,7 @@ var W = class e extends m {
|
|
|
643
656
|
attrName: n
|
|
644
657
|
} : t), t instanceof HTMLElement && this.#S(t, n, r);
|
|
645
658
|
let o = this.#v(e);
|
|
646
|
-
n ?
|
|
659
|
+
n ? H(t, n, o) : this.#V(t, o);
|
|
647
660
|
}
|
|
648
661
|
#P(e, t) {
|
|
649
662
|
let n = t?.trim() ?? "", r = this.#n.properties[n];
|
|
@@ -653,7 +666,7 @@ var W = class e extends m {
|
|
|
653
666
|
this.hasAttribute(e) || this.setAttribute(e, t);
|
|
654
667
|
}
|
|
655
668
|
setFormValue(e, t) {
|
|
656
|
-
!this.#a || !
|
|
669
|
+
!this.#a || !F(t) || (this.#a.set(e, t), this.#s?.setFormValue(this.#a));
|
|
657
670
|
}
|
|
658
671
|
static ssr(e = {}) {
|
|
659
672
|
throw new g("SSR is not available in the browser build.");
|
|
@@ -679,7 +692,7 @@ var W = class e extends m {
|
|
|
679
692
|
}
|
|
680
693
|
return n;
|
|
681
694
|
}
|
|
682
|
-
if (i === Number) return
|
|
695
|
+
if (i === Number) return B(n);
|
|
683
696
|
if (i === Boolean) {
|
|
684
697
|
if (n === "true") return !0;
|
|
685
698
|
if (n === "false" || n === "null") return !1;
|
|
@@ -688,7 +701,7 @@ var W = class e extends m {
|
|
|
688
701
|
}
|
|
689
702
|
}
|
|
690
703
|
#z(e, t, n, r) {
|
|
691
|
-
|
|
704
|
+
F(n) && !this.#T(e) && n !== (t === Boolean ? this.hasAttribute(r) : this.#L(e, r)) && V(this, r || e, n);
|
|
692
705
|
}
|
|
693
706
|
#B(e) {
|
|
694
707
|
for (let [t, n] of this.#x([e])) this.#M(t, this.#v(n));
|
|
@@ -700,7 +713,7 @@ var W = class e extends m {
|
|
|
700
713
|
let r = typeof t;
|
|
701
714
|
r !== "string" && r !== "number" && this.#F(e, void 0, " computed content is not a string or number");
|
|
702
715
|
let i = String(t);
|
|
703
|
-
e instanceof HTMLElement &&
|
|
716
|
+
e instanceof HTMLElement && I(e) ? e.value = i : n && r === "string" && i.trim().startsWith("<") ? (e.innerHTML = d(i), this.#J(e), this.#E(e)) : n && (e.textContent = i);
|
|
704
717
|
}
|
|
705
718
|
#H(e, t) {
|
|
706
719
|
let n = this.#c.get(e);
|
|
@@ -725,7 +738,7 @@ var W = class e extends m {
|
|
|
725
738
|
}
|
|
726
739
|
let { properties: n, propToExprsMap: r } = e;
|
|
727
740
|
for (let [i, a] of Object.entries(n)) {
|
|
728
|
-
let n =
|
|
741
|
+
let n = U(a.usedBy);
|
|
729
742
|
if (!n) continue;
|
|
730
743
|
e.methodToExprsMap || t.call(this);
|
|
731
744
|
let { methodToExprsMap: o } = e, s = r.get(i);
|
|
@@ -826,7 +839,7 @@ var W = class e extends m {
|
|
|
826
839
|
}
|
|
827
840
|
}
|
|
828
841
|
};
|
|
829
|
-
function
|
|
842
|
+
function K(e, ...t) {
|
|
830
843
|
let n = N(e, t);
|
|
831
844
|
for (;;) {
|
|
832
845
|
let e = _.exec(n);
|
|
@@ -837,24 +850,24 @@ function G(e, ...t) {
|
|
|
837
850
|
if (!r.startsWith("--")) {
|
|
838
851
|
let i = `--${r}: ${t};
|
|
839
852
|
${r}: var(--${r})`;
|
|
840
|
-
n =
|
|
853
|
+
n = z(n, e.index, e[0].length, i);
|
|
841
854
|
}
|
|
842
855
|
}
|
|
843
856
|
}
|
|
844
857
|
return n;
|
|
845
858
|
}
|
|
846
|
-
function
|
|
859
|
+
function q(e, ...t) {
|
|
847
860
|
let n = N(e, t);
|
|
848
861
|
for (;;) {
|
|
849
862
|
let e = S.exec(n);
|
|
850
863
|
if (!e || e[1] === "style") break;
|
|
851
|
-
let t =
|
|
864
|
+
let t = R(e[2]);
|
|
852
865
|
if (T.test(t)) {
|
|
853
866
|
let r = `<!-- ${t.trim()} -->`, i = e.index + e[0].indexOf(">") + 1;
|
|
854
|
-
n =
|
|
867
|
+
n = z(n, i, t.length, r);
|
|
855
868
|
}
|
|
856
869
|
}
|
|
857
870
|
return n;
|
|
858
871
|
}
|
|
859
872
|
//#endregion
|
|
860
|
-
export { a,
|
|
873
|
+
export { a, q as i, O as n, K as r, G as t };
|
package/dist/wrec-ssr.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, i as t, n, r, t as i } from "./wrec-
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "./wrec-C03zEU8-.js";
|
|
2
2
|
//#region \0rolldown/runtime.js
|
|
3
3
|
var a = Object.defineProperty, o = Object.getOwnPropertyDescriptor, s = Object.getOwnPropertyNames, c = Object.prototype.hasOwnProperty, l = (e, t) => () => (e && (t = e(e = 0)), t), u = (e, t) => () => (t || e((t = { exports: {} }).exports, t), t.exports), d = (e, t) => {
|
|
4
4
|
let n = {};
|
package/dist/wrec.es.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, r, t as i } from "./wrec-
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "./wrec-C03zEU8-.js";
|
|
2
2
|
export { i as Wrec, e as WrecState, n as createElement, r as css, t as html };
|
package/package.json
CHANGED
package/scripts/lint.js
CHANGED
|
@@ -140,20 +140,20 @@ const SUPPORTED_EVENT_NAMES = new Set([
|
|
|
140
140
|
const WREC_REF_NAME = '__wrec';
|
|
141
141
|
const componentPropertyCache = new Map();
|
|
142
142
|
|
|
143
|
-
// Analyzes
|
|
143
|
+
// Analyzes code for invalid property access,
|
|
144
144
|
// method calls, and arithmetic usage.
|
|
145
|
-
function
|
|
146
|
-
|
|
145
|
+
function analyzeCodeNode(
|
|
146
|
+
codeNode,
|
|
147
147
|
checker,
|
|
148
148
|
classNode,
|
|
149
149
|
findings,
|
|
150
150
|
metadata
|
|
151
151
|
) {
|
|
152
|
-
if (metadata.eventHandler && ts.isIdentifier(
|
|
153
|
-
if (!metadata.classMethods.has(
|
|
152
|
+
if (metadata.eventHandler && ts.isIdentifier(codeNode)) {
|
|
153
|
+
if (!metadata.classMethods.has(codeNode.text)) {
|
|
154
154
|
uniquePush(
|
|
155
155
|
findings.invalidEventHandlers,
|
|
156
|
-
`"${
|
|
156
|
+
`"${codeNode.text}" is not a defined instance method`
|
|
157
157
|
);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
@@ -175,7 +175,7 @@ function analyzeExpression(
|
|
|
175
175
|
|
|
176
176
|
if (ts.isCallExpression(node)) {
|
|
177
177
|
const callee = node.expression;
|
|
178
|
-
if (ts.isIdentifier(callee)) {
|
|
178
|
+
if (metadata.checkContextCalls && ts.isIdentifier(callee)) {
|
|
179
179
|
if (!metadata.contextKeys.has(callee.text)) {
|
|
180
180
|
const symbol = checker.getSymbolAtLocation(callee);
|
|
181
181
|
if (!symbol || requiresContextFunction(symbol, metadata.sourceFile)) {
|
|
@@ -283,7 +283,7 @@ function analyzeExpression(
|
|
|
283
283
|
ts.forEachChild(node, visit);
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
visit(
|
|
286
|
+
visit(codeNode);
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
// Builds a temporary source string used only for type-checking
|
|
@@ -297,7 +297,7 @@ function buildAugmentedSource(
|
|
|
297
297
|
classNode,
|
|
298
298
|
supportedProps,
|
|
299
299
|
contextKeys,
|
|
300
|
-
|
|
300
|
+
codeItems
|
|
301
301
|
) {
|
|
302
302
|
const propLines = [];
|
|
303
303
|
for (const [name, info] of supportedProps.entries()) {
|
|
@@ -308,17 +308,21 @@ function buildAugmentedSource(
|
|
|
308
308
|
? `const {${contextKeys.join(', ')}} = ${classNode.name.text}.context;`
|
|
309
309
|
: '';
|
|
310
310
|
|
|
311
|
-
const helperBlocks =
|
|
311
|
+
const helperBlocks = codeItems.map((item, index) => {
|
|
312
312
|
const targetType =
|
|
313
|
-
|
|
313
|
+
item.context === 'static'
|
|
314
314
|
? `typeof ${classNode.name.text}`
|
|
315
315
|
: `${classNode.name.text} & __WrecSupportedProps`;
|
|
316
|
-
const rewrittenText =
|
|
316
|
+
const rewrittenText = item.text.replace(/\bthis\b/g, WREC_REF_NAME);
|
|
317
|
+
const helperBody =
|
|
318
|
+
item.shape === 'block'
|
|
319
|
+
? rewrittenText
|
|
320
|
+
: `return (${rewrittenText});`;
|
|
317
321
|
return `
|
|
318
322
|
function __wrec_expr_${index}() {
|
|
319
323
|
const ${WREC_REF_NAME} = null as unknown as ${targetType};
|
|
320
|
-
${
|
|
321
|
-
|
|
324
|
+
${item.checkContextCalls ? contextLine : ''}
|
|
325
|
+
${helperBody}
|
|
322
326
|
}
|
|
323
327
|
`;
|
|
324
328
|
});
|
|
@@ -350,15 +354,14 @@ function collectClassMethods(classNode) {
|
|
|
350
354
|
}
|
|
351
355
|
|
|
352
356
|
// Finds the synthetic `__wrec_expr_*` helper functions that were added by
|
|
353
|
-
// `buildAugmentedSource` and
|
|
354
|
-
// This gives the linter a stable list of typed
|
|
355
|
-
// that line up with the original
|
|
356
|
-
|
|
357
|
-
function collectHelperExpressions(augmentedSourceFile) {
|
|
357
|
+
// `buildAugmentedSource` and returns their bodies in index order.
|
|
358
|
+
// This gives the linter a stable list of typed code nodes
|
|
359
|
+
// that line up with the original extracted snippets for later analysis.
|
|
360
|
+
function collectHelperCodeNodes(augmentedSourceFile) {
|
|
358
361
|
const helpers = [];
|
|
359
362
|
|
|
360
363
|
// Finds generated helper functions and
|
|
361
|
-
// stores their
|
|
364
|
+
// stores their bodies by index.
|
|
362
365
|
function visit(node) {
|
|
363
366
|
if (
|
|
364
367
|
ts.isFunctionDeclaration(node) &&
|
|
@@ -366,12 +369,7 @@ function collectHelperExpressions(augmentedSourceFile) {
|
|
|
366
369
|
) {
|
|
367
370
|
const match = node.name.text.match(/(\d+)$/);
|
|
368
371
|
const index = match ? Number(match[1]) : -1;
|
|
369
|
-
if (index >= 0 && node.body)
|
|
370
|
-
const statement = node.body.statements.find(ts.isReturnStatement);
|
|
371
|
-
if (statement?.expression) {
|
|
372
|
-
helpers[index] = statement.expression;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
372
|
+
if (index >= 0 && node.body) helpers[index] = node.body;
|
|
375
373
|
}
|
|
376
374
|
ts.forEachChild(node, visit);
|
|
377
375
|
}
|
|
@@ -380,6 +378,37 @@ function collectHelperExpressions(augmentedSourceFile) {
|
|
|
380
378
|
return helpers;
|
|
381
379
|
}
|
|
382
380
|
|
|
381
|
+
// Collects analyzable code blocks from instance methods and accessors.
|
|
382
|
+
function collectMethodCodeItems(classNode) {
|
|
383
|
+
const codeItems = [];
|
|
384
|
+
|
|
385
|
+
for (const member of classNode.members) {
|
|
386
|
+
if (hasStaticModifier(member)) continue;
|
|
387
|
+
|
|
388
|
+
if (
|
|
389
|
+
ts.isMethodDeclaration(member) ||
|
|
390
|
+
ts.isGetAccessorDeclaration(member) ||
|
|
391
|
+
ts.isSetAccessorDeclaration(member)
|
|
392
|
+
) {
|
|
393
|
+
if (!member.body) continue;
|
|
394
|
+
if (!member.body.getText().includes('this.')) continue;
|
|
395
|
+
codeItems.push({
|
|
396
|
+
checkContextCalls: false,
|
|
397
|
+
context: 'instance',
|
|
398
|
+
eventHandler: false,
|
|
399
|
+
kind: 'method',
|
|
400
|
+
location: member.getSourceFile().getLineAndCharacterOfPosition(
|
|
401
|
+
member.name.getStart(member.getSourceFile())
|
|
402
|
+
),
|
|
403
|
+
shape: 'block',
|
|
404
|
+
text: member.body.getText()
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return codeItems;
|
|
410
|
+
}
|
|
411
|
+
|
|
383
412
|
// Collects the property names declared in
|
|
384
413
|
// a component's static properties object.
|
|
385
414
|
function collectSupportedPropertyNames(classNode) {
|
|
@@ -1291,7 +1320,13 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1291
1320
|
componentPropertyMaps,
|
|
1292
1321
|
supportedProps
|
|
1293
1322
|
);
|
|
1323
|
+
const methodCodeItems = collectMethodCodeItems(classNode);
|
|
1294
1324
|
const allExpressions = [...templateExprs, ...computedExprs];
|
|
1325
|
+
const allCodeItems = [...allExpressions, ...methodCodeItems].map(item => ({
|
|
1326
|
+
checkContextCalls: item.kind !== 'method',
|
|
1327
|
+
shape: 'shape' in item ? item.shape : 'expression',
|
|
1328
|
+
...item
|
|
1329
|
+
}));
|
|
1295
1330
|
|
|
1296
1331
|
if (allMethods.has('formAssociatedCallback') && !formAssociated) {
|
|
1297
1332
|
findings.missingFormAssociatedProperty.push(
|
|
@@ -1304,7 +1339,7 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1304
1339
|
classNode,
|
|
1305
1340
|
supportedProps,
|
|
1306
1341
|
contextKeys,
|
|
1307
|
-
|
|
1342
|
+
allCodeItems
|
|
1308
1343
|
);
|
|
1309
1344
|
const augmentedProgram = createProgram(filePath, augmentedSource);
|
|
1310
1345
|
const augmentedSourceFile = augmentedProgram.getSourceFile(filePath);
|
|
@@ -1316,7 +1351,7 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1316
1351
|
throw new Error('unable to find Wrec subclass after augmentation');
|
|
1317
1352
|
}
|
|
1318
1353
|
|
|
1319
|
-
const
|
|
1354
|
+
const helperCodeNodes = collectHelperCodeNodes(augmentedSourceFile);
|
|
1320
1355
|
|
|
1321
1356
|
validatePropertyConfigs(
|
|
1322
1357
|
checker,
|
|
@@ -1340,17 +1375,18 @@ export function lintSource(filePath, sourceText, options = {}) {
|
|
|
1340
1375
|
}
|
|
1341
1376
|
});
|
|
1342
1377
|
|
|
1343
|
-
|
|
1344
|
-
if (!
|
|
1345
|
-
|
|
1346
|
-
|
|
1378
|
+
helperCodeNodes.forEach((codeNode, index) => {
|
|
1379
|
+
if (!codeNode) return;
|
|
1380
|
+
analyzeCodeNode(
|
|
1381
|
+
codeNode,
|
|
1347
1382
|
augmentedChecker,
|
|
1348
1383
|
augmentedClassNode,
|
|
1349
1384
|
findings,
|
|
1350
1385
|
{
|
|
1351
1386
|
classMethods: allMethods,
|
|
1352
1387
|
contextKeys: new Set(contextKeys),
|
|
1353
|
-
|
|
1388
|
+
checkContextCalls: allCodeItems[index]?.checkContextCalls ?? true,
|
|
1389
|
+
eventHandler: allCodeItems[index]?.eventHandler ?? false,
|
|
1354
1390
|
sourceFile: augmentedSourceFile
|
|
1355
1391
|
}
|
|
1356
1392
|
);
|