fix: parse JSX namespace identifiers that have numbers in them (#19912)

Co-authored-by: Michael H <git@riskymh.dev>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
This commit is contained in:
Varun Narravula
2025-05-27 22:45:11 +00:00
committed by GitHub
parent 44d04968cd
commit fc92921a4a
3 changed files with 58 additions and 1 deletions

View File

@@ -2335,7 +2335,7 @@ fn NewLexer_(
lexer.step();
if (isIdentifierStart(lexer.code_point)) {
while (isIdentifierStart(lexer.code_point) or lexer.code_point == '-') {
while (isIdentifierContinue(lexer.code_point) or lexer.code_point == '-') {
lexer.step();
}
} else {

View File

@@ -0,0 +1,10 @@
import { expect, it } from "bun:test";
import { nsExample1, nsExample2, nsExample3, nsExample4 } from "../../snippets/jsx-attributes.tsx";
it("parses namespaced attributes correctly", () => {
expect(nsExample1.props).toEqual({ "ns:bar": "baz", "tag": true });
expect(nsExample2.props).toEqual({ "ns:bar42": "baz", "tag": false });
expect(nsExample3.props).toEqual({ "ns:bar42bar": "baz" });
expect(nsExample4.props).toEqual({ "ns42:bar": "baz" });
});

View File

@@ -0,0 +1,47 @@
// @ts-nocheck
// Declare a minimally reproducible JSX namespace for testing;
// ensures that no dependencies are required for this test.
export interface JSXIntrinsicElements {
"ns:foo": {
"tag"?: boolean;
"ns:bar"?: string;
"ns:bar42"?: string;
"ns:bar42bar"?: string;
"ns42:bar"?: string;
};
}
// Minimal JSX element implementation.
export class Element<T, P, C> {
constructor(
public readonly tag: T,
public readonly props: P,
public readonly children: C,
) { }
}
export interface JsxElement extends Element<unknown, unknown, unknown> { }
// JSX factory function used when compiling JSX with `jsx` pragma.
// This is what the JSX transpiles to.
export function jsx<T, P, C extends unknown[]>(
tag: T,
props: P,
...children: C
) {
return new Element(tag, props, children);
}
// Define the JSX namespace itself so TypeScript can resolve JSX
// types correctly.
export namespace jsx.JSX {
export interface Element extends JsxElement { }
export type IntrinsicElements = JSXIntrinsicElements;
}
// Examples of namespaced JSX attributes
export const nsExample1 = <ns:foo tag ns:bar="baz" />;
export const nsExample2 = <ns:foo tag={false} ns:bar42="baz" />;
export const nsExample3 = <ns:foo ns:bar42bar="baz" />;
export const nsExample4 = <ns:foo ns42:bar="baz" />;