oxc-project / oxc Goto Github PK
View Code? Open in Web Editor NEW⚓ A collection of JavaScript tools written in Rust.
Home Page: https://oxc-project.github.io
License: MIT License
⚓ A collection of JavaScript tools written in Rust.
Home Page: https://oxc-project.github.io
License: MIT License
The conformance task now snapshots all diagnostics:
What you can do is review these diagnostics and improve them, you can checkout babel or tsc for reference, by using https://astexplorer.net/
To begin with, it should be relative easy to fix some of the Unexpected token
errors.
Problem
Printing lint errors slows down exponentially.
Slowness is significant once the threshold of a few hundred diagnostics is crossed.
Repro
./oxc_cli.exe lint --max-warnings 1 babylon.max.js
- very fast E2E time (to give an idea of parsing time)./oxc_cli.exe lint --max-warnings 10 babylon.max.js
- E2E time barely increased../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)../oxc_cli.exe lint --max-warnings 500 babylon.max.js
- time 20x,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
:
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.
This blocks #118
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!
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")]
From the v8 scanner blog, I still see low hanging fruits, let's play with these and make our lexer even faster!
Cargo fix
does this, which is really nice.
See:
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? 🙂
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
Implement the ESLint constructor-super rule
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:
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.
Motivation: #79
https://eslint.org/docs/latest/rules/no-constant-binary-expression
I'll implement this one.
@Boshen is there a reason `start` and `end` on `Span` are `u32`?
Originally posted by @shannonrothe in #101 (comment)
It would be nice to see the total execution time when linting is done.
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
The Token
struct is currently 80 bytes carrying a 56 byte TokenValue
. This should be reduced.
Let's study this and implement it https://github.com/eslint/eslint/blob/main/lib/linter/source-code-fixer.js
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
.
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.
So we need to:
declare_oxc_lint
proc_macro crateRuleMeta
traitNoDebugger
Rule with the proc macroRuleMeta
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.
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.
ESLint:
The rules in here don't need to be implemented since they are syntax errors.
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.
oxc_parser should be able to produce valid AST for these kinds of constructs
Yes
We should create a oxc_wasm
crate and export the parser so we can build a playground.
See https://github.com/rome/tools/tree/main/crates/rome_wasm
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.
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.
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.)
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?
@YangchenYe323 @YoniFeng Let's continue our adventure after the video https://www.youtube.com/watch?v=DMQ_HcNSOAI
@YangchenYe323 Can you draft a baseline line PR, and let's walk up the performance ladder. We don't need to go all the way.
I need to setup the fuzzer for the parser :-)
See https://twitter.com/jarredsumner/status/1485397686224257027 for baselines
From Twitter:
https://github.com/rust-lang/rust/issues/37939
u32
is enough for spans.
This is currently using usize
because miette
only accepts Range
in its miette::Diagnostic
macro.
There should be a workaround but I haven't investigated in detail yet.
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:
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.
https://eslint.org/docs/latest/use/command-line-interface#run-the-cli
npx eslint [options] [file|dir|glob]*
Please note that when passing a glob as a parameter, it is expanded by your shell. The results of the expansion can vary depending on your shell, and its configuration. If you want to use node glob syntax, you have to quote your parameter
Make a comment if you wish to tackle this, so I can assign this issue to you.
This blocks #118
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.
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
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>
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:
For performance, I wonder if using bumpalo
will be better than a Vec
by using the same allocator for the AST.
The problem with clap is that it's binary size is huge! And it compiles really slowly. You cna see the bloat here: https://github.com/Boshen/oxc/actions/runs/4336082139
Someone suggested google/argh, let's try it.
https://eslint.org/docs/latest/use/command-line-interface#ignore-files
It would be the best if you submit a PR for each command.
Make a comment if you wish to tackle this, so I can assign this issue to you.
This is caught by the fuzzer https://github.com/Boshen/oxc/actions/runs/4395420223/jobs/7697210796
To replicate:
Create a test.tsx
with the following string:
1<(V=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V=uIV=82<<t-j0<(V=$<LBI<(V=ut<I<(V=$<LBI<(V<II>
run cargo run -p oxc_parser --example parser -- test.tsx
and it will run forever.
I'm gussing this is the result of parsing the ambiguous <
token, where TypeScript needs to lookahead and rewind forever.
https://eslint.org/docs/latest/use/command-line-interface#handle-warnings
Make a comment if you wish to tackle this, so I can assign this issue to you.
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 wasm
ed eventually.
I see there are some demand for reading jsdoc information, let's do this in two steps:
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:
References:
Motivation: #79
This is from deepscan, https://deepscan.io/docs/rules/uninvoked-array-callback
TypeScript doesn't implement this.
I'll implement this one.
Sometime ago I drafted a version to use SIMD for skipping whitespaces:
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:
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:
Background reading:
Compact string currently holds a capacity, which isn't needed for our usecase.
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...
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.