Skip to content
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

Handle early errors for declarations in StatementList #1175

Merged
merged 4 commits into from
May 20, 2021

Conversation

0x7D2B
Copy link
Contributor

@0x7D2B 0x7D2B commented Mar 15, 2021

The standard specifies that redeclarations should be checked before the code is actually executed (see https://tc39.es/ecma262/#sec-block-static-semantics-early-errors), meaning that this piece of code would produce a SyntaxError even though the function does not run:

function f() {
  let foo = 1;
  let foo = 2;
}

This PR will add support for handling these errors, handle redeclarations of function argument names, and add some additional code that will make implementing other changes like forbidding certain names in statement lists easier.

This PR depends on #1181.

@0x7D2B 0x7D2B force-pushed the fix/let-early-errors branch from 4749c3a to 1d85cbd Compare March 21, 2021 13:56
@0x7D2B 0x7D2B marked this pull request as ready for review March 21, 2021 13:57
@RageKnify RageKnify added the parser Issues surrounding the parser label Mar 29, 2021
@RageKnify RageKnify added this to the v0.12.0 milestone Mar 29, 2021
@RageKnify RageKnify added the blocked Waiting for another code change label Mar 29, 2021
@RageKnify RageKnify requested review from Lan2u, Razican and tofpie March 31, 2021 17:44
@RageKnify RageKnify removed the blocked Waiting for another code change label May 7, 2021
Copy link
Member

@Razican Razican left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking very good. I'm approving it, since I believe it can be merged as-is. Some conformance results:

Test262 conformance changes:

Test result master count PR count difference
Total 78,497 78,497 0
Passed 25,344 25,370 +26
Ignored 15,587 15,587 0
Failed 37,566 37,540 -26
Panics 16 17 +1
Conformance 32.29 32.32 +0.03%

Benchmarks:

 ┌─────────┬──────────────────────────────────────────────┬─────────────────────┬──────────────────────┬────────────┐
│ (index) │                     name                     │   changesDuration   │    masterDuration    │ difference │
├─────────┼──────────────────────────────────────────────┼─────────────────────┼──────────────────────┼────────────┤
│    0    │     'Arithmetic operations (Execution)'      │   '353.0±5.08ns'    │    '352.7±8.38ns'    │   '0.0'    │
│    1    │        'Arithmetic operations (Full)'        │   '244.5±3.77µs'    │  '**235.3±5.14µs**'  │   '+4.0'   │
│    2    │          'Array access (Execution)'          │  '**5.7±0.15µs**'   │     '6.1±0.09µs'     │   '-7.4'   │
│    3    │            'Array access (Full)'             │ '**266.0±6.38µs**'  │    '271.5±5.22µs'    │   '-2.0'   │
│    4    │         'Array creation (Execution)'         │  '**2.7±0.10ms**'   │     '2.8±0.03ms'     │   '-2.0'   │
│    5    │           'Array creation (Full)'            │    '3.2±0.06ms'     │   '**3.2±0.05ms**'   │   '+1.0'   │
│    6    │           'Array pop (Execution)'            │   '899.1±21.03µs'   │   '900.1±13.92µs'    │   '0.0'    │
│    7    │              'Array pop (Full)'              │  '1403.0±18.80µs'   │   '1399.6±21.59µs'   │   '0.0'    │
│    8    │     'Boolean Object Access (Execution)'      │    '5.2±0.09µs'     │   '**5.2±0.08µs**'   │   '+1.0'   │
│    9    │        'Boolean Object Access (Full)'        │ '**263.0±4.78µs**'  │    '265.0±4.68µs'    │  '-0.99'   │
│   10    │            'Clean js (Execution)'            │   '651.5±10.34µs'   │    '654.0±7.86µs'    │   '0.0'    │
│   11    │              'Clean js (Full)'               │   '955.0±11.94µs'   │ '**916.5±27.62µs**'  │   '+4.0'   │
│   12    │             'Clean js (Parser)'              │    '42.4±0.55µs'    │  '**40.1±1.17µs**'   │   '+6.0'   │
│   13    │                'Create Realm'                │   '463.7±7.34ns'    │  '**460.3±6.85ns**'  │   '+1.0'   │
│   14    │ 'Dynamic Object Property Access (Execution)' │  '**4.6±0.16µs**'   │     '4.9±0.09µs'     │   '-5.7'   │
│   15    │   'Dynamic Object Property Access (Full)'    │ '**263.5±4.19µs**'  │    '268.2±4.84µs'    │   '-2.0'   │
│   16    │            'Expression (Parser)'             │    '6.9±0.09µs'     │     '6.9±0.12µs'     │   '0.0'    │
│   17    │           'Fibonacci (Execution)'            │ '**822.1±23.29µs**' │   '835.7±14.46µs'    │   '-2.0'   │
│   18    │              'Fibonacci (Full)'              │  '1112.4±18.34µs'   │ '**1095.6±22.06µs**' │   '+2.0'   │
│   19    │            'For loop (Execution)'            │  '**22.4±0.43µs**'  │    '22.8±0.29µs'     │   '-2.0'   │
│   20    │              'For loop (Full)'               │ '**279.9±3.80µs**'  │    '288.6±5.40µs'    │   '-2.9'   │
│   21    │             'For loop (Parser)'              │    '20.7±0.45µs'    │  '**19.3±0.57µs**'   │   '+7.0'   │
│   22    │           'Goal Symbols (Parser)'            │    '14.3±0.24µs'    │  '**13.5±0.36µs**'   │   '+6.0'   │
│   23    │            'Hello World (Parser)'            │    '4.0±0.06µs'     │   '**3.9±0.09µs**'   │   '+2.0'   │
│   24    │             'Long file (Parser)'             │   '764.7±12.71ns'   │ '**741.2±18.73ns**'  │   '+3.0'   │
│   25    │            'Mini js (Execution)'             │   '591.0±9.87µs'    │    '591.7±8.20µs'    │   '0.0'    │
│   26    │               'Mini js (Full)'               │ '**882.9±12.20µs**' │   '895.7±21.40µs'    │  '-0.99'   │
│   27    │              'Mini js (Parser)'              │    '37.5±0.55µs'    │  '**36.0±0.93µs**'   │   '+4.0'   │
│   28    │      'Number Object Access (Execution)'      │    '4.1±0.05µs'     │     '4.1±0.07µs'     │   '0.0'    │
│   29    │        'Number Object Access (Full)'         │   '257.7±3.77µs'    │    '258.2±3.46µs'    │   '0.0'    │
│   30    │        'Object Creation (Execution)'         │    '4.2±0.08µs'     │   '**4.2±0.08µs**'   │   '+1.0'   │
│   31    │           'Object Creation (Full)'           │ '**255.6±2.83µs**'  │    '264.7±4.79µs'    │   '-3.8'   │
│   32    │             'RegExp (Execution)'             │  '**10.9±0.18µs**'  │    '11.1±0.16µs'     │  '-0.99'   │
│   33    │               'RegExp (Full)'                │ '**269.2±3.84µs**'  │    '274.5±3.55µs'    │   '-2.0'   │
│   34    │         'RegExp Literal (Execution)'         │  '**10.8±0.17µs**'  │    '11.1±0.17µs'     │   '-2.0'   │
│   35    │           'RegExp Literal (Full)'            │ '**264.8±2.86µs**'  │    '270.2±4.00µs'    │   '-2.0'   │
│   36    │    'RegExp Literal Creation (Execution)'     │  '**9.3±0.24µs**'   │     '9.8±0.18µs'     │   '-5.7'   │
│   37    │       'RegExp Literal Creation (Full)'       │ '**261.6±3.56µs**'  │    '267.6±7.29µs'    │   '-2.0'   │
│   38    │ 'Static Object Property Access (Execution)'  │  '**4.3±0.11µs**'   │     '4.5±0.06µs'     │   '-5.7'   │
│   39    │    'Static Object Property Access (Full)'    │ '**256.2±3.85µs**'  │    '264.9±3.34µs'    │   '-2.9'   │
│   40    │      'String Object Access (Execution)'      │    '7.2±0.31µs'     │   '**7.1±0.09µs**'   │   '+2.0'   │
│   41    │        'String Object Access (Full)'         │   '266.2±4.38µs'    │  '**259.6±8.24µs**'  │   '+3.0'   │
│   42    │       'String comparison (Execution)'        │  '**6.5±0.10µs**'   │     '6.6±0.09µs'     │  '-0.99'   │
│   43    │          'String comparison (Full)'          │ '**262.8±3.42µs**'  │    '268.4±4.39µs'    │   '-2.0'   │
│   44    │      'String concatenation (Execution)'      │  '**5.2±0.06µs**'   │     '5.3±0.08µs'     │   '-2.0'   │
│   45    │        'String concatenation (Full)'         │ '**255.5±3.84µs**'  │    '259.1±3.59µs'    │  '-0.99'   │
│   46    │          'String copy (Execution)'           │  '**3.9±0.06µs**'   │     '3.9±0.06µs'     │  '-0.99'   │
│   47    │             'String copy (Full)'             │   '255.0±4.35µs'    │  '**251.7±3.79µs**'  │   '+1.0'   │
│   48    │            'Symbols (Execution)'             │    '3.3±0.06µs'     │     '3.3±0.06µs'     │   '0.0'    │
│   49    │               'Symbols (Full)'               │ '**242.7±15.10µs**' │    '245.0±2.88µs'    │  '-0.99'   │
│   50    │                      ''                      │      undefined      │      undefined       │   '+NaN'   │
└─────────┴──────────────────────────────────────────────┴─────────────────────┴──────────────────────┴────────────┘

boa/src/syntax/ast/node/statement_list/mod.rs Show resolved Hide resolved
@Razican
Copy link
Member

Razican commented May 10, 2021

This just requires a re-base to be merged.

@Razican Razican requested review from HalidOdat and RageKnify May 10, 2021 13:47
@0x7D2B 0x7D2B force-pushed the fix/let-early-errors branch from fc83ba6 to 1d85cbd Compare May 18, 2021 11:41
Comment on lines +309 to +316
return Err(ParseError::lex(LexError::Syntax(
format!("Redeclaration of variable `{}`", decl.name()).into(),
match cursor.peek(0)? {
Some(token) => token.span().end(),
None => Position::new(1, 1),
},
)));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a lexer error? The lexer correctly understood the tokens, right? It's just a normal parsing / Syntax error. Same happens for VarDeclList.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be a better way to get a syntax error here? ParseError doesn't have it as an option.

Copy link
Member

@Razican Razican left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with the code. Maybe @HalidOdat or @RageKnify want to check it further?

@RageKnify RageKnify merged commit 6723252 into boa-dev:master May 20, 2021
Razican pushed a commit that referenced this pull request May 22, 2021
* Merge {Let,Const,Var}DeclList

* Rustfmt

* Handle early errors for declarations in StatementList
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
parser Issues surrounding the parser
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants