Add support for Flow def-site variance syntax

This syntax allows you to specify whether a type variable can appear in
a covariant or contravariant position, and is super useful for, say,
Promise.

Right now this is hacked in jankily, but in the next major release we
should stop using Identifier nodes for type parameters.
This commit is contained in:
Sam Goldman 2016-02-29 17:20:55 -08:00
parent 6adbe96bf1
commit b85d6c7e4a
3 changed files with 353 additions and 0 deletions

View File

@ -624,9 +624,23 @@ pp.flowParseTypeAnnotation = function () {
};
pp.flowParseTypeAnnotatableIdentifier = function (requireTypeAnnotation, canBeOptionalParam) {
let variance;
if (this.match(tt.plusMin)) {
if (this.state.value === "+") {
variance = "plus";
} else if (this.state.value === "-") {
variance = "minus";
}
this.eat(tt.plusMin);
}
let ident = this.parseIdentifier();
let isOptionalParam = false;
if (variance) {
ident.variance = variance;
}
if (canBeOptionalParam && this.eat(tt.question)) {
this.expect(tt.question);
isOptionalParam = true;

View File

@ -0,0 +1,3 @@
class C<+T,-U> {}
function f<+T,-U>() {}
type T<+T,-U> = {}

View File

@ -0,0 +1,336 @@
{
"type": "File",
"start": 0,
"end": 59,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 18
}
},
"program": {
"type": "Program",
"start": 0,
"end": 59,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 18
}
},
"sourceType": "module",
"body": [
{
"type": "ClassDeclaration",
"start": 0,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 17
}
},
"id": {
"type": "Identifier",
"start": 6,
"end": 7,
"loc": {
"start": {
"line": 1,
"column": 6
},
"end": {
"line": 1,
"column": 7
}
},
"name": "C"
},
"typeParameters": {
"type": "TypeParameterDeclaration",
"start": 7,
"end": 14,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 14
}
},
"params": [
{
"type": "Identifier",
"start": 9,
"end": 10,
"loc": {
"start": {
"line": 1,
"column": 9
},
"end": {
"line": 1,
"column": 10
}
},
"name": "T",
"variance": "plus"
},
{
"type": "Identifier",
"start": 12,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 1,
"column": 13
}
},
"name": "U",
"variance": "minus"
}
]
},
"superClass": null,
"body": {
"type": "ClassBody",
"start": 15,
"end": 17,
"loc": {
"start": {
"line": 1,
"column": 15
},
"end": {
"line": 1,
"column": 17
}
},
"body": []
}
},
{
"type": "FunctionDeclaration",
"start": 18,
"end": 40,
"loc": {
"start": {
"line": 2,
"column": 0
},
"end": {
"line": 2,
"column": 22
}
},
"id": {
"type": "Identifier",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 10
}
},
"name": "f"
},
"generator": false,
"expression": false,
"async": false,
"typeParameters": {
"type": "TypeParameterDeclaration",
"start": 28,
"end": 35,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 17
}
},
"params": [
{
"type": "Identifier",
"start": 30,
"end": 31,
"loc": {
"start": {
"line": 2,
"column": 12
},
"end": {
"line": 2,
"column": 13
}
},
"name": "T",
"variance": "plus"
},
{
"type": "Identifier",
"start": 33,
"end": 34,
"loc": {
"start": {
"line": 2,
"column": 15
},
"end": {
"line": 2,
"column": 16
}
},
"name": "U",
"variance": "minus"
}
]
},
"params": [],
"body": {
"type": "BlockStatement",
"start": 38,
"end": 40,
"loc": {
"start": {
"line": 2,
"column": 20
},
"end": {
"line": 2,
"column": 22
}
},
"body": [],
"directives": []
}
},
{
"type": "TypeAlias",
"start": 41,
"end": 59,
"loc": {
"start": {
"line": 3,
"column": 0
},
"end": {
"line": 3,
"column": 18
}
},
"id": {
"type": "Identifier",
"start": 46,
"end": 47,
"loc": {
"start": {
"line": 3,
"column": 5
},
"end": {
"line": 3,
"column": 6
}
},
"name": "T"
},
"typeParameters": {
"type": "TypeParameterDeclaration",
"start": 47,
"end": 54,
"loc": {
"start": {
"line": 3,
"column": 6
},
"end": {
"line": 3,
"column": 13
}
},
"params": [
{
"type": "Identifier",
"start": 49,
"end": 50,
"loc": {
"start": {
"line": 3,
"column": 8
},
"end": {
"line": 3,
"column": 9
}
},
"name": "T",
"variance": "plus"
},
{
"type": "Identifier",
"start": 52,
"end": 53,
"loc": {
"start": {
"line": 3,
"column": 11
},
"end": {
"line": 3,
"column": 12
}
},
"name": "U",
"variance": "minus"
}
]
},
"right": {
"type": "ObjectTypeAnnotation",
"start": 57,
"end": 59,
"loc": {
"start": {
"line": 3,
"column": 16
},
"end": {
"line": 3,
"column": 18
}
},
"callProperties": [],
"properties": [],
"indexers": []
}
}
],
"directives": []
}
}