diff --git a/crates/oxc_napi/src/error.rs b/crates/oxc_napi/src/error.rs index 15f4488043438..36ef38b2b05c0 100644 --- a/crates/oxc_napi/src/error.rs +++ b/crates/oxc_napi/src/error.rs @@ -4,7 +4,7 @@ use napi_derive::napi; use oxc_diagnostics::{LabeledSpan, NamedSource, OxcDiagnostic}; -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct OxcError { pub severity: Severity, pub message: String, @@ -64,7 +64,7 @@ impl From<&OxcDiagnostic> for OxcError { } } -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct ErrorLabel { pub message: Option, pub start: u32, diff --git a/napi/minify/index.d.ts b/napi/minify/index.d.ts index df84728e06231..d84dab2d9cc14 100644 --- a/napi/minify/index.d.ts +++ b/napi/minify/index.d.ts @@ -191,7 +191,7 @@ export interface Comment { } export interface ErrorLabel { - message?: string + message: string | null start: number end: number } @@ -200,8 +200,8 @@ export interface OxcError { severity: Severity message: string labels: Array - helpMessage?: string - codeframe?: string + helpMessage: string | null + codeframe: string | null } export declare const enum Severity { diff --git a/napi/parser/src-js/index.d.ts b/napi/parser/src-js/index.d.ts index f107d47119c84..2bef9bf1456ab 100644 --- a/napi/parser/src-js/index.d.ts +++ b/napi/parser/src-js/index.d.ts @@ -22,7 +22,7 @@ export interface Comment { } export interface ErrorLabel { - message?: string + message: string | null start: number end: number } @@ -31,8 +31,8 @@ export interface OxcError { severity: Severity message: string labels: Array - helpMessage?: string - codeframe?: string + helpMessage: string | null + codeframe: string | null } export declare const enum Severity { @@ -74,9 +74,9 @@ export interface EcmaScriptModule { export interface ExportExportName { kind: ExportExportNameKind - name?: string - start?: number - end?: number + name: string | null + start: number | null + end: number | null } export declare const enum ExportExportNameKind { @@ -90,9 +90,9 @@ export declare const enum ExportExportNameKind { export interface ExportImportName { kind: ExportImportNameKind - name?: string - start?: number - end?: number + name: string | null + start: number | null + end: number | null } export declare const enum ExportImportNameKind { @@ -108,9 +108,9 @@ export declare const enum ExportImportNameKind { export interface ExportLocalName { kind: ExportLocalNameKind - name?: string - start?: number - end?: number + name: string | null + start: number | null + end: number | null } export declare const enum ExportLocalNameKind { @@ -127,9 +127,9 @@ export declare const enum ExportLocalNameKind { export interface ImportName { kind: ImportNameKind - name?: string - start?: number - end?: number + name: string | null + start: number | null + end: number | null } export declare const enum ImportNameKind { @@ -229,7 +229,7 @@ export interface StaticExportEntry { * ``` */ isType: boolean - moduleRequest?: ValueSpan + moduleRequest: ValueSpan | null } export interface StaticImport { diff --git a/napi/parser/src/types.rs b/napi/parser/src/types.rs index c07c3d9941c94..bb9ea90ebd986 100644 --- a/napi/parser/src/types.rs +++ b/napi/parser/src/types.rs @@ -170,7 +170,7 @@ pub enum ImportNameKind { Default, } -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct ImportName { pub kind: ImportNameKind, pub name: Option, @@ -178,7 +178,7 @@ pub struct ImportName { pub end: Option, } -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct StaticExportEntry { pub start: u32, pub end: u32, @@ -222,7 +222,7 @@ pub enum ExportImportNameKind { None, } -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct ExportImportName { pub kind: ExportImportNameKind, pub name: Option, @@ -240,7 +240,7 @@ pub enum ExportExportNameKind { None, } -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct ExportExportName { pub kind: ExportExportNameKind, pub name: Option, @@ -248,7 +248,7 @@ pub struct ExportExportName { pub end: Option, } -#[napi(object)] +#[napi(object, use_nullable = true)] pub struct ExportLocalName { pub kind: ExportLocalNameKind, pub name: Option, diff --git a/napi/parser/test/__snapshots__/esm.test.ts.snap b/napi/parser/test/__snapshots__/esm.test.ts.snap index d6f606bb13efd..fac278d791165 100644 --- a/napi/parser/test/__snapshots__/esm.test.ts.snap +++ b/napi/parser/test/__snapshots__/esm.test.ts.snap @@ -13,7 +13,10 @@ exports[`esm > export * as name1 from "module-name"; 1`] = ` "start": 0, "end": 37, "importName": { - "kind": "All" + "kind": "All", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -22,7 +25,10 @@ exports[`esm > export * as name1 from "module-name"; 1`] = ` "end": 17 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -52,13 +58,22 @@ exports[`esm > export * from "module-name"; 1`] = ` "start": 0, "end": 28, "importName": { - "kind": "AllButDefault" + "kind": "AllButDefault", + "name": null, + "start": null, + "end": null }, "exportName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -100,7 +115,10 @@ exports[`esm > export { default as name1 } from "module-name"; 1`] = ` "end": 25 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -142,7 +160,10 @@ exports[`esm > export { default, /* …, */ } from "module-name"; 1`] = ` "end": 16 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -184,7 +205,10 @@ exports[`esm > export { import1 as name1, import2 as name2, /* …, */ nameN } f "end": 25 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -209,7 +233,10 @@ exports[`esm > export { import1 as name1, import2 as name2, /* …, */ nameN } f "end": 43 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -234,7 +261,10 @@ exports[`esm > export { import1 as name1, import2 as name2, /* …, */ nameN } f "end": 59 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -264,7 +294,10 @@ exports[`esm > export { name1 as default /*, … */ }; 1`] = ` "start": 9, "end": 25, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -278,7 +311,8 @@ exports[`esm > export { name1 as default /*, … */ }; 1`] = ` "start": 9, "end": 14 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -313,7 +347,10 @@ exports[`esm > export { name1, /* …, */ nameN } from "module-name"; 1`] = ` "end": 14 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -338,7 +375,10 @@ exports[`esm > export { name1, /* …, */ nameN } from "module-name"; 1`] = ` "end": 30 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "isType": false, "moduleRequest": { @@ -368,7 +408,10 @@ exports[`esm > export { name1, /* …, */ nameN }; 1`] = ` "start": 9, "end": 14, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -382,13 +425,17 @@ exports[`esm > export { name1, /* …, */ nameN }; 1`] = ` "start": 9, "end": 14 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 25, "end": 30, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -402,7 +449,8 @@ exports[`esm > export { name1, /* …, */ nameN }; 1`] = ` "start": 25, "end": 30 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -425,7 +473,10 @@ exports[`esm > export { variable1 as "string name" }; 1`] = ` "start": 9, "end": 35, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -439,7 +490,8 @@ exports[`esm > export { variable1 as "string name" }; 1`] = ` "start": 9, "end": 18 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -462,7 +514,10 @@ exports[`esm > export { variable1 as name1, variable2 as name2, /* …, */ nameN "start": 9, "end": 27, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -476,13 +531,17 @@ exports[`esm > export { variable1 as name1, variable2 as name2, /* …, */ nameN "start": 9, "end": 18 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 29, "end": 47, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -496,13 +555,17 @@ exports[`esm > export { variable1 as name1, variable2 as name2, /* …, */ nameN "start": 29, "end": 38 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 58, "end": 63, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -516,7 +579,8 @@ exports[`esm > export { variable1 as name1, variable2 as name2, /* …, */ nameN "start": 58, "end": 63 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -539,7 +603,10 @@ exports[`esm > export class ClassName { /* … */ } 1`] = ` "start": 7, "end": 34, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -553,7 +620,8 @@ exports[`esm > export class ClassName { /* … */ } 1`] = ` "start": 13, "end": 22 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -576,7 +644,10 @@ exports[`esm > export const [ name1, name2 ] = array; 1`] = ` "start": 7, "end": 38, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -590,13 +661,17 @@ exports[`esm > export const [ name1, name2 ] = array; 1`] = ` "start": 15, "end": 20 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 7, "end": 38, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -610,7 +685,8 @@ exports[`esm > export const [ name1, name2 ] = array; 1`] = ` "start": 22, "end": 27 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -633,7 +709,10 @@ exports[`esm > export const { name1, name2: bar } = o; 1`] = ` "start": 7, "end": 39, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -647,13 +726,17 @@ exports[`esm > export const { name1, name2: bar } = o; 1`] = ` "start": 15, "end": 20 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 7, "end": 39, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -667,7 +750,8 @@ exports[`esm > export const { name1, name2: bar } = o; 1`] = ` "start": 29, "end": 32 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -690,7 +774,10 @@ exports[`esm > export const name1 = 1, name2 = 2/*, … */; // also var, let 1`] "start": 7, "end": 42, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -704,13 +791,17 @@ exports[`esm > export const name1 = 1, name2 = 2/*, … */; // also var, let 1`] "start": 13, "end": 18 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 7, "end": 42, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -724,7 +815,8 @@ exports[`esm > export const name1 = 1, name2 = 2/*, … */; // also var, let 1`] "start": 24, "end": 29 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -747,17 +839,25 @@ exports[`esm > export default class { /* … */ } 1`] = ` "start": 15, "end": 32, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -780,10 +880,14 @@ exports[`esm > export default class ClassName { /* … */ } 1`] = ` "start": 15, "end": 42, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, @@ -793,7 +897,8 @@ exports[`esm > export default class ClassName { /* … */ } 1`] = ` "start": 21, "end": 30 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -816,10 +921,14 @@ exports[`esm > export default expression; 1`] = ` "start": 15, "end": 25, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, @@ -829,7 +938,8 @@ exports[`esm > export default expression; 1`] = ` "start": 15, "end": 25 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -852,17 +962,25 @@ exports[`esm > export default function () { /* … */ } 1`] = ` "start": 15, "end": 38, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -885,10 +1003,14 @@ exports[`esm > export default function functionName() { /* … */ } 1`] = ` "start": 15, "end": 50, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, @@ -898,7 +1020,8 @@ exports[`esm > export default function functionName() { /* … */ } 1`] = ` "start": 24, "end": 36 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -921,17 +1044,25 @@ exports[`esm > export default function* () { /* … */ } 1`] = ` "start": 15, "end": 39, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, "localName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -954,10 +1085,14 @@ exports[`esm > export default function* generatorFunctionName() { /* … */ } 1` "start": 15, "end": 60, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Default", + "name": null, "start": 7, "end": 14 }, @@ -967,7 +1102,8 @@ exports[`esm > export default function* generatorFunctionName() { /* … */ } 1` "start": 25, "end": 46 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -990,7 +1126,10 @@ exports[`esm > export function functionName() { /* … */ } 1`] = ` "start": 7, "end": 42, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -1004,7 +1143,8 @@ exports[`esm > export function functionName() { /* … */ } 1`] = ` "start": 16, "end": 28 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -1027,7 +1167,10 @@ exports[`esm > export function* generatorFunctionName() { /* … */ } 1`] = ` "start": 7, "end": 52, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -1041,7 +1184,8 @@ exports[`esm > export function* generatorFunctionName() { /* … */ } 1`] = ` "start": 17, "end": 38 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -1064,7 +1208,10 @@ exports[`esm > export let name1, name2/*, … */; // also var 1`] = ` "start": 7, "end": 32, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -1078,13 +1225,17 @@ exports[`esm > export let name1, name2/*, … */; // also var 1`] = ` "start": 11, "end": 16 }, - "isType": false + "isType": false, + "moduleRequest": null }, { "start": 7, "end": 32, "importName": { - "kind": "None" + "kind": "None", + "name": null, + "start": null, + "end": null }, "exportName": { "kind": "Name", @@ -1098,7 +1249,8 @@ exports[`esm > export let name1, name2/*, … */; // also var 1`] = ` "start": 18, "end": 23 }, - "isType": false + "isType": false, + "moduleRequest": null } ] } @@ -1144,7 +1296,10 @@ exports[`esm > import * as name from "module-name"; 1`] = ` "entries": [ { "importName": { - "kind": "NamespaceObject" + "kind": "NamespaceObject", + "name": null, + "start": null, + "end": null }, "localName": { "value": "name", @@ -1422,6 +1577,7 @@ exports[`esm > import defaultExport from "module-name"; 1`] = ` { "importName": { "kind": "Default", + "name": null, "start": 7, "end": 20 }, @@ -1457,6 +1613,7 @@ exports[`esm > import defaultExport, * as name from "module-name"; 1`] = ` { "importName": { "kind": "Default", + "name": null, "start": 7, "end": 20 }, @@ -1469,7 +1626,10 @@ exports[`esm > import defaultExport, * as name from "module-name"; 1`] = ` }, { "importName": { - "kind": "NamespaceObject" + "kind": "NamespaceObject", + "name": null, + "start": null, + "end": null }, "localName": { "value": "name", @@ -1503,6 +1663,7 @@ exports[`esm > import defaultExport, { export1, /* … */ } from "module-name"; { "importName": { "kind": "Default", + "name": null, "start": 7, "end": 20 }, diff --git a/napi/parser/test/parse-raw-worker.ts b/napi/parser/test/parse-raw-worker.ts index 22690fa74554b..0784fee0c660f 100644 --- a/napi/parser/test/parse-raw-worker.ts +++ b/napi/parser/test/parse-raw-worker.ts @@ -211,18 +211,7 @@ async function runTsCase( expect(oxcJson).toEqual(standardJson); - // Move `message` field to last in `ErrorLabel`s to match NAPI-RS, which puts optional fields last - for (const error of errors) { - for (const label of error.labels) { - if (hasOwn(label, "message")) { - const { message } = label; - delete label.message; - label.message = message; - } - } - } - - const errorsRawJson = JSON.stringify(removeNullProperties(errors), null, 2); + const errorsRawJson = JSON.stringify(errors, null, 2); const errorsStandardJson = JSON.stringify(errorsStandard, null, 2); expect(errorsRawJson).toEqual(errorsStandardJson); } @@ -361,10 +350,12 @@ function assertRawAndStandardMatch( const retRaw = parseSync(filename, sourceText, { experimentalRawTransfer: true, }); - const { program: programRaw, comments: commentsRaw } = retRaw; - // Remove `null` values, to match what NAPI-RS does - const moduleRaw = removeNullProperties(retRaw.module); - const errorsRaw = removeNullProperties(retRaw.errors); + const { + program: programRaw, + comments: commentsRaw, + module: moduleRaw, + errors: errorsRaw, + } = retRaw; // Compare as JSON (to ensure same field order) const jsonStandard = stringify( @@ -450,11 +441,6 @@ function stringifyAcornTest262Style(obj: any): string { return containsInfinity ? json.replace(INFINITY_REGEXP, "1e+400") : json; } -// Remove `null` values, to match what NAPI-RS does -function removeNullProperties(obj: any): any { - return JSON.parse(JSON.stringify(obj, (_key, value) => (value === null ? undefined : value))); -} - // Type for expect function interface ExpectFunction { (value: any): { diff --git a/napi/parser/test/parse.test.ts b/napi/parser/test/parse.test.ts index 54447980f52a2..79667ab1a7112 100644 --- a/napi/parser/test/parse.test.ts +++ b/napi/parser/test/parse.test.ts @@ -790,7 +790,10 @@ describe("UTF-16 span", () => { }, "isType": false, "localName": { + "end": null, "kind": "None", + "name": null, + "start": null, }, "moduleRequest": { "end": 22, @@ -811,6 +814,7 @@ describe("UTF-16 span", () => { "importName": { "end": 13, "kind": "Default", + "name": null, "start": 12, }, "isType": false, @@ -851,6 +855,7 @@ describe("UTF-16 span", () => { "labels": [ { "end": 9, + "message": null, "start": 9, }, ], @@ -873,8 +878,9 @@ describe("error", () => { helpMessage: "Try inserting a semicolon here", labels: [ { - end: 4, + message: null, start: 4, + end: 4, }, ], message: "Expected a semicolon or an implicit semicolon after a statement, but found none", diff --git a/napi/playground/index.d.ts b/napi/playground/index.d.ts index bea5fab2351dd..3d6632500f38b 100644 --- a/napi/playground/index.d.ts +++ b/napi/playground/index.d.ts @@ -8,7 +8,7 @@ export interface Comment { } export interface ErrorLabel { - message?: string + message: string | null start: number end: number } @@ -17,8 +17,8 @@ export interface OxcError { severity: Severity message: string labels: Array - helpMessage?: string - codeframe?: string + helpMessage: string | null + codeframe: string | null } export declare const enum Severity { diff --git a/napi/transform/index.d.ts b/napi/transform/index.d.ts index 79b47567f80a7..ba493e3fe3b40 100644 --- a/napi/transform/index.d.ts +++ b/napi/transform/index.d.ts @@ -8,7 +8,7 @@ export interface Comment { } export interface ErrorLabel { - message?: string + message: string | null start: number end: number } @@ -17,8 +17,8 @@ export interface OxcError { severity: Severity message: string labels: Array - helpMessage?: string - codeframe?: string + helpMessage: string | null + codeframe: string | null } export declare const enum Severity {