Git Product home page Git Product logo

oxc's People

Contributors

arnaudbarre avatar boshen avatar camc314 avatar cijiugechu avatar dependabot[bot] avatar devin-yeung avatar donisaac avatar dunqing avatar eryue0220 avatar haocheng6 avatar hyf0 avatar iwanabethatguy avatar jason89521 avatar josebu1 avatar kaykdm avatar keita-hino avatar ken-hh24 avatar leaysgur avatar magic-akari avatar maurice avatar msdlisper avatar mysteryven avatar overlookmotel avatar renovate[bot] avatar riesaex avatar rzvxa avatar shannonrothe avatar u9g avatar underfin avatar yangchenye323 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oxc's Issues

perf(cli/lint) poor print performance above several hundred diagnostics threshold

Problem
Printing lint errors slows down exponentially.
Slowness is significant once the threshold of a few hundred diagnostics is crossed.

Repro

  1. Download babylon.max.js (arbitrary example)
  2. Build release
  3. Run ./oxc_cli.exe lint --max-warnings 1 babylon.max.js - very fast E2E time (to give an idea of parsing time)
  4. Run ./oxc_cli.exe lint --max-warnings 10 babylon.max.js - E2E time barely increased.
  5. Run ./oxc_cli.exe lint --max-warnings 100 babylon.max.js - E2E time increased much more in relative terms. On my machine, it's ~60x, where the number of printed messages only grew 10x (90 vs 9).
  6. Run ./oxc_cli.exe lint --max-warnings 500 babylon.max.js - time 20x,
  7. You get the point..

Initial findings
I thought it would be related to writing to stdout, but that seems to be done correctly already:

 let mut buf_writer = BufWriter::new(std::io::stdout());
        let mut number_of_warnings = 0;
        let mut number_of_diagnostics = 0;

        while let Ok(diagnostic) = rx_error.recv() {
            number_of_diagnostics += 1;

            if diagnostic.severity() == Some(Severity::Warning) {
                number_of_warnings += 1;
                // The --quiet flag follows ESLint's --quiet behavior as documented here: https://eslint.org/docs/latest/use/command-line-interface#--quiet
                // Note that it does not disable ALL diagnostics, only Warning diagnostics
                if self.cli_options.quiet {
                    continue;
                }

                if let Some(max_warnings) = self.cli_options.max_warnings {
                    if number_of_warnings > max_warnings {
                        continue;
                    }
                }
            }

            buf_writer
                .write_all(format!("{diagnostic:?}").as_bytes())
                .expect("Failed to write diagnostic.");
        }

One thing we can improve is take the lock on stdout. However, that doesn't solve the issue.

Profiling shows all of the time spent in miette:
image

The culprit isn't immediately obvious.
I haven't dug into miette code yet. It seems unlikely that it would have such a big performance issue, with no smoke (I couldn't find any issues in the repo related to performance).

The exponential nature of the slowness hints towards some vector or other struct's memory not being cleared/reused efficiently.

Feat(cli): exit with non-zero code when there are diagnostics

The current prototype always exit with 0 because I haven't implemented anything related to exit code.

In this good first issue, you will learn about the std::process::Termination trait and the std::process::ExitCode struct.

In oxc_cli, you may define a wrapper enum for all the possible exit states

#[derive(Debug)]
pub enum CliRunResult {
    None,
    PathNotFound {
        path: PathBuf,
    },
    LintResult {
        ... bunch of stats and stuff
    },
}

and nice messages inside the report method.

Finally inside main.rs, you can return the run result with std::process::Termination implemented on it.

fn main() -> CliRunResult {}

Have fun!

refactor(ast): remove `Option<Vec>` for clarity.

We have code like these:

    #[serde(skip_serializing_if = "Option::is_none")]
    pub decorators: Option<Vec<'a, Decorator<'a>>>,

I was in the mentality of None = JavaScript and didn't think more deeply.

This should just be

#[serde(skip_serializing_if = "Vec::is_empty")]

implement lint rules

After I wrap up the work on #57 it'd be great to try to implement some lint rules, do you have any particular rules in mind that you'd like implemented? 🙂

Better diagnostics for language/asi/S7.9_A6.2_T10.js

for test of test262/test/language/asi/S7.9_A6.2_T10.js

for(
    false
;) {
  break;
}

oxc now only prints Unexpected token for expressions missing semicolon.

  × Unexpected token
    ╭─[language/asi/S7.9_A6.2_T1.js:19:1]
 19 │ for(;
 20 │ ) {
    · ─
 21 │   break;
    ╰────

It would be better for the diagnostics to print ';' expected since we are in a for loop. An insertion of semi will simply help complete the for statement. See diagnostics of tsc

feat(linter): configuration comments

configuration comments, a.k.a suspension comments, eslint-disable-next

https://eslint.org/docs/latest/use/configure/rules#disabling-rules

background: #6


Here's what I have in mind, please correct me if you don't think it is not going to work:

To get configuration comments to work, we need to:

  1. inside the lexer, save all the eslint configuration comments and the span they apply to
  2. when a diagnostic is emitted, find if it overlaps with the comment ranges saved from above
  3. report all unused comments (the reportUnusedDisableDirectives option)

The first step will be the most difficult part. I don't know if it is even possible, but it'll be much more efficient than eslint because we don't need to track line numbers.

refactor(linter): use proc_macro to for rule registration

This file is getting huge and it is just repetitive boilerplate. It would be nice to use a proc_macro to generate these.

The file should end up with something like

declare_all_lints! {
    no_debugger,
    typescript::no_empty_interface,
    deepscan::uninvoked_array_callback
}

The identifier deepscan::uninvoked_array_callback should be a syn::Path I think.

It is expanded into

mod deepscan {
  pub mod uninvoked_array_callback;
}

For example

https://github.com/Boshen/oxc/blob/4829b85c2d89cfc8241e8542e49f4f9a8f8d36ae/crates/oxc_linter/src/rules.rs#L5-L7

has this directory structure

feat(linter): rule categories

Clippy defines the following rule categories for lint rules

Category Description Default level
clippy::all all lints that are on by default (correctness, suspicious, style, complexity, perf) warn/deny
clippy::correctness code that is outright wrong or useless deny
clippy::suspicious code that is most likely wrong or useless warn
clippy::style code that should be written in a more idiomatic way warn
clippy::complexity code that does something simple but in a complex way warn
clippy::perf code that can be written to run faster warn
clippy::pedantic lints which are rather strict or have occasional false positives allow
clippy::restriction lints which prevent the use of language and library features[^restrict] allow
clippy::nursery new lints that are still under development allow
clippy::cargo lints for the cargo manifest allow

I haven't thought much about the to categorize JavaScript / TypeScript rules, but we should at least define a correctness and nursery rule so we can ship and merge unfinished rules at the same time.

This should be an easy task where we copy how Clippy does this.

We will need to define correctness and nursery.

Feat(linter): `declare_oxc_lint` proc_macro

Rules have metadata we want to access to, but it is tedious to implement a RuleMeta trait on every lint rule.

In this good first issue, we will follow the more difficult paths of following rust-clippy, e.g.

https://github.com/rust-lang/rust-clippy/blob/e1ac1332b668f584919aba86ad3e81f267251e9b/clippy_lints/src/almost_complete_range.rs#L11-L31

So we need to:

  • add a declare_oxc_lint proc_macro crate
  • define a RuleMeta trait
  • hook up the NoDebugger Rule with the proc macro
  • add some tests for this, maybe in the same file where the RuleMeta trait is.

The first prototype should probably just contain a name and a documentation. Other metadata can be added later.

See

Drop a comment if you wish to tackle this, so I can assign this issue to you.

linter: rules we want to implement

For our first good release, we want to have some correctness rules.

Correctness rules (defined by clippy) are code that is outright wrong or useless.

Some of these are from deepscan or eslint-plugin-import.

Only ASTs rules can implemented right now, but I'll be adding scopes and symbol resolution soon.

Rules that require CFG (Control flow graph) cannot be implemented right now.

Deepscan:

eslint-plugin-import:

  • import/export
  • import/named
  • import/no-absolute-path
  • import/no-named-as-default-member
  • import/no-self-import

ESLint:

  • array-callback-return
  • #127
  • #136
  • getter-return
  • missing-throw
  • no-async-promise-executor #180
  • no-caller #178
  • no-class-assign #204
  • no-compare-neg-zero #185
  • no-const-assign #199
  • no-constant-binary-expression #118
  • no-constant-condition
  • no-debugger
  • no-dupe-class-members #195
  • no-dupe-else-if
  • no-dupe-keys #188
  • no-duplicate-case #179
  • no-eval
  • no-func-assign
  • no-implied-eval
  • no-import-assign
  • no-irregular-whitespace
  • no-new-symbol #201
  • no-obj-calls
  • no-self-compare #152
  • no-setter-return
  • no-shadow-restricted-names
  • no-this-before-super
  • no-unreachable
  • no-unsafe-negation #186
  • no-unused-labels
  • require-yield
  • #112
  • use-isnan #161
  • valid-typeof #202

Syntax error

The rules in here don't need to be implemented since they are syntax errors.

  • no-with (strict mode error)
  • no-dupe-args #181
  • no-octal

feat(oxc_parser): handle typescript modifiers in a more unified way

Description

Typescript modifiers, e.g., abstract, public, declare, can appear in arbitrary order and they can modify any kind of declarations, not only class. For example, abstract const a = 1; can produce a valid AST and the semantic analyzer would reject the code because abstract can only modify class declaration.

Expected Behavior

oxc_parser should be able to produce valid AST for these kinds of constructs

Are you planning on fix it.

Yes

Benchmark on different cpu architectures

#23 (comment)

I have found that to_bitmask on ARM NEON can be cause parsing to be slower compared to a scalar version. My block comment parser only uses SIMD on x86, not ARM. Do you run your benchmarks on ARM NEON or just Intel SSE?

On x86_64, to_bitmask is one instruction. On AArch64, there is no instruction and to_bitmask needs to be emulated. See: https://godbolt.org/z/531oEo5d1 It looks like the Rust compiler currently does a terrible job on AArch64. You can definitely do better by hand, but it still might not be faster than the scalar version.

feat: printer

It seems I need a way to verify the code is correct.

Basically a parse -> print -> parse routine will sufficiently indicate if parsing is correct.

Refactor: try aligned string for simd in lexer

#26 (comment)

You can guarantee that remainder is always empty or unimportant (thus you don't need to check for it) if you add enough zeros at the end of bytes. I do this in quick-lint-js when I load the file from the filesystem, so everything can safely assume that the extra bytes are present. (I have a dedicated type for this called padded_string_view which doesn't allow breaking this invariant.)

Nested Code Fixes

I wonder if it's possible for us to implement nested code fixes. For example, the following expression:
1 & 2 ^ 3 | 4
should be changed to ((1 & 2) ^ 3) | 4, which involves first changing the span 1 & 2 to be (1 & 2) and then changing (1 & 2) ^ 3 to be ((1 & 2) ^ 3).

I noticed our current fixer seems to assume its fix spans are disjoint intervals. Could this be done with our current approach, i.e., manipulating source text directly rather than changing the AST?

feat(linter): implement `no-array-constructor`

This is going to be fun!

We will be porting the no-array-constructor rule for JavaScript and TypeScript at the same time:

The goal of this task is to:

  • iron out the details for implementing a rule
  • draft a documentation for how to implement a rule
  • nice to have - create a script to transform tests to our Rust, because it is going to be very time consuming to copy, paste and modify the tests

Your feedbacks will shape the future of this project.

I have also setup a discord channel for quick communications.

Drop a comment if you wish to try this, so I can assign this issue to you.

perf(ast): shrink struct sizes

Relevant: https://github.com/swc-project/swc/issues/7019

I'll take a look at the AST and see if there are any further improvements we can made, I already boxed all the enums but there may be some low hanging fruits.


Commands

cargo install top-type-sizes
RUSTFLAGS=-Zprint-type-sizes cargo build --release -p oxc_ast -j 1 > type-sizes.txt
top-type-sizes -w -f ast:: < type-sizes.txt > output.txt
Output ``` 1024 internals::ast::Container<'_> align=8 32 ident 32 data 944 attrs 8 generics 8 original

728 internals::ast::Field<'_> align=8
32 member
8 ty
8 original
680 attrs

512 internals::ast::Variant<'_> align=8
32 ident
24 fields
8 original
440 attrs
1 style
7

216 ast::js::Class<'_> align=8
32 id
32 implements
32 modifiers
32 decorators
16 super_class
8 span
8 type_parameters
8 super_type_parameters
40 body
1 type
7

216 [closure@bumpalo::Bump::alloc<ast::js::Class<'_>>::{closure#0}] align=8
216

200 std::result::Result<ast::Input<'_>, syn::Error> align=8
200 variant Ok
32 variant Err
8
24 0 align=8

200 std::ops::ControlFlow<std::result::Result<std::convert::Infallible, syn::Error>, ast::Input<'_>> align=8
200 variant Continue
32 variant Break
8
24 0 align=8

200 ast::Input<'_> align=8
8
192 variant Struct, Enum

192 std::result::Result<ast::Struct<'_>, syn::Error> align=8
192 variant Ok
24 variant Err

192 std::result::Result<ast::Enum<'_>, syn::Error> align=8
192 variant Ok
24 variant Err

192 ast::Struct<'_> align=8
32 ident
8 original
8 generics
24 fields
120 attrs

192 ast::Enum<'_> align=8
32 ident
8 original
8 generics
24 variants
120 attrs

184 std::result::Result<ast::Variant<'_>, syn::Error> align=8
184 variant Ok
24 variant Err

184 std::ops::ControlFlow<std::result::Result<std::convert::Infallible, syn::Error>, ast::Variant<'_>> align=8
184 variant Continue
24 variant Break

184 ast::Variant<'_> align=8
32 ident
8 original
24 fields
120 attrs

176 std::result::Result<ast::Field<'_>, syn::Error> align=8
176 variant Ok
24 variant Err

176 std::ops::ControlFlow<std::result::Result<std::convert::Infallible, syn::Error>, ast::Field<'_>> align=8
176 variant Continue
24 variant Break

176 ast::Field<'_> align=8
32 member
8 original
8 ty
120 attrs
1 contains_generic
7

128 ast::js::Function<'_> align=8
32 id
32 modifiers
8 span
8 body
8 type_parameters
8 params
24 return_type
1 type
1 expression
1 generator
1 async
4

128 [closure@bumpalo::Bump::alloc<ast::js::Function<'_>>::{closure#0}] align=8
128

120 ast::ts::TSInterfaceDeclaration<'_> align=8
32 extends
32 modifiers
32 id
8 span
8 type_parameters
8 body

120 [closure@bumpalo::Bump::alloc<ast::ts::TSInterfaceDeclaration<'_>>::{closure#0}] align=8
120

112 ast::js::ExportAllDeclaration<'_> align=8
32 assertions
32 source
40 exported
1 export_kind
7

112 [closure@bumpalo::Bump::alloc<ast::js::ExportAllDeclaration<'_>>::{closure#0}] align=8
112

104 ast::ts::TSEnumDeclaration<'_> align=8
32 modifiers
32 id
32 members
8 span

104 ast::js::TaggedTemplateExpression<'_> align=8
16 tag
8 span
8 type_parameters
72 quasi

104 ast::js::PropertyDefinition<'_> align=8
32 decorators
16 key
16 value
8 span
24 type_annotation
1 accessibility
1 computed
1 static
1 declare
1 override
1 optional
1 definite
1 readonly

104 ast::js::ImportDeclaration<'_> align=8
32 assertions
32 specifiers
32 source
1 import_kind
7

104 [closure@bumpalo::Bump::alloc<ast::ts::TSEnumDeclaration<'_>>::{closure#0}] align=8
104

104 [closure@bumpalo::Bump::alloc<ast::js::TaggedTemplateExpression<'_>>::{closure#0}] align=8
104

104 [closure@bumpalo::Bump::alloc<ast::js::ImportDeclaration<'_>>::{closure#0}] align=8
104

96 std::iter::Map<std::iter::Zip<std::iter::Map<std::ops::Range, fn(usize) -> proc_macro2::Ident>, std::slice::Iter<', internals::ast::Field<'>>>, [closure@/Users/boshen/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_derive-1.0.152/src/de.rs:657:51: 657:65]> align=8
64 iter
32 f

96 ast::ts::TSTypeAliasDeclaration<'_> align=8
32 modifiers
32 id
16 type_annotation
8 span
8 type_parameters

96 ast::ts::TSModuleDeclaration<'_> align=8
32 modifiers
16 body
8 span
40 id

96 ast::jsx::JSXOpeningElement<'_> align=8
32 attributes
8 span
8 type_parameters
40 name
1 self_closing
7

96 ast::js::FormalParameter<'_> align=8
32 decorators
48 pattern
8 span
1 accessibility
1 readonly
6

96 [closure@bumpalo::Bump::alloc<ast::ts::TSTypeAliasDeclaration<'_>>::{closure#0}] align=8
96

96 [closure@bumpalo::Bump::alloc<ast::ts::TSModuleDeclaration<'_>>::{closure#0}] align=8
96

96 [closure@bumpalo::Bump::alloc<ast::jsx::JSXOpeningElement<'_>>::{closure#0}] align=8
96

88 std::iter::adapters::flatten::FlattenCompat<std::iter::Map<std::iter::FilterMap<std::slice::Iter<', internals::ast::Variant<'>>, [closure@/Users/boshen/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_derive-1.0.152/src/bound.rs:74:21: 74:30]>, for<'a> fn(&'a [syn::WherePredicate]) -> std::vec::Vecsyn::WherePredicate {std::slice::<impl [syn::WherePredicate]>::to_vec}>, std::vec::IntoItersyn::WherePredicate> align=8
32 frontiter
32 backiter
24 iter

88 std::iter::adapters::flatten::FlattenCompat<std::iter::Map<std::iter::FilterMap<std::boxed::Box<dyn std::iter::Iterator<Item = &internals::ast::Field<'_>>>, [closure@/Users/boshen/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_derive-1.0.152/src/bound.rs:52:21: 52:28]>, for<'a> fn(&'a [syn::WherePredicate]) -> std::vec::Vecsyn::WherePredicate {std::slice::<impl [syn::WherePredicate]>::to_vec}>, std::vec::IntoItersyn::WherePredicate> align=8
32 frontiter
32 backiter
24 iter

88 ast::js::ExportSpecifier align=8
8 span
40 local
40 exported

88 ast::js::ExportNamedDeclaration<'_> align=8
32 source
32 specifiers
16 declaration
1 export_kind
7

88 [closure@bumpalo::Bump::alloc<ast::js::ExportNamedDeclaration<'_>>::{closure#0}] align=8
88

80 std::iter::adapters::flatten::FlattenCompat<std::iter::Map<std::slice::Iter<', std::option::Option<ast::js::BindingPattern<'>>>, for<'a> fn(&'a std::option::Option<ast::js::BindingPattern<'>>) -> std::vec::Vec<&'a ast::js::BindingIdentifier> {<std::option::Option<ast::js::BindingPattern<'>> as syntax_directed_operations::BoundNames>::bound_names}>, std::vec::IntoIter<&ast::js::BindingIdentifier>> align=8
32 frontiter
32 backiter
16 iter

80 std::iter::adapters::flatten::FlattenCompat<std::iter::Map<std::slice::Iter<', ast::js::VariableDeclarator<'>>, [closure@crates/oxc_ast/src/syntax_directed_operations.rs:100:43: 100:55]>, std::vec::IntoIter<&ast::js::BindingIdentifier>> align=8
32 frontiter
32 backiter
16 iter

80 std::iter::adapters::flatten::FlattenCompat<std::iter::Map<std::slice::Iter<', ast::js::ObjectPatternProperty<'>>, [closure@crates/oxc_ast/src/syntax_directed_operations.rs:55:23: 55:26]>, std::vec::IntoIter<&ast::js::BindingIdentifier>> align=8
32 frontiter
32 backiter
16 iter

80 std::iter::adapters::flatten::FlattenCompat<std::iter::Map<std::slice::Iter<', ast::js::FormalParameter<'>>, for<'a> fn(&'a ast::js::FormalParameter<'>) -> std::vec::Vec<&'a ast::js::BindingIdentifier> {<ast::js::FormalParameter<'> as syntax_directed_operations::BoundNames>::bound_names}>, std::vec::IntoIter<&ast::js::BindingIdentifier>> align=8
32 frontiter
32 backiter
16 iter

80 ast::ts::TSTypeParameter<'_> align=8
32 name
16 constraint
16 default
8 span
1 in
1 out
6

80 ast::jsx::JSXAttribute<'_> align=8
32 name
8 span
40 value

80 ast::js::VariableDeclarator<'_> align=8
16 init
48 id
8 span
1 kind
1 definite
6

80 ast::js::VariableDeclaration<'_> align=8
32 modifiers
32 declarations
8 span
1 kind
7

80 ast::js::Property<'_> align=8
16 key
48 value
8 span
1 kind
1 method
1 shorthand
1 computed
4

80 ast::js::Program<'_> align=8
32 directives
32 body
8 span
3 source_type
5

80 ast::js::ImportSpecifier align=8
32 local
8 span
40 imported

80 ast::js::ImportDeclarationSpecifier align=8
80 variant ImportSpecifier
40 variant ImportDefaultSpecifier, ImportNamespaceSpecifier

80 ast::js::ImportAttribute align=8
32 value
8 span
40 key

80 ast::js::ArrayAssignmentTarget<'_> align=8
32 elements
8 span
24 rest
12 trailing_comma
4

80 [closure@bumpalo::Bump::alloc<ast::ts::TSTypeParameter<'_>>::{closure#0}] align=8
80

80 [closure@bumpalo::Bump::alloc<ast::jsx::JSXAttribute<'_>>::{closure#0}] align=8
80

80 [closure@bumpalo::Bump::alloc<ast::js::VariableDeclaration<'_>>::{closure#0}] align=8
80

80 [closure@bumpalo::Bump::alloc<ast::js::Property<'_>>::{closure#0}] align=8
80

72 ast::ts::TSTypePredicate<'_> align=8
32 parameter_name
8 span
24 type_annotation
1 asserts
7

72 ast::ts::TSTemplateLiteralType<'_> align=8
32 quasis
32 types
8 span

72 ast::ts::TSMethodSignature<'_> align=8
16 key
8 span
8 type_parameters
8 params
24 return_type
1 kind
1 computed
1 optional
5

72 ast::ts::TSConditionalType<'_> align=8
16 check_type
16 extends_type
16 true_type
16 false_type
8 span

72 ast::jsx::JSXNamespacedName align=8
32 namespace
32 property
8 span

72 ast::jsx::JSXMemberExpression<'_> align=8
32 object
32 property
8 span

72 ast::js::TemplateLiteral<'_> align=8
32 quasis
32 expressions
8 span

72 ast::js::MethodDefinition<'_> align=8
32 decorators
16 key
8 span
8 value
1 kind
1 accessibility
1 computed
1 static
1 override
1 optional
2

72 ast::js::MetaProperty align=8
32 meta
32 property
8 span

72 ast::js::MemberExpression<'_> align=8
8
64 variant StaticMemberExpression, PrivateFieldExpression
48 variant ComputedMemberExpression

72 ast::js::FunctionBody<'_> align=8
32 directives
32 statements
8 span

72 ast::js::ForStatement<'_> align=8
16 init
16 test
16 update
16 body
8 span

72 ast::js::ForOfStatement<'_> align=8
16 right
16 body
8 span
24 left
1 await
7

72 ast::js::CallExpression<'_> align=8
32 arguments
16 callee
8 span
8 type_parameters
1 optional
7

72 ast::js::AssignmentPattern<'_> align=8
16 right
48 left
8 span

72 [closure@bumpalo::Bump::alloc<ast::ts::TSTypePredicate<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::ts::TSTemplateLiteralType<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::ts::TSMethodSignature<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::ts::TSConditionalType<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::allocast::jsx::JSXNamespacedName::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::jsx::JSXMemberExpression<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::TemplateLiteral<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::allocast::js::MetaProperty::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::MemberExpression<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::FunctionBody<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::ForStatement<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::ForOfStatement<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::CallExpression<'_>>::{closure#0}] align=8
72

72 [closure@bumpalo::Bump::alloc<ast::js::AssignmentPattern<'_>>::{closure#0}] align=8
72

64 std::iter::Zip<std::iter::Map<std::ops::Range, fn(usize) -> proc_macro2::Ident>, std::slice::Iter<', internals::ast::Field<'>>> align=8
16 b
8 index
8 len
8 a_len
24 a

64 ast::ts::TSNamedTupleMember<'_> align=8
32 label
16 element_type
8 span
1 optional
7

64 ast::ts::TSIndexSignature<'_> align=8
32 parameters
8 span
24 type_annotation

64 ast::ts::TSEnumMember<'_> align=8
16 initializer
8 span
40 id

64 ast::js::TemplateElement align=8
48 value
8 span
1 tail
7

64 ast::js::StaticMemberExpression<'_> align=8
32 property
16 object
8 span
1 optional
7

64 ast::js::PrivateInExpression<'_> align=8
32 left
16 right
8 span
1 operator
7

64 ast::js::PrivateFieldExpression<'_> align=8
32 field
16 object
8 span
1 optional
7

64 ast::js::ObjectAssignmentTarget<'_> align=8
32 properties
8 span
24 rest

</details>

perf(semantic): indextree

We are currently constructing a parent pointing tree using the indextree crate, but this is probably an overkill both cpu and memory wise.

The only functionality we need are:

  • find a node's parent node
  • iterate through a node's ancestor nodes

For performance, I wonder if using bumpalo will be better than a Vec by using the same allocator for the AST.

feat(cli): check for git uncommit files when trying to apply a fix

We need to check git status before applying any fixes otherwise we'll blow up people's code.

Clippy does this if you haven't noticed ;-)

This check has to live inside the cli for now because we don't have a file system abstraction. All the other components will be wasmed eventually.

feat(ast,parser): parse jsdoc

I see there are some demand for reading jsdoc information, let's do this in two steps:

  1. parse jsdoc into structured data, this should be lazy.
  2. save them into trivias and have them accessible. I haven't figured out the best way to do this, but see #6 for disucssion.

Note: This is for parsing jsdoc comments to structured data. This is not about wiring up all the jsdoc comments into a document tree (which is the main purpose for jsdoc).

To parse jsdoc comments, we need to:

  1. add a new routine to parse jsdoc in oxc_parser, this should be a separate routine so we can parse jsdoc lazily
  2. add the jsdoc AST to oxc_ast
  3. setup jsdoc tests (I'm unsure on how to do this properly yet).

References:

perf(lexer): Use SIMD to accelerate whitespace skipping

Sometime ago I drafted a version to use SIMD for skipping whitespaces:

image

In this good first issue, you should be able to replicate the code from above, and add it to the lexer.

You should refactor the code above into a function and call the function just above the while loop:

https://github.com/Boshen/oxc/blob/93993978de969589f1fb91a689594a5e5c4b8f02/crates/oxc_parser/src/lexer/mod.rs#L320-L330

You will also need to add #![feature(portable_simd)] to the top of crates/oxc_parser/src/lib.rs

To the run parser, you can run the example binary:

https://github.com/Boshen/oxc/blob/3daf5bcea95f6fe2c88a7956948f4cb22711f99e/crates/oxc_parser/examples/simple.rs#L7-L10

Background reading:

README is not very helpful

Sorry if this may come out as rude. But I'm not a rust developer, I saw oxc on github explore feed, and wanted to try it out (you know, let it "oxidise" my javascript), but the README doesn't have those instructions.

Usually, one would like to include "Installation" and "Usage" headings to help new users learn how to use it...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.