diff --git a/.github/generated/ast_changes_watch_list.yml b/.github/generated/ast_changes_watch_list.yml index 3649cc6d7cac3..994b27b580b47 100644 --- a/.github/generated/ast_changes_watch_list.yml +++ b/.github/generated/ast_changes_watch_list.yml @@ -4,6 +4,8 @@ src: - '.github/generated/ast_changes_watch_list.yml' - 'apps/oxlint/src-js/generated/constants.js' + - 'apps/oxlint/src-js/generated/deserialize.js' + - 'apps/oxlint/src-js/generated/keys.js' - 'apps/oxlint/src-js/generated/types.d.ts' - 'apps/oxlint/src-js/generated/types.js' - 'apps/oxlint/src-js/generated/visitor.d.ts' @@ -78,7 +80,6 @@ src: - 'napi/parser/generated/deserialize/ts.js' - 'napi/parser/generated/deserialize/ts_parent.js' - 'napi/parser/generated/deserialize/ts_range.js' - - 'napi/parser/generated/deserialize/ts_range_loc_parent_no_parens.js' - 'napi/parser/generated/deserialize/ts_range_parent.js' - 'napi/parser/generated/lazy/constructors.js' - 'napi/parser/generated/lazy/types.js' diff --git a/apps/oxlint/scripts/build.js b/apps/oxlint/scripts/build.js index 3425d489b3d65..7fabe118a3edc 100755 --- a/apps/oxlint/scripts/build.js +++ b/apps/oxlint/scripts/build.js @@ -3,8 +3,7 @@ import { copyFileSync, mkdirSync, readdirSync, readFileSync, writeFileSync } fro import { join } from 'node:path'; const oxlintDirPath = join(import.meta.dirname, '..'), - distDirPath = join(oxlintDirPath, 'dist'), - parserDirPath = join(oxlintDirPath, '../../napi/parser'); + distDirPath = join(oxlintDirPath, 'dist'); // Modify `bindings.js` to use correct package names console.log('Modifying bindings.js...'); @@ -20,18 +19,19 @@ writeFileSync(bindingsPath, bindingsJs); console.log('Building with tsdown...'); execSync('pnpm tsdown', { stdio: 'inherit', cwd: oxlintDirPath }); +// Lazy implementation +/* // Copy files from `napi/parser` to `apps/oxlint/dist` console.log('Copying files from parser...'); +const parserDirPath = join(oxlintDirPath, '../../napi/parser'); + const parserFilePaths = [ - // Lazy implementation - /* 'src-js/raw-transfer/lazy-common.js', 'src-js/raw-transfer/node-array.js', 'generated/lazy/constructors.js', 'generated/lazy/types.js', 'generated/lazy/walk.js', - */ 'generated/deserialize/ts_range_loc_parent_no_parens.js', 'generated/visit/keys.js', ]; @@ -39,6 +39,15 @@ const parserFilePaths = [ for (const parserFilePath of parserFilePaths) { copyFile(join(parserDirPath, parserFilePath), join(distDirPath, parserFilePath)); } +*/ + +// Copy files from `src-js/generated` to `dist/generated` +console.log('Copying generated files...'); + +const generatedFilePaths = ['deserialize.js', 'keys.js']; +for (const filePath of generatedFilePaths) { + copyFile(join(oxlintDirPath, 'src-js/generated', filePath), join(distDirPath, 'generated', filePath)); +} // Copy native `.node` files from `src-js` console.log('Copying `.node` files...'); diff --git a/napi/parser/generated/deserialize/ts_range_loc_parent_no_parens.js b/apps/oxlint/src-js/generated/deserialize.js similarity index 100% rename from napi/parser/generated/deserialize/ts_range_loc_parent_no_parens.js rename to apps/oxlint/src-js/generated/deserialize.js diff --git a/apps/oxlint/src-js/generated/keys.js b/apps/oxlint/src-js/generated/keys.js new file mode 100644 index 0000000000000..50259c1aa5b93 --- /dev/null +++ b/apps/oxlint/src-js/generated/keys.js @@ -0,0 +1,172 @@ +// Auto-generated code, DO NOT EDIT DIRECTLY! +// To edit this generated file you have to edit `tasks/ast_tools/src/generators/estree_visit.rs`. + +export default Object.freeze({ + // Leaf nodes + DebuggerStatement: [], + EmptyStatement: [], + Literal: [], + PrivateIdentifier: [], + Super: [], + TemplateElement: [], + ThisExpression: [], + JSXClosingFragment: [], + JSXEmptyExpression: [], + JSXIdentifier: [], + JSXOpeningFragment: [], + JSXText: [], + TSAnyKeyword: [], + TSBigIntKeyword: [], + TSBooleanKeyword: [], + TSIntrinsicKeyword: [], + TSJSDocUnknownType: [], + TSNeverKeyword: [], + TSNullKeyword: [], + TSNumberKeyword: [], + TSObjectKeyword: [], + TSStringKeyword: [], + TSSymbolKeyword: [], + TSThisType: [], + TSUndefinedKeyword: [], + TSUnknownKeyword: [], + TSVoidKeyword: [], + // Non-leaf nodes + AccessorProperty: ['decorators', 'key', 'typeAnnotation', 'value'], + ArrayExpression: ['elements'], + ArrayPattern: ['decorators', 'elements', 'typeAnnotation'], + ArrowFunctionExpression: ['typeParameters', 'params', 'returnType', 'body'], + AssignmentExpression: ['left', 'right'], + AssignmentPattern: ['decorators', 'left', 'right', 'typeAnnotation'], + AwaitExpression: ['argument'], + BinaryExpression: ['left', 'right'], + BlockStatement: ['body'], + BreakStatement: ['label'], + CallExpression: ['callee', 'typeArguments', 'arguments'], + CatchClause: ['param', 'body'], + ChainExpression: ['expression'], + ClassBody: ['body'], + ClassDeclaration: ['decorators', 'id', 'typeParameters', 'superClass', 'superTypeArguments', 'implements', 'body'], + ClassExpression: ['decorators', 'id', 'typeParameters', 'superClass', 'superTypeArguments', 'implements', 'body'], + ConditionalExpression: ['test', 'consequent', 'alternate'], + ContinueStatement: ['label'], + Decorator: ['expression'], + DoWhileStatement: ['body', 'test'], + ExportAllDeclaration: ['exported', 'source', 'attributes'], + ExportDefaultDeclaration: ['declaration'], + ExportNamedDeclaration: ['declaration', 'specifiers', 'source', 'attributes'], + ExportSpecifier: ['local', 'exported'], + ExpressionStatement: ['expression'], + ForInStatement: ['left', 'right', 'body'], + ForOfStatement: ['left', 'right', 'body'], + ForStatement: ['init', 'test', 'update', 'body'], + FunctionDeclaration: ['id', 'typeParameters', 'params', 'returnType', 'body'], + FunctionExpression: ['id', 'typeParameters', 'params', 'returnType', 'body'], + Identifier: ['decorators', 'typeAnnotation'], + IfStatement: ['test', 'consequent', 'alternate'], + ImportAttribute: ['key', 'value'], + ImportDeclaration: ['specifiers', 'source', 'attributes'], + ImportDefaultSpecifier: ['local'], + ImportExpression: ['source', 'options'], + ImportNamespaceSpecifier: ['local'], + ImportSpecifier: ['imported', 'local'], + LabeledStatement: ['label', 'body'], + LogicalExpression: ['left', 'right'], + MemberExpression: ['object', 'property'], + MetaProperty: ['meta', 'property'], + MethodDefinition: ['decorators', 'key', 'value'], + NewExpression: ['callee', 'typeArguments', 'arguments'], + ObjectExpression: ['properties'], + ObjectPattern: ['decorators', 'properties', 'typeAnnotation'], + ParenthesizedExpression: ['expression'], + Program: ['body'], + Property: ['key', 'value'], + PropertyDefinition: ['decorators', 'key', 'typeAnnotation', 'value'], + RestElement: ['decorators', 'argument', 'typeAnnotation'], + ReturnStatement: ['argument'], + SequenceExpression: ['expressions'], + SpreadElement: ['argument'], + StaticBlock: ['body'], + SwitchCase: ['test', 'consequent'], + SwitchStatement: ['discriminant', 'cases'], + TaggedTemplateExpression: ['tag', 'typeArguments', 'quasi'], + TemplateLiteral: ['quasis', 'expressions'], + ThrowStatement: ['argument'], + TryStatement: ['block', 'handler', 'finalizer'], + UnaryExpression: ['argument'], + UpdateExpression: ['argument'], + V8IntrinsicExpression: ['name', 'arguments'], + VariableDeclaration: ['declarations'], + VariableDeclarator: ['id', 'init'], + WhileStatement: ['test', 'body'], + WithStatement: ['object', 'body'], + YieldExpression: ['argument'], + JSXAttribute: ['name', 'value'], + JSXClosingElement: ['name'], + JSXElement: ['openingElement', 'children', 'closingElement'], + JSXExpressionContainer: ['expression'], + JSXFragment: ['openingFragment', 'children', 'closingFragment'], + JSXMemberExpression: ['object', 'property'], + JSXNamespacedName: ['namespace', 'name'], + JSXOpeningElement: ['name', 'typeArguments', 'attributes'], + JSXSpreadAttribute: ['argument'], + JSXSpreadChild: ['expression'], + TSAbstractAccessorProperty: ['decorators', 'key', 'typeAnnotation'], + TSAbstractMethodDefinition: ['key', 'value'], + TSAbstractPropertyDefinition: ['decorators', 'key', 'typeAnnotation'], + TSArrayType: ['elementType'], + TSAsExpression: ['expression', 'typeAnnotation'], + TSCallSignatureDeclaration: ['typeParameters', 'params', 'returnType'], + TSClassImplements: ['expression', 'typeArguments'], + TSConditionalType: ['checkType', 'extendsType', 'trueType', 'falseType'], + TSConstructSignatureDeclaration: ['typeParameters', 'params', 'returnType'], + TSConstructorType: ['typeParameters', 'params', 'returnType'], + TSDeclareFunction: ['id', 'typeParameters', 'params', 'returnType', 'body'], + TSEmptyBodyFunctionExpression: ['id', 'typeParameters', 'params', 'returnType'], + TSEnumBody: ['members'], + TSEnumDeclaration: ['id', 'body'], + TSEnumMember: ['id', 'initializer'], + TSExportAssignment: ['expression'], + TSExternalModuleReference: ['expression'], + TSFunctionType: ['typeParameters', 'params', 'returnType'], + TSImportEqualsDeclaration: ['id', 'moduleReference'], + TSImportType: ['argument', 'options', 'qualifier', 'typeArguments'], + TSIndexSignature: ['parameters', 'typeAnnotation'], + TSIndexedAccessType: ['objectType', 'indexType'], + TSInferType: ['typeParameter'], + TSInstantiationExpression: ['expression', 'typeArguments'], + TSInterfaceBody: ['body'], + TSInterfaceDeclaration: ['id', 'typeParameters', 'extends', 'body'], + TSInterfaceHeritage: ['expression', 'typeArguments'], + TSIntersectionType: ['types'], + TSJSDocNonNullableType: ['typeAnnotation'], + TSJSDocNullableType: ['typeAnnotation'], + TSLiteralType: ['literal'], + TSMappedType: ['key', 'constraint', 'nameType', 'typeAnnotation'], + TSMethodSignature: ['key', 'typeParameters', 'params', 'returnType'], + TSModuleBlock: ['body'], + TSModuleDeclaration: ['id', 'body'], + TSNamedTupleMember: ['label', 'elementType'], + TSNamespaceExportDeclaration: ['id'], + TSNonNullExpression: ['expression'], + TSOptionalType: ['typeAnnotation'], + TSParameterProperty: ['decorators', 'parameter'], + TSParenthesizedType: ['typeAnnotation'], + TSPropertySignature: ['key', 'typeAnnotation'], + TSQualifiedName: ['left', 'right'], + TSRestType: ['typeAnnotation'], + TSSatisfiesExpression: ['expression', 'typeAnnotation'], + TSTemplateLiteralType: ['quasis', 'types'], + TSTupleType: ['elementTypes'], + TSTypeAliasDeclaration: ['id', 'typeParameters', 'typeAnnotation'], + TSTypeAnnotation: ['typeAnnotation'], + TSTypeAssertion: ['typeAnnotation', 'expression'], + TSTypeLiteral: ['members'], + TSTypeOperator: ['typeAnnotation'], + TSTypeParameter: ['name', 'constraint', 'default'], + TSTypeParameterDeclaration: ['params'], + TSTypeParameterInstantiation: ['params'], + TSTypePredicate: ['parameterName', 'typeAnnotation'], + TSTypeQuery: ['exprName', 'typeArguments'], + TSTypeReference: ['typeName', 'typeArguments'], + TSUnionType: ['types'], +}); diff --git a/apps/oxlint/src-js/plugins/source_code.ts b/apps/oxlint/src-js/plugins/source_code.ts index aca8274ff2e50..1001f8f8c9e94 100644 --- a/apps/oxlint/src-js/plugins/source_code.ts +++ b/apps/oxlint/src-js/plugins/source_code.ts @@ -8,7 +8,7 @@ import { // @ts-expect-error we need to generate `.d.ts` file for this module // We use the deserializer which removes `ParenthesizedExpression`s from AST, // and with `range`, `loc`, and `parent` properties on AST nodes, to match ESLint -import { deserializeProgramOnly } from '../../dist/generated/deserialize/ts_range_loc_parent_no_parens.js'; +import { deserializeProgramOnly } from '../../dist/generated/deserialize.js'; import { getLineColumnFromOffset, @@ -125,7 +125,7 @@ export const SOURCE_CODE = Object.freeze({ // Get visitor keys to traverse this AST. get visitorKeys(): { [key: string]: string[] } { // This is the path relative to `plugins.js` file in `dist` directory - if (visitorKeys === null) visitorKeys = require('./generated/visit/keys.js').default; + if (visitorKeys === null) visitorKeys = require('./generated/keys.js').default; return visitorKeys; }, diff --git a/tasks/ast_tools/src/generators/estree_visit.rs b/tasks/ast_tools/src/generators/estree_visit.rs index ee274dfd62279..54c20d72ad213 100644 --- a/tasks/ast_tools/src/generators/estree_visit.rs +++ b/tasks/ast_tools/src/generators/estree_visit.rs @@ -55,7 +55,7 @@ impl Generator for ESTreeVisitGenerator { }, Output::Javascript { path: format!("{NAPI_PARSER_PACKAGE_PATH}/generated/visit/keys.js"), - code: visitor_keys, + code: visitor_keys.clone(), }, Output::Javascript { path: format!("{NAPI_PARSER_PACKAGE_PATH}/generated/visit/types.js"), @@ -69,6 +69,10 @@ impl Generator for ESTreeVisitGenerator { path: format!("{OXLINT_APP_PATH}/src-js/generated/walk.js"), code: walk, }, + Output::Javascript { + path: format!("{OXLINT_APP_PATH}/src-js/generated/keys.js"), + code: visitor_keys, + }, Output::Javascript { path: format!("{OXLINT_APP_PATH}/src-js/generated/types.js"), code: type_ids_map, diff --git a/tasks/ast_tools/src/generators/raw_transfer.rs b/tasks/ast_tools/src/generators/raw_transfer.rs index fdd949b9887a0..b8e37d5e6717e 100644 --- a/tasks/ast_tools/src/generators/raw_transfer.rs +++ b/tasks/ast_tools/src/generators/raw_transfer.rs @@ -77,10 +77,7 @@ impl Generator for RawTransferGenerator { let mut outputs = deserializers .into_iter() - .map(|(name, code)| Output::Javascript { - path: format!("{NAPI_PARSER_PACKAGE_PATH}/generated/deserialize/{name}.js"), - code, - }) + .map(|(path, code)| Output::Javascript { path, code }) .collect::>(); outputs.extend([ @@ -127,7 +124,7 @@ fn generate_deserializers( consts: Constants, schema: &Schema, codegen: &Codegen, -) -> Vec<(/* name */ String, /* code */ String)> { +) -> Vec<(/* path */ String, /* code */ String)> { let estree_derive_id = codegen.get_derive_id_by_name("ESTree"); let span_type_id = schema.type_names["Span"]; @@ -206,7 +203,7 @@ fn generate_deserializers( // Create deserializers with various settings, by setting `IS_TS`, `RANGE`, `LOC`, `PARENT` // and `PRESERVE_PARENS` consts, and running through minifier to shake out irrelevant code struct VariantGen { - variant_names: Vec, + variant_paths: Vec, } impl VariantGenerator<5> for VariantGen { @@ -218,14 +215,12 @@ fn generate_deserializers( for is_ts in [false, true] { for range in [false, true] { for parent in [false, true] { - let mut name = if is_ts { "ts" } else { "js" }.to_string(); - if range { - name.push_str("_range"); - } - if parent { - name.push_str("_parent"); - } - self.variant_names.push(name); + self.variant_paths.push(format!( + "{NAPI_PARSER_PACKAGE_PATH}/generated/deserialize/{}{}{}.js", + if is_ts { "ts" } else { "js" }, + if range { "_range" } else { "" }, + if parent { "_parent" } else { "" }, + )); variants.push([ is_ts, range, /* loc */ false, parent, @@ -235,7 +230,7 @@ fn generate_deserializers( } } - self.variant_names.push("ts_range_loc_parent_no_parens".to_string()); + self.variant_paths.push(format!("{OXLINT_APP_PATH}/src-js/generated/deserialize.js")); variants.push([ /* is_ts */ true, /* range */ true, /* loc */ true, /* parent */ true, /* preserve_parens */ false, @@ -257,10 +252,10 @@ fn generate_deserializers( } } - let mut generator = VariantGen { variant_names: vec![] }; + let mut generator = VariantGen { variant_paths: vec![] }; let codes = generator.generate(&code); - generator.variant_names.into_iter().zip(codes).collect() + generator.variant_paths.into_iter().zip(codes).collect() } /// Type of deserializer in which some code appears.