-
Notifications
You must be signed in to change notification settings - Fork 358
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
Allow null for FunctionDeclaration and ClassDeclaration id #98
Comments
That's interesting. Acorn / Babylon currently parse that as |
No, it was intended decision (and there were debates on this) because allowing null as id in FunctionDeclaration nodes breaks backward compatibility for tools that rely on safely using id as non-null Identifier. Also, it's easier to distinguish export default declarations that can be hoisted from those that can't by simply checking whether it's expression (that is, in |
@RReverser Interesting. (For anyone arriving at this issue, I found some of that previous discussion in #38, jquery/esprima#311, acornjs/acorn#208.) |
That's interesting, I hadn't thought about hoistable vs. not. Still, it seems that something has to change here, either Acorn or the spec + Esprima/Espree because right now, this is an incompatibility that isn't allowed by the spec: https://github.com/estree/estree/blob/master/es6.md#exportdefaultdeclaration |
@RReverser mentions a debate -- which I think he and I were on opposite sides of :) Ultimately I don't remember whether we all gave up talking about it (and thus status-quo remained) or if I just gave up and went with the wind, heh. But I mostly agree with the premise of the original post -- I wish 'id' could just be null and for estree to match the changing reality of the actual ES spec. A good chunk of the original discussion can be found in the second half of this thread if you want to read through it: jquery/esprima#311 |
Using a FunctionExpression here causes an ambiguity between NFEs and FDs. I just tried using babel to compile export default (function a(){}); and sure enough, it exposes |
The Babel bug is irrelevant and just the result of some sloppy parsing. FWIW I've switched my opinion on this, I didn't think the hoisting mattered which is why I was in favour of reusing a FunctionExpression but it's important for circular dependencies. On Sun, Aug 2, 2015 at 4:54 PM, Michael Ficarra notifications@github.com
|
@sebmck then how should that be parsed? |
@michaelficarra Didn't mean to imply that the bug was incorrect just that a nullable |
Ping @caridy I can see arguments both ways, I'd just like us all to agree. The thing I keep coming back to I'd the difference between these:
According to the spec, these are not the same (HoistableDeclaration vs. AssignmentExpression). |
That's true (unfortunately), they're not precisely the same. I don't have that strong opinion on any resolution of this (this was anyway too long debate :) ), it's just that breaking backwards compatibility on such a low level as declaration feels wrong to me, as before this we had that any declaration node is not just hoistable, but well, it declares something in scope, and tools could safely rely that id is always present and always an Identifier. Alternatively, this could be solved by creating separate node types (like we discussed earlier), but that probably looks even uglier. I hope we could find some way of representing those without introducing incompatibilities or unnecessary node types, but if not, I'm happy to reflect any changes to spec. |
It wont effect whether a local binding is hoisted (because there is none), but it will effect circular dependencies as the export should be hoisted. |
@sebmck Yes - that's what I mean. Basically |
This is the key here. It does matter when circular dependencies are suppose to work due to the hoistable nature of those declarations. I recall the discussion vividly, and @jeffmo and I spoke to Allen about this particular issue, and whether or not we will have similar hoistable declarations in the future, and the answer was yes! I will be ok with custom nodes (e.g.: |
Btw, in the implementation in espree and esprima, I was using |
How would changing the definition of Also, for my own edification and future reference, could someone provide a concrete example of where |
if (node.type === "FunctionDeclaration") {
console.log("I'm a function with the name", node.id.name);
} now throws a
a.js import "./b";
export default function () {
console.log("i'm a little teapot");
} b.js import a from "./a";
a(); The |
I don't think that quite cuts it, because a) AFAIK, there have been no reports to Esprima/Espree for already returning if (node.type === "Property") {
var key = node.key.name || node.key.value; // undefined for most computed keys
console.log("I'm an object property with the name", key);
}
So attempting to execute the expression version (a.js: |
Sure it does, that was just a naive example. Making
Yep. The declaration hoists, the expression doesn't. |
We dealt with this in ESLint when we enabled modules support - several rules broke. But in all cases it was an easy fix because we had the exports context to rely on. So, I don't see this breakage as a hurdle if FunctionDeclaration is the correct choice. |
Agreed with @gibson042 that this is not the only place where consuming ASTs of the updated format will require non-trivial changes. Computed property names is a perfect example. |
But computed properties were described much earlier. Might be harder to make changes at this point when ES6 is finished. But as I said above - if everyone else thinks it's a good idea, I don't mind and can change Acorn's behavior as soon as spec is updated. |
I don't see how there is even a discussion still happening here. Using a FunctionExpression to represent both an expression and a hoistable declaration in |
That's exactly an answer to
:) |
Alright, as long as we're agreed that the implementation in acorn is an insufficient representation and the spec as of now doesn't permit one that is sufficient. |
If I understand the spec correctly (the ES2015 spec, that is), would it be better to make the same condition that's in the ES spec that it can only be |
@IMPinball Unfortunately, that's not possible within out DSL. |
@RReverser Sure it's possible. interface NullableFunctionDeclaration <: FunctionDeclaration {
id: Identifier | null;
}
interface NullableClassDeclaration <: ClassDeclaration {
id: Identifier | null;
}
interface ExportDefaultDeclaration <: ModuleDeclaration {
type: "ExportDefaultDeclaration";
declaration: NullableFunctionDeclaration | NullableClassDeclaration | VariableDeclaration | Expression;
} |
I prefer sebmck's version. Creating an intermediate interface for < 3 cases seems over-abstracted. LGTM on @sebmck's proposal. |
+1 on @sebmck proposal as well. |
Then I'd suggest changing the names. |
@sebmck Do you want to submit PR with updated names? |
…claration Summary: `export default class {}` creates a `ClassDeclaration`, not a `ClassExpression`. ESTree doesn't technically allow nullable ids on `FunctionDeclaration` and `ClassDeclaration` yet, but that will be fixed by estree/estree#98. Reviewed By: samwgoldman Differential Revision: D3939824 fbshipit-source-id: 9b671beeb936a1154cef7b54c812198ff2dc5ab0
@RReverser do you know where this ended up? |
I believe we went with a variation of sebmck proposal + some changed names. (Basically that so interface OptFunctionDeclaration <: FunctionDeclaration {
id: Identifier | null;
}
interface OptClassDeclaration <: ClassDeclaration {
id: Identifier | null;
}
interface ExportDefaultDeclaration <: ModuleDeclaration {
type: "ExportDefaultDeclaration";
declaration: OptFunctionDeclaration | OptClassDeclaration | VariableDeclaration | Expression;
} |
@RReverser @ariya what does Esprima and Acorn do here? |
Esprima, Espree, Babylon, Flow all do |
Ok, let's PR this as originally described by sebmck and file an acorn bug @hzoo |
Acorn has done this has part of 5.0 a while ago acornjs/acorn#512 |
Ok @hzoo is there a PR for this to land in ESTree? |
Closes estree#98. This implementation was initially suggested by Sebastian McKenzie.
Closes estree#98. This implementation was initially suggested by Sebastian McKenzie.
Closes estree#98. This implementation was initially suggested by Sebastian McKenzie.
I opened a pull request for this: #174 |
Closes estree#98. This also removes `VariableDeclaration` from the list of valid `declaration`s in a `ExportDefaultDeclaration`.
Closes #98. This also removes `VariableDeclaration` from the list of valid `declaration`s in a `ExportDefaultDeclaration`.
FunctionDeclaration
andClassDeclaration
don't allownull
in itsid
property.However, both can be default exports without an ID.
I believe Acorn and Esprima produce the same.
I think this was an oversight and the spec needs updating.
The text was updated successfully, but these errors were encountered: