Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/generated/ast_changes_watch_list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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'
Expand Down
19 changes: 14 additions & 5 deletions apps/oxlint/scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -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...');
Expand All @@ -20,25 +19,35 @@ 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',
];

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...');
Expand Down
172 changes: 172 additions & 0 deletions apps/oxlint/src-js/generated/keys.js
Original file line number Diff line number Diff line change
@@ -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'],
});
4 changes: 2 additions & 2 deletions apps/oxlint/src-js/plugins/source_code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
},

Expand Down
6 changes: 5 additions & 1 deletion tasks/ast_tools/src/generators/estree_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand All @@ -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,
Expand Down
29 changes: 12 additions & 17 deletions tasks/ast_tools/src/generators/raw_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>();

outputs.extend([
Expand Down Expand Up @@ -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"];

Expand Down Expand Up @@ -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<String>,
variant_paths: Vec<String>,
}

impl VariantGenerator<5> for VariantGen {
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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.
Expand Down
Loading