Skip to content

Commit

Permalink
fix(codegen): print Directive original string (#2157)
Browse files Browse the repository at this point in the history
> A Use Strict Directive may not contain an EscapeSequence or
LineContinuation.

It is `Use Strict Directive` spec, but the `expression` of `Directive`
isn't original string value, it has error if using it to codegen, so
here using `directive` of `Directive` to codegen and not to escape it.
Here is crashed test cases.

``` js
'use str\
ict';
```
The babel will print the original string, I follow it and avoid using
`print_str` because it will escape string.

I also changed some code using the `expression` of `Directive` to check
`Use Strict Directive` .
  • Loading branch information
underfin authored Jan 25, 2024
1 parent ac1d318 commit 989ab88
Show file tree
Hide file tree
Showing 6 changed files with 17 additions and 19 deletions.
9 changes: 7 additions & 2 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,13 @@ impl<const MINIFY: bool> Gen<MINIFY> for Hashbang {

impl<const MINIFY: bool> Gen<MINIFY> for Directive {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
// Use the string value instead of the raw self.directive because it can cannot escaped values.
print_str(self.expression.value.as_str(), p);
// A Use Strict Directive may not contain an EscapeSequence or LineContinuation.
// So here should print original `directive` value, the `expression` value is escaped str.
// See https://github.com/babel/babel/blob/main/packages/babel-generator/src/generators/base.ts#L64
let quote = choose_quote(self.directive.as_str());
p.print(quote as u8);
p.print_str(self.directive.as_bytes());
p.print(quote as u8);
p.print_semicolon();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,7 @@ impl Rule for NoAsyncClientComponent {
let Some(root) = ctx.nodes().iter().next() else { return };
let AstKind::Program(program) = root.kind() else { return };

if program
.directives
.iter()
.any(|directive| directive.expression.value.as_str() == "use client")
{
if program.directives.iter().any(|directive| directive.directive.as_str() == "use client") {
for node in &program.body {
let Statement::ModuleDeclaration(mod_decl) = &node else {
continue;
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_prettier/src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'a> Format<'a> for Directive {
let mut parts = p.vec();
parts.push(Doc::Str(string::print_string(
p,
self.expression.value.as_str(),
self.directive.as_str(),
p.options.single_quote,
)));
if let Some(semi) = p.semi() {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_semantic/src/checker/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ fn check_directive<'a>(directive: &Directive, node: &AstNode<'a>, ctx: &Semantic
#[diagnostic()]
struct IllegalUseStrict(#[label] Span);

if directive.expression.value != "use strict" {
if directive.directive != "use strict" {
return;
}

Expand Down
10 changes: 2 additions & 8 deletions tasks/coverage/codegen_runtime_test262.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
codegen_runtime_test262 Summary:
AST Parsed : 19663/19663 (100.00%)
Positive Passed: 19219/19663 (97.74%)
AST Parsed : 19665/19665 (100.00%)
Positive Passed: 19220/19665 (97.74%)
Expect to run correctly: "annexB/built-ins/String/prototype/substr/surrogate-pairs.js"
But got a runtime error: Test262Error: start: 1 Expected SameValue(«�», «\udf06») to be true

Expand Down Expand Up @@ -131,12 +131,6 @@ But got a runtime error: Test262Error: descriptor should be enumerable
Expect to run correctly: "annexB/language/global-code/switch-dflt-global-init.js"
But got a runtime error: Test262Error: descriptor should be enumerable

Expect to run correctly: "language/directive-prologue/14.1-4-s.js"
But got a runtime error: Test262Error: Expected true but got false

Expect to run correctly: "language/directive-prologue/14.1-5-s.js"
But got a runtime error: Test262Error: Expected true but got false

Expect to run correctly: "language/eval-code/direct/async-gen-func-decl-fn-body-cntns-arguments-func-decl-declare-arguments-and-assign.js"
But got a runtime error: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all

Expand Down
7 changes: 5 additions & 2 deletions tasks/transform_conformance/babel.snap.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
Passed: 329/1369
Passed: 327/1369

# All Passed:
* babel-plugin-transform-numeric-separator
* babel-plugin-transform-optional-catch-binding
* babel-plugin-transform-json-strings
* babel-plugin-transform-shorthand-properties
* babel-plugin-transform-sticky-regex
* babel-plugin-transform-instanceof
Expand Down Expand Up @@ -608,6 +607,10 @@ Passed: 329/1369
* transparent-expr-wrappers/ts-as-member-expression/input.ts
* transparent-expr-wrappers/ts-parenthesized-expression-member-call/input.ts

# babel-plugin-transform-json-strings (2/4)
* json-strings/directive-line-separator/input.js
* json-strings/directive-paragraph-separator/input.js

# babel-plugin-transform-async-generator-functions (0/22)
* async-generators/class-method/input.js
* async-generators/class-private-method/input.js
Expand Down

0 comments on commit 989ab88

Please sign in to comment.