-
-
Notifications
You must be signed in to change notification settings - Fork 688
feat: parse parameter decorators for transforms #3001
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2173a84
9cf0769
cac365b
1103856
0d59a95
4786023
bd029c6
2b84dc5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,274 @@ | ||
| /* global module */ | ||
|
|
||
| module.exports = { | ||
| root: true, | ||
| ignorePatterns: [ | ||
| // These fixtures intentionally exercise AssemblyScript-only syntax that | ||
| // TypeScript's parser rejects before lint rules can run. | ||
| "tests/compiler/parameter-decorators.ts", | ||
| "tests/transform/parameter-decorators.ts" | ||
| ], | ||
| parser: "@typescript-eslint/parser", | ||
| plugins: [ | ||
| "@typescript-eslint", | ||
| ], | ||
| extends: [ | ||
| "eslint:recommended", | ||
| "plugin:@typescript-eslint/eslint-recommended", | ||
| "plugin:@typescript-eslint/recommended", | ||
| ], | ||
| parserOptions: { | ||
| ecmaVersion: 2020, | ||
| sourceType: "module", | ||
| ecmaFeatures: {} | ||
| }, | ||
| globals: { | ||
| "globalThis": "readonly", | ||
| "BigInt64Array": "readonly", | ||
| "BigUint64Array": "readonly", | ||
| "WebAssembly": "readonly", | ||
| "FinalizationRegistry": "readonly", | ||
| "fetch": "readonly", | ||
| "URL": "readonly", | ||
| "console": "readonly" | ||
| }, | ||
|
|
||
| // === General rules ========================================================= | ||
|
|
||
| rules: { | ||
| // Omitted semicolons are hugely popular, yet within the compiler it makes | ||
| // sense to be better safe than sorry. | ||
| "semi": "error", | ||
|
|
||
| // Our code bases uses 2 spaces for indentation, and we enforce it here so | ||
| // files don't mix spaces, tabs or different indentation levels. | ||
| "indent": ["error", 2, { | ||
| "SwitchCase": 1, | ||
| "VariableDeclarator": "first", | ||
| "offsetTernaryExpressions": true, | ||
| "ignoredNodes": [ // FIXME: something's odd here | ||
| "ConditionalExpression > *", | ||
| "ConditionalExpression > * > *", | ||
| "ConditionalExpression > * > * > *" | ||
| ] | ||
| }], | ||
|
|
||
| // This is mostly visual style, making comments look uniform. | ||
| "spaced-comment": ["error", "always", { | ||
| "markers": ["/"], // triple-slash | ||
| "exceptions": ["/"] // all slashes | ||
| }], | ||
|
|
||
| // This tends to be annoying as it encourages developers to make everything | ||
| // that is never reassigned a 'const', sometimes semantically incorrect so, | ||
| // typically leading to huge diffs in follow-up PRs modifying affected code. | ||
| "prefer-const": "off", | ||
|
|
||
| // It is perfectly fine to declare top-level variables with `var`, yet this | ||
| // rule doesn't provide configuration options that would help. | ||
| "no-var": "off", | ||
|
|
||
| // Quite often, dealing with multiple related cases at once or otherwise | ||
| // falling through is exactly the point of using a switch. | ||
| "no-fallthrough": "off", | ||
|
|
||
| // Typical false-positives here are `do { ... } while (true)` statements or | ||
| // similar, but the only option provided here is not checking any loops. | ||
| "no-constant-condition": ["error", { checkLoops: false }], | ||
|
|
||
| // Functions are nested in blocks occasionally, and there haven't been any | ||
| // problems with this so far, so turning the check off. | ||
| "no-inner-declarations": "off", | ||
|
|
||
| // Quite common in scenarios where an iteration starts at `current = this`. | ||
| "@typescript-eslint/no-this-alias": "off", | ||
|
|
||
| // Interferes with tests and 64-bit literals | ||
| "@typescript-eslint/no-loss-of-precision": "off", | ||
|
|
||
| // Disabled here, but enabled again for JavaScript files. | ||
| "no-unused-vars": "off", | ||
|
|
||
| // Disabled here, but enabled again for TypeScript files. | ||
| "@typescript-eslint/no-unused-vars": "off" | ||
| }, | ||
| overrides: [ | ||
|
|
||
| // === JavaScript rules ==================================================== | ||
|
|
||
| { | ||
| env: { | ||
| "browser": true, | ||
| "amd": true, | ||
| "node": true, | ||
| "es6": true | ||
| }, | ||
| files: [ | ||
| "**/*.js", | ||
| "bin/*" | ||
| ], | ||
| rules: { | ||
| // We are testing both ESM and UMD, so don't limit us. | ||
| "@typescript-eslint/no-var-requires": "off", | ||
|
|
||
| // This rule does not behave well in JS files. | ||
| "@typescript-eslint/explicit-module-boundary-types": "off", | ||
|
|
||
| // Enforcing to remove function parameters on stubs makes code less | ||
| // maintainable, so we instead allow unused function parameters. | ||
| "no-unused-vars": [ | ||
| "warn", { | ||
| "vars": "local", | ||
| "args": "none", | ||
| "ignoreRestSiblings": false | ||
| } | ||
| ], | ||
|
|
||
| "@typescript-eslint/no-loss-of-precision": "error", | ||
| } | ||
| }, | ||
|
|
||
| // === TypeScript rules ==================================================== | ||
|
|
||
| { | ||
| files: [ | ||
| "**/*.ts" | ||
| ], | ||
| rules: { | ||
| // Enforcing to remove function parameters on stubs makes code less | ||
| // maintainable, so we instead allow unused function parameters. | ||
| "@typescript-eslint/no-unused-vars": [ | ||
| "warn", { | ||
| "vars": "local", | ||
| "varsIgnorePattern": "^[A-Z](?:From|To)?$", // ignore type params | ||
| "args": "none", | ||
| "ignoreRestSiblings": false | ||
| } | ||
| ] | ||
| } | ||
| }, | ||
|
|
||
| // === AssemblyScript rules (extends TypeScript rules) ===================== | ||
|
|
||
| { | ||
| files: [ | ||
| "**/assembly/**/*.ts", | ||
| "src/**/*.ts", | ||
| "lib/parse/src/**/*.ts" | ||
| ], | ||
| rules: { | ||
| // Namespaces are quite useful in AssemblyScript | ||
| "@typescript-eslint/no-namespace": "off", | ||
|
|
||
| // There is actually codegen difference here | ||
| "@typescript-eslint/no-array-constructor": "off", | ||
|
|
||
| // Sometimes it can't be avoided to add a @ts-ignore | ||
| "@typescript-eslint/ban-ts-comment": "off", | ||
|
|
||
| // Utilized to achieve portability in some cases | ||
| "@typescript-eslint/no-non-null-assertion": "off", | ||
| } | ||
| }, | ||
|
|
||
| // === Compiler rules (extends AssemblyScript rules) ======================= | ||
|
|
||
| { | ||
| files: [ | ||
| "src/**/*.ts", | ||
| "std/assembly/**/*.ts" | ||
| ], | ||
| rules: { | ||
| // There is an actual codegen difference here - TODO: revisit | ||
| "no-cond-assign": "off", | ||
|
|
||
| // Not all types can be omitted in AS yet - TODO: revisit | ||
| "@typescript-eslint/no-inferrable-types": "off", | ||
|
|
||
| // Used rarely to reference internals that are not user-visible | ||
| "@typescript-eslint/triple-slash-reference": "off", | ||
|
|
||
| // The compiler has its own `Function` class for example | ||
| "no-shadow-restricted-names": "off", | ||
| "@typescript-eslint/ban-types": "off" | ||
| } | ||
| }, | ||
|
|
||
| // === Standard Library rules (extends AssemblyScript rules) =============== | ||
|
|
||
| { | ||
| files: [ | ||
| "std/assembly/**/*.ts" | ||
| ], | ||
| rules: { | ||
| // We are implementing with --noLib, so we shadow all the time | ||
| "no-shadow-restricted-names": "off", | ||
|
|
||
| // Similarly, sometimes we need the return type to be String, not string | ||
| "@typescript-eslint/ban-types": "off" | ||
| } | ||
| }, | ||
|
|
||
| // === Standard Definition rules (extends TypeScript rules) ================ | ||
|
|
||
| { | ||
| files: [ | ||
| "std/**/*.d.ts" | ||
| ], | ||
| rules: { | ||
| // Often required to achieve compatibility with TypeScript | ||
| "@typescript-eslint/no-explicit-any": "off", | ||
|
|
||
| // Interfaces can be stubs here, i.e. not yet fully implemented | ||
| "@typescript-eslint/no-empty-interface": "off", | ||
|
|
||
| // Definitions make use of `object` to model rather unusual constraints | ||
| "@typescript-eslint/ban-types": "off" | ||
| } | ||
| }, | ||
|
|
||
| // === Compiler Definition rules (extends TypeScript rules) ================ | ||
|
|
||
| { | ||
| files: [ | ||
| "./dist/*.d.ts" | ||
| ], | ||
| rules: { | ||
| // Our definitions are complicated, and all attempts to describe them | ||
| // as modules have failed so far. As such, we re-export namespaces. | ||
| "@typescript-eslint/no-namespace": "off", | ||
| "@typescript-eslint/triple-slash-reference": "off" | ||
| } | ||
| }, | ||
|
|
||
| // === Test rules (extends TypeScript rules) =============================== | ||
|
|
||
| { | ||
| files: [ | ||
| "./tests/compiler/**/*.ts", | ||
| "./lib/loader/tests/assembly/**/*.ts" | ||
| ], | ||
| rules: { | ||
| // Tests typically include unusual code patterns on purpose. This is | ||
| // very likely not an extensive list, but covers what's there so far. | ||
| "no-empty": "off", | ||
| "no-cond-assign": "off", | ||
| "no-compare-neg-zero": "off", | ||
| "no-inner-declarations": "off", | ||
| "no-constant-condition": "off", | ||
| "use-isnan": "off", | ||
| "@typescript-eslint/no-namespace": "off", | ||
| "@typescript-eslint/no-unused-vars": "off", | ||
| "@typescript-eslint/no-empty-function": "off", | ||
| "@typescript-eslint/no-non-null-assertion": "off", | ||
| "@typescript-eslint/no-extra-semi": "off", | ||
| "@typescript-eslint/no-inferrable-types": "off", | ||
| "@typescript-eslint/ban-types": "off", | ||
| "@typescript-eslint/triple-slash-reference": "off", | ||
| "@typescript-eslint/ban-ts-comment": "off", | ||
| "@typescript-eslint/no-extra-non-null-assertion": "off", | ||
| "@typescript-eslint/no-empty-interface": "off" | ||
| } | ||
| }, | ||
| ] | ||
| }; | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -181,9 +181,12 @@ export abstract class Node { | |||||
| name: IdentifierExpression, | ||||||
| type: TypeNode, | ||||||
| initializer: Expression | null, | ||||||
| range: Range | ||||||
| range: Range, | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i prefer to put range at the end like the other ast.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I agree |
||||||
| decorators: DecoratorNode[] | null = null | ||||||
| ): ParameterNode { | ||||||
|
Comment on lines
-184
to
186
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think range should be always at end. decorators: DecoratorNode[] | null,
range: Range,
): ParameterNode {And yes, this will lead to more refactorings |
||||||
| return new ParameterNode(parameterKind, name, type, initializer, range); | ||||||
| let parameter = new ParameterNode(parameterKind, name, type, initializer, range); | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar here.
Suggested change
|
||||||
| parameter.decorators = decorators; | ||||||
| return parameter; | ||||||
| } | ||||||
|
|
||||||
| // special | ||||||
|
|
@@ -926,6 +929,9 @@ export class FunctionTypeNode extends TypeNode { | |||||
| ) { | ||||||
| super(NodeKind.FunctionType, isNullable, range); | ||||||
| } | ||||||
|
|
||||||
| /** Decorators on an explicit `this` parameter, if any, preserved for transforms. */ | ||||||
| explicitThisDecorators: DecoratorNode[] | null = null; | ||||||
| } | ||||||
|
|
||||||
| /** Represents a type parameter. */ | ||||||
|
|
@@ -971,6 +977,8 @@ export class ParameterNode extends Node { | |||||
| super(NodeKind.Parameter, range); | ||||||
| } | ||||||
|
|
||||||
| /** Decorators, if any, preserved so transforms can rewrite them before validation. */ | ||||||
| decorators: DecoratorNode[] | null = null; | ||||||
| /** Implicit field declaration, if applicable. */ | ||||||
| implicitFieldDeclaration: FieldDeclaration | null = null; | ||||||
| /** Common flags indicating specific traits. */ | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR adds a full legacy
.eslintrc.cjsalongside the existing flateslint.config.jsconfiguration. With ESLint v10 (as pinned in package.json),eslint.config.jsis the active config and.eslintrc.*is typically ignored unless users opt out of flat config. Consider removing this file or documenting why it’s needed to avoid confusing contributors with two independent ESLint configurations.