jquery / jquery/esprima

Object Getter triggers yield to incorrectly parse as YieldExpression

Open
#1,982 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.1k
Forks
772
PR merge metrics
No merged PRs in 30d

Description

When any get property is encountered the context.allowYield property is set to false and not reverted after parsing the getter body. This results in any future yield to be parsed as a yield expression incorrectly.

esprima.parse(`
({get a(){}});
yield;
`)
Expected output
{
  "type": "Program",
  "sourceType": "script",
  "body": [
    {
      "type": "ExpressionStatement",
      "expression": {
        "type": "ObjectExpression",
        "properties": [
          {
            "type": "Property",
            "key": {
              "type": "Identifier",
              "name": "a"
            },
            "computed": false,
            "kind": "get",
            "method": false,
            "shorthand": false,
            "value": {
              "type": "FunctionExpression",
              "id": null,
              "params": [],
              "body": {
                "type": "BlockStatement",
                "body": []
              },
              "generator": false,
              "async": false,
              "expression": false
            }
          }
        ]
      }
    },
    {
      "type": "ExpressionStatement",
      "expression": {
        "type": "Identifier",
        "name": "yield"
      }
    }
  ]
}
Actual output
{
    "type": "Program",
    "body": [
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "ObjectExpression",
                "properties": [
                    {
                        "type": "Property",
                        "key": {
                            "type": "Identifier",
                            "name": "a"
                        },
                        "computed": false,
                        "value": {
                            "type": "FunctionExpression",
                            "id": null,
                            "params": [],
                            "body": {
                                "type": "BlockStatement",
                                "body": []
                            },
                            "generator": false,
                            "expression": false,
                            "async": false
                        },
                        "kind": "get",
                        "method": false,
                        "shorthand": false
                    }
                ]
            }
        },
        {
            "type": "ExpressionStatement",
            "expression": {
                "type": "YieldExpression",
                "argument": null,
                "delegate": false
            }
        }
    ],
    "sourceType": "script"
}

This is pulled directly from everything.js

Using this file as and example, I was surprised that removing line 84 will cause this to parse differently as they are completely unrelated.

I believe the offending code is located on line 3257 of parser.ts.

I believe the correct path in the ecma262 spec for line 200 would be

  1. StatementListItem
  2. Statement
  3. ExpressionStatement
  4. Expression
  5. AssignmentExpression
  6. ConditionalExpression
  7. LogicalORExpression
  8. LogicalANDExpression
  9. BitwiseORExpression
  10. BitwiseXORExpression
  11. BitwiseANDExpression
  12. EqualityExpression
  13. RelationalExpression
  14. ShiftExpression
  15. AdditiveExpression
  16. MultiplicativeExpression
  17. ExponentiationExpression
  18. UnaryExpression
  19. UpdateExpression
  20. LeftHandSideExpression
  21. NewExpression
  22. MemberExpression
  23. PrimaryExpression
  24. IdentifierReference
  25. Identifier

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at parser.ts around line 3257 and reproduce the issue with the provided esprima.parse example. Compare the resulting AST with the expected output, focusing on whether parsing the getter leaves context.allowYield changed. Done means the later yield is represented as an Identifier while the getter remains correctly parsed.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.