Compare commits

...

3 Commits

Author SHA1 Message Date
autofix-ci[bot]
e8285c8015 [autofix.ci] apply automated fixes 2025-08-29 06:53:07 +00:00
Claude Bot
4497265e34 fix: add missing $ and _ characters to identifier tables
The previous fix for middle dot characters accidentally broke $ and _
character parsing in JavaScript identifiers. These characters are
special cases in ECMAScript that must be explicitly added to the
ID_Start and ID_Continue sets, as they are not included in the
standard Unicode categories.

This restores support for:
- $ in destructuring: import { $ } from "bun"
- _ in variable names: const _private = 123
- All other $ and _ usage in identifiers

While maintaining the fix for Japanese middle dot characters.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 06:49:58 +00:00
Claude Bot
98311300a3 fix: allow Japanese middle dot characters in JavaScript identifiers
This fixes an issue where Japanese middle dot characters (U+30FB "・" and
U+FF65 "・") were incorrectly excluded from identifier continuation characters.
These characters are valid in ECMAScript identifiers and are commonly used
in Japanese text, particularly in real estate property names like "バス・トイレ".

Changes:
- Remove incorrect exclusion of middle dot characters from Unicode tables
- Regenerate identifier lookup tables with correct Unicode data
- Add regression test to prevent future issues
- Maintain correct behavior: middle dots can only continue identifiers, not start them

Fixes https://github.com/oven-sh/bun/discussions/22230

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-29 06:39:48 +00:00
3 changed files with 68 additions and 24 deletions

View File

@@ -20,8 +20,9 @@ const idContinueES5Set = new Set([
const idStartESNextSet = new Set(require("@unicode/unicode-15.1.0/Binary_Property/ID_Start/code-points"));
const idContinueESNextSet = new Set(require("@unicode/unicode-15.1.0/Binary_Property/ID_Continue/code-points"));
// Exclude known problematic codepoints
const ID_Continue_mistake = new Set([0x30fb, 0xff65]);
// Note: Previously excluded middle dot characters (0x30fb, 0xff65) but these are valid
// in Node.js and ECMAScript specification, so they should be included
const ID_Continue_mistake = new Set();
function bitsToU64Array(bits: number[]): bigint[] {
const result: bigint[] = [];
@@ -82,12 +83,12 @@ async function main() {
{
name: "isIDStartESNext",
table: "idStartESNext",
check: (cp: number) => idStartESNextSet.has(cp),
check: (cp: number) => idStartESNextSet.has(cp) || cp === 0x24 || cp === 0x5F, // Add $ and _
},
{
name: "isIDContinueESNext",
table: "idContinueESNext",
check: (cp: number) => idContinueESNextSet.has(cp) && !ID_Continue_mistake.has(cp),
check: (cp: number) => (idContinueESNextSet.has(cp) && !ID_Continue_mistake.has(cp)) || cp === 0x24 || cp === 0x5F, // Add $ and _
},
];

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,50 @@
import { expect, test } from "bun:test";
test("Japanese middle dot character should be allowed in identifier names", () => {
// Test the full-width middle dot (・) character U+30FB
const code1 = `
const obj = {
"バス・トイレ": "bathroom"
};
obj["バス・トイレ"];
`;
expect(() => eval(code1)).not.toThrow();
// Test unquoted property with middle dot
const code2 = `
const obj = {
バス・トイレ: "bathroom"
};
obj["バス・トイレ"];
`;
expect(() => eval(code2)).not.toThrow();
// Test variable name with middle dot continuation
const code3 = `
let test・variable = 42;
test・variable;
`;
expect(() => eval(code3)).not.toThrow();
// Test the half-width middle dot (・) character U+FF65 as well
const code4 = `
const obj = {
test・value: "test"
};
obj["test・value"];
`;
expect(() => eval(code4)).not.toThrow();
});
test("Middle dot should not be allowed at start of identifier", () => {
// Middle dot should NOT be allowed as identifier start
const code1 = `
var ・test = 1;
`;
expect(() => eval(code1)).toThrow();
const code2 = `
var ・test = 1;
`;
expect(() => eval(code2)).toThrow();
});