-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
BUG: Module exporting undeclared name should be a syntax error #5778
Comments
Merge pull request #5779 from rhuanjl:exportNamespace This PR does the following: 1. implements support for `export * as ns from "module"` syntax a normative change PR to ecma262 which has tc39 consensus See spec diff: https://spectranaut.github.io/proposal-export-ns-from/ See normative PR here: tc39/ecma262#1174 (comment) This is placed behind a flag but set to default enabled 2. Adds some relevant tests 3. Fixes a bug where duplicate exports weren't always a syntax error (implementing this feature correctly without fixing this bug would have been awkward) 4. Some drive by syntax error message improvement for duplicate exports and alias'd exports - "Syntax error: Syntax error" -> "Syntax error: Duplicate export of name '%s'" - "Syntax error: Syntax error" -> "Syntax error: 'as' is only valid if followed by an identifier." There are unfortunately some remaining related test262 failures due to #5778 and #5501 closes #5759 fixes #5777
I've been thinking about how to fix this - it seems it needs to involve adding a step at the end of parsing a module that re-checks any names exported via |
Seems like something we should be able to do at name binding. We do push a pidref to 'anything' when we export it, right? When we bind names, we could throw a SyntaxError if we find a referenced name with no declaration. |
Would that permit a valid case like this: export {foo};
var foo = 5; Whilst catching the invalid cases I put in the first post? |
Yes, it would. @boingoing is referring to the way the parser binds names to declarations. The "push" records the fact that there was a reference to the given name in the current scope. Binding takes place when parsing of the current scope is completed. So the reference can lexically precede or follow the declaration. |
Thanks @pleath that makes sense. I was going to make a PR to fix this but see it's now assigned to you @boingoing want me to give it a go still or have you got it? |
@rhuanjl, feel free to take a stab at it if you're motivated. I haven't looked-into the fix yet. We can help if you need some in that area of the code. If you're not feeling it I can take this one on, as well. 👍 |
I had a go at trying to do this but didn't get far, unless I'm missing something currently no pid ref is pushed for an exported name unless the export is also variable declaration (in which case it can't possibly hit this error). And I couldn't quite work out how to push a pid ref for the name and have it be accessible in the right place without making it into a variable declaration which would obviously be wrong. |
You're right, no pid ref is pushed in this case. It looks like we implemented it without attempting to bind the exported name to a declaration. Either we missed this requirement in the spec or implemented an earlier spec that didn't contain the requirement. What you'll want to do is call PushPidRef from Parser::AddModuleImportOrExportEntry, passing in the IdentPtr of the local name, and store the resulting PidRefStack* on the export record. Binding will fill in the Symbol* on the PidRefStack. When we later resolve the export entries, a null Symbol* will indicate an undeclared name. Note that this has to be done whether buildAST is false or true, so the caller of AddModuleImportOrExportEntry will have to make the call in both cases. Does all that make sense? |
Merge pull request #5837 from rhuanjl:undefinedNames This PR causes CC to throw a syntax error when a module is parsed that exports a name with no local definition, this is per point 4 of https://tc39.github.io/ecma262/#sec-module-semantics-static-semantics-early-errors @boingoing @pleath Thanks for the help with how to do this, please could one of you review? fix: #5778
Another bug I found whilst working on #5759 though I do not currently have a fix planned for this.
Per
https://tc39.github.io/ecma262/#sec-module-semantics-static-semantics-early-errors
It is a Syntax Error if any element of the ExportedBindings of
ModuleItemList does not also occur in either the VarDeclaredNames of
ModuleItemList, or the LexicallyDeclaredNames of ModuleItemList.
POC:
Note the same repros if instead of "anything" you use any other undeclared name OR use a global like Number or Array or if you don't alias "anything".
Output with ch:
undefined
, jsc and v8 throw Syntax Errors(Can't do an eshost repro at the moment as eshost doesn't yet interact with ch's module flag)
This causes numerous test262 failures.
The text was updated successfully, but these errors were encountered: