-
-
Notifications
You must be signed in to change notification settings - Fork 256
Conversation
Codecov Report
@@ Coverage Diff @@
## master #393 +/- ##
==========================================
- Coverage 98.26% 98.13% -0.14%
==========================================
Files 20 20
Lines 3511 3478 -33
Branches 934 936 +2
==========================================
- Hits 3450 3413 -37
- Misses 22 25 +3
- Partials 39 40 +1
Continue to review full report at Codecov.
|
@@ -2,5 +2,8 @@ | |||
"extends": "babel", | |||
"env": { | |||
"node": true | |||
}, | |||
"rules": { | |||
"indent": 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you disable this rule? Where there problems with it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I indent things correctly, this PR will have an unreadable diff because the indent of most lines will change. Don't know a good solution for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh? Wasn't it properly indented before?
Edit: Ah I see the mixin part. Nice catch. Yes we can enable and autofix later
👍
src/options.js
Outdated
allowImportExportEverywhere: boolean; | ||
allowSuperOutsideMethod: boolean; | ||
plugins: $ReadOnlyArray<string>; | ||
strictMode: any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strictMode can be boolean or null
src/plugins/flow.js
Outdated
jsx_readToken() { | ||
// $FlowFixMe This method doesn't override anything! | ||
if (!this.state.inType) return super.jsx_readToken(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the history this was never working, so can you please remove this?
node.body.unshift(this.directiveToStmt(directive)); | ||
}); | ||
const directiveStatements = node.directives.map((d) => this.directiveToStmt(d)); | ||
node.body = directiveStatements.concat(node.body); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverse() got missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverse
+ forEach
+ unshift
= concat
.
end: number; | ||
loc: SourceLocation; | ||
range: [number, number]; | ||
leadingComments?: ?Array<Comment>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flow has a bug with maybe-typed properties in interfaces. It's better to avoid interfaces completely unless they only contain methods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is implemented by a class, so I think we need the interface?
|
||
pp.addComment = function (comment) { | ||
Parser.mixin(class extends Parser { | ||
addComment(comment: N.Comment): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can omit annotations if you don't export class or function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of them could be omitted, but I've tested around and some of them can't without breaking compilation. I also think it's nice to have the type annotations locally so I don't have to look them up in parserTypes.js
. The code worked fine without any type annotations, the point was to make it easier to read.
src/parser/node.js
Outdated
this.type = ""; | ||
// $FlowNonNull | ||
this.start = pos; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's always present, then why pos
is optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new Node;
is called in one place, but I just added a $FlowFixMe
comment at that place and no longer need hacks here. Thanks!
src/parser/statement.js
Outdated
@@ -238,6 +244,7 @@ pp.parseForStatement = function (node) { | |||
if (forAwait) { | |||
this.unexpected(); | |||
} | |||
// $FlowCast node: N.ForStatement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to do this explicitly with any
: ((node: any): N.ForStatement)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
…with actual casts
|
||
pp.shouldParseAsyncArrow = function () { | ||
shouldParseAsyncArrow(): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does flow not infer this, or do you want to assert that it returns a boolean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a function declared in parserTypes.ts
, the return type should be carried along from there. But for a function declared only locally, you may get no (or confusing) errors without a type annotation. I think it's better to just consistently declare types. E.g., remove the return type from parseCallExpressionArguments
, add elts.push(0);
somewhere, and you won't get any errors.
src/parser/expression.js
Outdated
const value = this.state.value; | ||
node = this.parseLiteral(value.value, "RegExpLiteral"); | ||
const node = this.parseLiteral(value.value, "RegExpLiteral"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A similar change could be made in most of the switch cases, but probably best to not make the diff much larger than it needs to be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, must have been trying something and forgot to change it back.
continue; | ||
if (proto[key]) | ||
throw new Error(`Can't mixin '${key}', already defined`); | ||
proto[key] = mixedProto[key]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copied keys will be enumerable, but they are not when defined in the class
expression.
On the other hand, before the change to class
expression, they were enumerable anyway, so it might not matter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an opinion on this.
src/parser/index.js
Outdated
} | ||
|
||
superProto[key] = self[key]; | ||
self[key] = extenderProto[key]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing in these two lines here w.r.t. enumerability.
We moved the previous 7.0 branch to be |
Hey @andy-ms! It looks like one or more of your builds have failed. I've copied the relevant info below to save you some time. |
It looks like the test failure is in babel somewhere -- did this PR change it or was the change in babel? |
Yeah a different pr we need to fix that I merged, need to mereg babel/babel#5450 |
Hm, still failing.
|
Yeah, looks like an unrelated (to this PR) issue with the latest b7 alpha, will take a look after lunch. |
@existentialism Seems to have been fixed. |
Again, test failures are probably due to some change in babel? |
Besides it being a massive diff I do not like they idea of restructuring code just to please flow. It might have been easier to start small and just enable flow file by file and PR them separately. Ohh and we should keep an eye on performance, as a drastic change like this might also have performance impacts. |
I'll second performance. The That said, I don't have a problem with the structure. I think having the node types in their own file is inevitable since they are used all over the place, and the class extension + mixin approach is a little weird, not doesn't seem too bad to me. |
Bad news: It looks like with plugins applied, this branch does make parsing a bit slower. Currently, plugins work by writing functions directly to the instance. I have modified this to instead just create a class, and never directly assign to an instance. Here are my measurements parsing
It looks like the existence of instance functions was making it run significantly slower, but moving that all into a prototype brought the time back down. There is of course still some increase in time due to the actual work that the plugin does. Shall I make a pull request doing just this? (UPDATE: #459) |
Closing since this has been broken into many separate PRs. #459 Convert each plugin to a function from a class to an overriding class |
This change enables type-checking in all
src
files (viaall=true
in.flowconfig
).Two big changes were needed:
Parser.prototype.foo = function () { ... }
) doesn't get a type-checkedthis
. Changed these toParser.mixin(class extends Parser { ... }
, and did the actual prototype assignment inmixin
.parser.extend
, a plugin is now a function(superClass: Class<Parser>): Class<Parser> => class extends superClass { ... }
, andparser.usePlugin
does the actual extending (and setting ofsuper
).Other than those, I tried as much as possible to keep the code as it is, and just add type annotations and comments.
Notes:
parserTypes.js
or they are invisible to the outside.indent
rule so that it can get a readable diff. Indenting could be fixed in another PR.[key: string]: any
onNode
, since often a node will be downcast to another node type and writing all those downcasts would be a pain.estree.js
contains lots of$FlowIgnore
since we're changing the node to a different type.throw
in front ofthis.raise(...)
andthis.unexpected(...)
so that control-flow analysis can know about these.