Support extends syntax for Flow type parameter bounds#17857
Conversation
|
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/61127 |
|
commit: |
Flow is migrating type parameter bounds from colon syntax (`T: S`) to `extends` syntax (`T extends S`). Update the parser to accept both delimiters, producing the same TypeAnnotation bound node in either case.
211ffa3 to
5b9249d
Compare
JLHwung
left a comment
There was a problem hiding this comment.
Thank you for your contribution.
| @@ -0,0 +1 @@ | |||
| class A<T extends Foo> {} | |||
There was a problem hiding this comment.
Is it semantically equivalent to
class A<T: Foo> {}?
The babel-generator currently always generates : type for extends type because the AST is the same. Since extends type might break old flow versions, we may have to add a new babel-generator option to always emit extends type now that flow is migrating to the extends syntax.
| // @ts-expect-error migrate to Babel types | ||
| node.bound = ident.typeAnnotation; | ||
|
|
||
| if (this.match(tt.colon) || this.match(tt._extends)) { |
There was a problem hiding this comment.
| if (this.match(tt.colon) || this.match(tt._extends)) { | |
| if (this.match(tt.colon) || this.isContextual(tt._extends)) { |
The parser should reject invalid production such as
class A<T \u65xtends Foo> {}| this.next(); | ||
| boundNode.typeAnnotation = this.flowParseType(); | ||
| // @ts-expect-error migrate to Babel types | ||
| node.bound = this.finishNode(boundNode, "TypeAnnotation"); |
There was a problem hiding this comment.
| node.bound = this.finishNode(boundNode, "TypeAnnotation"); | |
| node.bound = this.finishNode(boundNode, "TypeAnnotation"); | |
| this.resetEndLocation(ident); |
The end location should be adjusted such that the range of the identifier node covers its .bound child node.
Could you add a test case for comment attachment? For example,
function F</* 0 */T/* 1 */extends/* 2 */Foo/* 3 */>() {}where 0 should be the leading comment of the identifier node, 3 should be the trailing comment.
|
|
||
| const variance = this.flowParseVariance(); | ||
|
|
||
| const ident = this.flowParseTypeAnnotatableIdentifier(); |
There was a problem hiding this comment.
With this change, the flowParseTypeAnnotatableIdentifier will be always called with allowPrimitiveOverride: true, could you also simplify its signature?
Summary
T: S) toextendssyntax (T extends S)flowParseTypeParameterto accept both:andextendsas bound delimiters, producing the sameTypeAnnotationbound node in either caseflowParseTypeAnnotatableIdentifiercall withflowParseRestrictedIdentifierdirectly, then handle the bound inline with an OR check for both token typesTest plan
extendssyntax: class, function, type alias with default, and multiple type params