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

SyntaxError: unknown: Binding 'arguments' in strict mode (2:6) #11385

Closed
RichardHoOoOo opened this issue Apr 7, 2020 · 18 comments · Fixed by #12344
Closed

SyntaxError: unknown: Binding 'arguments' in strict mode (2:6) #11385

RichardHoOoOo opened this issue Apr 7, 2020 · 18 comments · Fixed by #12344
Assignees
Labels
help wanted i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue

Comments

@RichardHoOoOo
Copy link

Hi I follow the instructions in this doc to transform arrow functions.

I find an error SyntaxError: unknown: Binding 'arguments' in strict mode (2:5) is thrown every time when a variable is named "arguments". For example,

var foo = () => {
 var arguments = 1;
};

The instruction I use is require('@babel/core').transform(code, {plugins: ['@babel/plugin-transform-arrow-functions']}) where code is the input program like the above example.

So how can I fix it? Is there any options I miss to set?

@babel-bot
Copy link
Collaborator

Hey @RichardHoOoOo! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."

@nicolo-ribaudo
Copy link
Member

You can pass sourceType: "script" as an option to Babel. The default value is "module", and that code is not valid inside modules.

@RichardHoOoOo
Copy link
Author

Thanks for your answer! It works!

However, it seems the semantic of the program got changed. For example, if the input is like this:

var foo = () => {
 var arguments = 1;
 console.log(arguments);
};

foo();

The output is

var _arguments = arguments;

var foo = function () {
  var arguments = 1;
  console.log(_arguments);
};

foo();

Then the output in console is different. Could you give me some more advise? Thanks!

@nicolo-ribaudo
Copy link
Member

The second one is a bug!

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Apr 7, 2020

@RichardHoOoOo If you are interested in fixing this issue you are welcome to help, otherwise it's open for anyone who wants to work on it!


The problem is in the utility we have to convert arrow functions to ES5 function expressions. In the hoistFunctionEnvironment function, we "extract" this, arguments, super and new.target to the outer scope, to preserve the correct semantics in cases like this one:

function f() {
  var g = () => console.log(arguments);
  g();
}

f(1, 2, 3); // should log 1, 2, 3

However, when there is a var arguments; declaration, arguments shouldn't refer to the outer function's arguments anymore. When replacing arguments, we need to check if it was defined as a variable in the local scope using argumentsChild.scope.hasOwnBinding("arguments").

Note that we also need to check argumentsChild.scope.parent, argumentsChild.scope.parent.parent and so on: we should stop when we reach a non-arrow function scope, which defines the implicit arguments binding.

A few test cases:

var foo = () => {
  var arguments = 1;
  return arguments;
};
var foo = () => {
  var arguments = 1;
  return () => arguments;
};
function fn() {
  var arguments = 1;
  var foo = () => {
    return arguments;
  };
}
var arguments = 1;
function fn() {
  var foo = () => {
    return arguments;
  };
}

If it is the first time that you contribute to Babel, follow these steps: (you need to have make and yarn available on your machine)

  1. Write a comment there to let other possible contributors know that you are working on this bug.
  2. Fork the repo
  3. Run git clone https://github.com/<YOUR_USERNAME>/babel.git && cd babel
  4. Run yarn && make bootstrap
  5. Wait ⏳
  6. Run make watch (or make build whenever you change a file)
  7. Add a test (only input.js; output.js will be automatically generated)
  8. Update the code!
  9. yarn jest plugin-transform-arrow-functions to run the tests
    • If some test outputs don't match but the new results are correct, you can delete the bad output.js files and run the tests again
    • If you prefer, you can run OVERWRITE=true yarn jest plugin-transform-arrow-functions and they will be automatically updated.
  10. If it is working, run make test to run all the tests
  11. Run git push and open a PR!

@RichardHoOoOo
Copy link
Author

@nicolo-ribaudo Very appreciate your help for finding the root cause! Let me take a look and see if I can fix it.

@nicolo-ribaudo
Copy link
Member

@RichardHoOoOo Are you still working on this?


@Yokubjon-J If Richard doesn't respond in 3-4 days and if you are interested, you can take this issue. Otherwise we'll need to find another one!

@Yokubjon-J
Copy link
Contributor

@nicolo-ribaudo Hello! Sorry for late reply! OK I will take on the issue!

@Yokubjon-J
Copy link
Contributor

I have started working on the issue!

@Yokubjon-J
Copy link
Contributor

Yokubjon-J commented Jul 5, 2020

@RichardHoOoOo If you are interested in fixing this issue you are welcome to help, otherwise it's open for anyone who wants to work on it!

The problem is in the utility we have to convert arrow functions to ES5 function expressions. In the hoistFunctionEnvironment function, we "extract" this, arguments, super and new.target to the outer scope, to preserve the correct semantics in cases like this one:

function f() {
  var g = () => console.log(arguments);
  g();
}

f(1, 2, 3); // should log 1, 2, 3

However, when there is a var arguments; declaration, arguments shouldn't refer to the outer function's arguments anymore. When replacing arguments, we need to check if it was defined as a variable in the local scope using argumentsChild.scope.hasOwnBinding("arguments").

Note that we also need to check argumentsChild.scope.parent, argumentsChild.scope.parent.parent and so on: we should stop when we reach a non-arrow function scope, which defines the implicit arguments binding.

A few test cases:

var foo = () => {
  var arguments = 1;
  return arguments;
};
var foo = () => {
  var arguments = 1;
  return () => arguments;
};
function fn() {
  var arguments = 1;
  var foo = () => {
    return arguments;
  };
}
var arguments = 1;
function fn() {
  var foo = () => {
    return arguments;
  };
}

If it is the first time that you contribute to Babel, follow these steps: (you need to have make and yarn available on your machine)

  1. Write a comment there to let other possible contributors know that you are working on this bug.

  2. Fork the repo

  3. Run git clone https://github.com/<YOUR_USERNAME>/babel.git && cd babel

  4. Run yarn && make bootstrap

  5. Wait ⏳

  6. Run make watch (or make build whenever you change a file)

  7. Add a test (only input.js; output.js will be automatically generated)

  8. Update the code!

  9. yarn jest plugin-transform-arrow-functions to run the tests

    • If some test outputs don't match but the new results are correct, you can delete the bad output.js files and run the tests again
    • If you prefer, you can run OVERWRITE=true yarn jest plugin-transform-arrow-functions and they will be automatically updated.
  10. If it is working, run make test to run all the tests

  11. Run git push and open a PR!

When I am at the 6th step, after running make watch I am getting stuck at:

[19:42:42] Finished 'build-no-bundle' after 12 s
[19:42:42] Starting 'watch'...
make: *** [Makefile:85: watch] Error 1

Up till this part, many files will have been compiled (it generates a really long list of those files), everything seem to work perfectly, but at [19:42:42] Starting 'watch'... it takes an indefinite amount of time and I will have had to stop it, then that error is generated. What is your suggestion for me to proceed? Can I overlook this problem and continue? (I use GitBash on Windows to run the commands.)

@nicolo-ribaudo
Copy link
Member

That's expected (I should have been clearer): make watch never ends. If you modify a file and save it, you'll notice that the make watch command that is running will produce new output showing that it re-compiled the updated file.

@Yokubjon-J
Copy link
Contributor

Yokubjon-J commented Jul 5, 2020

Could you try running make build-no-bundle and then yarn gulp watch instead of make watch?

make build-no-bundle worked fine but I am getting (again) stuck after running yarn gulp watch, the last 3 lines after which I am stuck are:

[20:54:42] Compiling 'packages\babel-types\src\validators\generated\index.js'...
[20:54:45] Finished 'build-no-bundle' after 12 s
[20:54:45] Starting 'watch'...

Here I have stopped the process manually but it didn't give make: *** [Makefile:85: watch] Error 1 error as before. Is it possible for me to start working on the bug without paying attention to this?

@nicolo-ribaudo
Copy link
Member

It's expected that it doesn't stop: it's waiting for you to change some files. I suggest leaving it in the background and opening a new terminal.

@snitin315
Copy link
Contributor

snitin315 commented Nov 3, 2020

@nicolo-ribaudo @JLHwung Can I work on this issue?

@JLHwung
Copy link
Contributor

JLHwung commented Nov 3, 2020

@snitin315 Sure. It's yours.

@JLHwung JLHwung assigned snitin315 and unassigned Yokubjon-J Nov 3, 2020
@snitin315
Copy link
Contributor

Thanks. Work in progress. I will sen a PR soon.

@taejs
Copy link

taejs commented Feb 14, 2021

I wonder if there's any progress on this issue. Can I take it?

@nicolo-ribaudo
Copy link
Member

@taejs There is already a PR for this (#12344), but I can look for another "good first issue" for you.

@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 6, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted i: bug outdated A closed issue/PR that is archived due to age. Recommended to make a new issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants