@tsrx/core 0.1.24 → 0.1.25
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/package.json +1 -1
- package/src/plugin.js +42 -1
- package/src/transform/jsx/index.js +730 -1850
- package/types/index.d.ts +0 -2
- package/types/jsx-platform.d.ts +3 -8
package/package.json
CHANGED
package/src/plugin.js
CHANGED
|
@@ -4232,7 +4232,36 @@ export function TSRXPlugin(config) {
|
|
|
4232
4232
|
body.push(text);
|
|
4233
4233
|
}
|
|
4234
4234
|
} else if (this.#isJSXControlFlowDirectiveStart()) {
|
|
4235
|
-
|
|
4235
|
+
const directive = this.#parseJSXControlFlowExpression();
|
|
4236
|
+
body.push(directive);
|
|
4237
|
+
// `#parseTemplateControlFlowBlock` reads the token after the block's
|
|
4238
|
+
// closing `}` in a code (b_stat) context, which runs `skipSpace()` and
|
|
4239
|
+
// advances `start` past any whitespace. The following token is therefore a
|
|
4240
|
+
// JS token (e.g. the `else` keyword), and when it is actually sibling
|
|
4241
|
+
// template raw text it reaches `#parseTemplateRawText` having lost the
|
|
4242
|
+
// space(s) between `}` and the text (e.g. `@if (x) { … } else` -> the text
|
|
4243
|
+
// "else" instead of " else"). JSX text after a plain element keeps that
|
|
4244
|
+
// whitespace, so when raw text follows and only whitespace was skipped,
|
|
4245
|
+
// rewind `start` to the block's end to re-include the dropped whitespace.
|
|
4246
|
+
const blockEnd = directive.end;
|
|
4247
|
+
const nextCh = this.input.charCodeAt(this.start);
|
|
4248
|
+
const startsRawText =
|
|
4249
|
+
this.type !== tt.eof &&
|
|
4250
|
+
nextCh !== CharCode.lessThan &&
|
|
4251
|
+
nextCh !== CharCode.openBrace &&
|
|
4252
|
+
nextCh !== CharCode.closeBrace &&
|
|
4253
|
+
!this.#isJSXControlFlowDirectiveStart();
|
|
4254
|
+
if (
|
|
4255
|
+
startsRawText &&
|
|
4256
|
+
typeof blockEnd === 'number' &&
|
|
4257
|
+
this.start > blockEnd &&
|
|
4258
|
+
/^\s*$/.test(this.input.slice(blockEnd, this.start))
|
|
4259
|
+
) {
|
|
4260
|
+
const loc = acorn.getLineInfo(this.input, blockEnd);
|
|
4261
|
+
this.pos = blockEnd;
|
|
4262
|
+
this.start = blockEnd;
|
|
4263
|
+
this.startLoc = new acorn.Position(loc.line, loc.column);
|
|
4264
|
+
}
|
|
4236
4265
|
} else if (this.type === tt.braceR) {
|
|
4237
4266
|
// Leaving a native template body. We may still be in TSX/JSX tokenization
|
|
4238
4267
|
// context (e.g. after parsing markup), but the closing `}` is a JS token.
|
|
@@ -4259,6 +4288,18 @@ export function TSRXPlugin(config) {
|
|
|
4259
4288
|
this.start = startPos;
|
|
4260
4289
|
this.startLoc = startLoc;
|
|
4261
4290
|
this.exprAllowed = false;
|
|
4291
|
+
// A genuine `jsxTagStart` pushes `tc_expr` + `tc_oTag` in its
|
|
4292
|
+
// `updateContext`; faking the token here skips those pushes. That is
|
|
4293
|
+
// harmless for an opening tag (the next token is the tag name), but a
|
|
4294
|
+
// closing tag (`</`) immediately runs `context.length -= 2` in the
|
|
4295
|
+
// slash `updateContext`, which would underflow the context stack and
|
|
4296
|
+
// throw "Invalid array length" (e.g. `<>@if (a) { … } done</>`). Push
|
|
4297
|
+
// the two contexts a real `jsxTagStart` would have added so the closing
|
|
4298
|
+
// tag pops its own contexts instead of the enclosing template's.
|
|
4299
|
+
if (this.input.charCodeAt(this.pos) === CharCode.slash) {
|
|
4300
|
+
this.context.push(tstc.tc_expr);
|
|
4301
|
+
this.context.push(tstc.tc_oTag);
|
|
4302
|
+
}
|
|
4262
4303
|
this.next();
|
|
4263
4304
|
}
|
|
4264
4305
|
if (this.value === '/' || this.type === tt.slash) {
|