Support Flow's proto modifier syntax for declared classes (#7978)

<!--
Before making a PR please make sure to read our contributing guidelines
https://github.com/babel/babel/blob/master/CONTRIBUTING.md

For issue references: Add a comma-separated list of a [closing word](https://help.github.com/articles/closing-issues-via-commit-messages/) followed by the ticket number fixed by the PR. It should be underlined in the preview if done correctly.
-->

| Q                        | A <!--(Can use an emoji 👍) -->
| ------------------------ | ---
| Fixed Issues?            | <!-- remove the (`) quotes to link the issues -->
| Patch: Bug Fix?          |
| Major: Breaking Change?  | No
| Minor: New Feature?      | Yes
| Tests Added + Pass?      | Yes
| Documentation PR         | <!-- If so, add `[skip ci]` to your commit message to skip CI -->
| Any Dependency Changes?  |
| License                  | MIT

See eb815be907 for more information about this feature.
    
The proto modifier indicates that a property declared using `x: T` syntax is actually present on the prototype object of the class, rather than an own property.
    
The proto and static modifiers are mutually exclusive, as class declarations don't simultaneously define the static prototype object, as they do the instance prototype.
    
This syntax is only supported on declared classes, not object types, interfaces, or runtime class declarations, and as such should only appear in library definitions.
This commit is contained in:
Sam Goldman 2018-05-25 21:40:56 +01:00 committed by Brian Ng
parent 90566103a6
commit f0283572a5
70 changed files with 624 additions and 6 deletions

View File

@ -472,6 +472,10 @@ export function ObjectTypeIndexer(node: Object) {
} }
export function ObjectTypeProperty(node: Object) { export function ObjectTypeProperty(node: Object) {
if (node.proto) {
this.word("proto");
this.space();
}
if (node.static) { if (node.static) {
this.word("static"); this.word("static");
this.space(); this.space();

View File

@ -427,7 +427,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// Interfaces // Interfaces
flowParseInterfaceish(node: N.FlowDeclare, isClass?: boolean): void { flowParseInterfaceish(
node: N.FlowDeclare,
isClass?: boolean = false,
): void {
node.id = this.flowParseRestrictedIdentifier(/*liberal*/ !isClass); node.id = this.flowParseRestrictedIdentifier(/*liberal*/ !isClass);
if (this.isRelational("<")) { if (this.isRelational("<")) {
@ -460,7 +463,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} while (this.eat(tt.comma)); } while (this.eat(tt.comma));
} }
node.body = this.flowParseObjectType(true, false, false); node.body = this.flowParseObjectType(true, false, false, isClass);
} }
flowParseInterfaceExtends(): N.FlowInterfaceExtends { flowParseInterfaceExtends(): N.FlowInterfaceExtends {
@ -653,7 +656,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} while (this.eat(tt.comma)); } while (this.eat(tt.comma));
} }
node.body = this.flowParseObjectType(true, false, false); node.body = this.flowParseObjectType(true, false, false, false);
return this.finishNode(node, "InterfaceTypeAnnotation"); return this.finishNode(node, "InterfaceTypeAnnotation");
} }
@ -755,6 +758,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
allowStatic: boolean, allowStatic: boolean,
allowExact: boolean, allowExact: boolean,
allowSpread: boolean, allowSpread: boolean,
allowProto: boolean,
): N.FlowObjectTypeAnnotation { ): N.FlowObjectTypeAnnotation {
const oldInType = this.state.inType; const oldInType = this.state.inType;
this.state.inType = true; this.state.inType = true;
@ -782,8 +786,19 @@ export default (superClass: Class<Parser>): Class<Parser> =>
while (!this.match(endDelim)) { while (!this.match(endDelim)) {
let isStatic = false; let isStatic = false;
let protoStart: ?number = null;
const node = this.startNode(); const node = this.startNode();
if (allowProto && this.isContextual("proto")) {
const lookahead = this.lookahead();
if (lookahead.type !== tt.colon && lookahead.type !== tt.question) {
this.next();
protoStart = this.state.start;
allowStatic = false;
}
}
if (allowStatic && this.isContextual("static")) { if (allowStatic && this.isContextual("static")) {
const lookahead = this.lookahead(); const lookahead = this.lookahead();
@ -797,6 +812,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
const variance = this.flowParseVariance(); const variance = this.flowParseVariance();
if (this.eat(tt.bracketL)) { if (this.eat(tt.bracketL)) {
if (protoStart != null) {
this.unexpected(protoStart);
}
if (this.eat(tt.bracketL)) { if (this.eat(tt.bracketL)) {
if (variance) { if (variance) {
this.unexpected(variance.start); this.unexpected(variance.start);
@ -810,6 +828,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
); );
} }
} else if (this.match(tt.parenL) || this.isRelational("<")) { } else if (this.match(tt.parenL) || this.isRelational("<")) {
if (protoStart != null) {
this.unexpected(protoStart);
}
if (variance) { if (variance) {
this.unexpected(variance.start); this.unexpected(variance.start);
} }
@ -835,6 +856,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
this.flowParseObjectTypeProperty( this.flowParseObjectTypeProperty(
node, node,
isStatic, isStatic,
protoStart,
variance, variance,
kind, kind,
allowSpread, allowSpread,
@ -857,6 +879,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
flowParseObjectTypeProperty( flowParseObjectTypeProperty(
node: N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty, node: N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty,
isStatic: boolean, isStatic: boolean,
protoStart: ?number,
variance: ?N.FlowVariance, variance: ?N.FlowVariance,
kind: string, kind: string,
allowSpread: boolean, allowSpread: boolean,
@ -868,6 +891,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
"Spread operator cannot appear in class or interface definitions", "Spread operator cannot appear in class or interface definitions",
); );
} }
if (protoStart != null) {
this.unexpected(protoStart);
}
if (variance) { if (variance) {
this.unexpected( this.unexpected(
variance.start, variance.start,
@ -881,6 +907,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} else { } else {
node.key = this.flowParseObjectPropertyKey(); node.key = this.flowParseObjectPropertyKey();
node.static = isStatic; node.static = isStatic;
node.proto = protoStart != null;
node.kind = kind; node.kind = kind;
let optional = false; let optional = false;
@ -888,6 +915,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// This is a method property // This is a method property
node.method = true; node.method = true;
if (protoStart != null) {
this.unexpected(protoStart);
}
if (variance) { if (variance) {
this.unexpected(variance.start); this.unexpected(variance.start);
} }
@ -1116,10 +1146,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
); );
case tt.braceL: case tt.braceL:
return this.flowParseObjectType(false, false, true); return this.flowParseObjectType(false, false, true, false);
case tt.braceBarL: case tt.braceBarL:
return this.flowParseObjectType(false, true, true); return this.flowParseObjectType(false, true, true, false);
case tt.bracketL: case tt.bracketL:
return this.flowParseTupleType(); return this.flowParseTupleType();

View File

@ -284,6 +284,7 @@
"name": "y" "name": "y"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "get", "kind": "get",
"method": true, "method": true,
"value": { "value": {
@ -181,6 +182,7 @@
"name": "b" "name": "b"
}, },
"static": false, "static": false,
"proto": false,
"kind": "set", "kind": "set",
"method": true, "method": true,
"value": { "value": {
@ -302,6 +304,7 @@
"value": "c" "value": "c"
}, },
"static": false, "static": false,
"proto": false,
"kind": "get", "kind": "get",
"method": true, "method": true,
"value": { "value": {
@ -374,6 +377,7 @@
"value": "d" "value": "d"
}, },
"static": false, "static": false,
"proto": false,
"kind": "set", "kind": "set",
"method": true, "method": true,
"value": { "value": {
@ -495,6 +499,7 @@
"value": 1 "value": 1
}, },
"static": false, "static": false,
"proto": false,
"kind": "get", "kind": "get",
"method": true, "method": true,
"value": { "value": {
@ -567,6 +572,7 @@
"value": 2 "value": 2
}, },
"static": false, "static": false,
"proto": false,
"kind": "set", "kind": "set",
"method": true, "method": true,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "static" "name": "static"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -161,6 +162,7 @@
"name": "bar" "name": "bar"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -213,6 +215,7 @@
"name": "baz" "name": "baz"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -161,6 +162,7 @@
"name": "bar" "name": "bar"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -213,6 +215,7 @@
"name": "baz" "name": "baz"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -175,6 +175,7 @@
"name": "meth" "name": "meth"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -105,6 +105,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -158,6 +158,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -151,6 +151,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "foo" "name": "foo"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -181,6 +182,7 @@
"name": "x" "name": "x"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -254,6 +255,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -164,6 +165,7 @@
"name": "b" "name": "b"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -216,6 +218,7 @@
"name": "c" "name": "c"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "didAnimate" "name": "didAnimate"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -228,6 +228,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -124,6 +124,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -191,6 +191,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -158,6 +158,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -162,6 +162,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -214,6 +215,7 @@
"name": "y" "name": "y"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "length" "name": "length"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "static" "name": "static"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "@@iterator" "name": "@@iterator"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "@@asyncIterator" "name": "@@asyncIterator"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -126,6 +126,7 @@
"name": "@@iterator" "name": "@@iterator"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -126,6 +126,7 @@
"name": "@@asyncIterator" "name": "@@asyncIterator"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "@@iterator" "name": "@@iterator"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "@@asyncIterator" "name": "@@asyncIterator"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "m" "name": "m"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -124,6 +124,7 @@
"name": "type" "name": "type"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -202,6 +203,7 @@
"name": "type" "name": "type"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -529,6 +531,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -594,6 +597,7 @@
"name": "type" "name": "type"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -672,6 +676,7 @@
"name": "type" "name": "type"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -793,6 +798,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -858,6 +864,7 @@
"name": "type" "name": "type"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -936,6 +943,7 @@
"name": "type" "name": "type"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -188,6 +189,7 @@
"name": "y" "name": "y"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -453,6 +455,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -505,6 +508,7 @@
"name": "y" "name": "y"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -871,6 +875,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -921,6 +926,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -973,6 +979,7 @@
"name": "y" "name": "y"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -1033,6 +1040,7 @@
"name": "b" "name": "b"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -1401,6 +1409,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -1451,6 +1460,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -1503,6 +1513,7 @@
"name": "y" "name": "y"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -1563,6 +1574,7 @@
"name": "b" "name": "b"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "numVal" "name": "numVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "numVal" "name": "numVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "numVal" "name": "numVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -150,6 +150,7 @@
"name": "numVal" "name": "numVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "numVal" "name": "numVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -188,6 +189,7 @@
"name": "strVal" "name": "strVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "subObj" "name": "subObj"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -186,6 +187,7 @@
"name": "strVal" "name": "strVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "subObj" "name": "subObj"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -200,6 +201,7 @@
"name": "strVal" "name": "strVal"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "param1" "name": "param1"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -188,6 +189,7 @@
"name": "param2" "name": "param2"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "param1" "name": "param1"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -188,6 +189,7 @@
"name": "param2" "name": "param2"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "add" "name": "add"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "id" "name": "id"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -191,6 +191,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -191,6 +191,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -196,6 +196,7 @@
"name": "x" "name": "x"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -136,6 +136,7 @@
"name": "param1" "name": "param1"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -188,6 +189,7 @@
"name": "param2" "name": "param2"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -240,6 +242,7 @@
"name": "param3" "name": "param3"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -233,6 +234,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -390,6 +392,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -513,6 +516,7 @@
"name": "a" "name": "a"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -978,6 +982,7 @@
"name": "foo" "name": "foo"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -1104,6 +1109,7 @@
"name": "foo" "name": "foo"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -129,6 +129,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -304,6 +305,7 @@
"name": "p" "name": "p"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "foobar" "name": "foobar"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -214,6 +215,7 @@
"name": "delete" "name": "delete"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -316,6 +318,7 @@
"name": "yield" "name": "yield"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -418,6 +421,7 @@
"name": "do" "name": "do"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -520,6 +524,7 @@
"name": "foobar" "name": "foobar"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -622,6 +627,7 @@
"name": "delete" "name": "delete"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -724,6 +730,7 @@
"name": "yield" "name": "yield"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -826,6 +833,7 @@
"name": "do" "name": "do"
}, },
"static": true, "static": true,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "foobar" "name": "foobar"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -214,6 +215,7 @@
"name": "delete" "name": "delete"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -316,6 +318,7 @@
"name": "yield" "name": "yield"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -418,6 +421,7 @@
"name": "do" "name": "do"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -112,6 +112,7 @@
"name": "foobar" "name": "foobar"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -214,6 +215,7 @@
"name": "delete" "name": "delete"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -316,6 +318,7 @@
"name": "yield" "name": "yield"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -418,6 +421,7 @@
"name": "do" "name": "do"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -109,6 +109,7 @@
"name": "foobar" "name": "foobar"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -211,6 +212,7 @@
"name": "delete" "name": "delete"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -313,6 +315,7 @@
"name": "yield" "name": "yield"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {
@ -415,6 +418,7 @@
"name": "do" "name": "do"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": true, "method": true,
"value": { "value": {

View File

@ -246,6 +246,7 @@
"name": "xxx" "name": "xxx"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {
@ -298,6 +299,7 @@
"name": "yyy" "name": "yyy"
}, },
"static": false, "static": false,
"proto": false,
"kind": "init", "kind": "init",
"method": false, "method": false,
"value": { "value": {

View File

@ -1634,6 +1634,7 @@ Aliases: `Flow`, `UserWhitespacable`
- `variance`: `Variance` (default: `null`) - `variance`: `Variance` (default: `null`)
- `kind`: `"init" | "get" | "set"` (default: `null`) - `kind`: `"init" | "get" | "set"` (default: `null`)
- `optional`: `boolean` (default: `null`) - `optional`: `boolean` (default: `null`)
- `proto`: `boolean` (default: `null`)
- `static`: `boolean` (default: `null`) - `static`: `boolean` (default: `null`)
--- ---

View File

@ -321,6 +321,7 @@ defineType("ObjectTypeProperty", {
value: validateType("FlowType"), value: validateType("FlowType"),
kind: validate(assertOneOf("init", "get", "set")), kind: validate(assertOneOf("init", "get", "set")),
static: validate(assertValueType("boolean")), static: validate(assertValueType("boolean")),
proto: validate(assertValueType("boolean")),
optional: validate(assertValueType("boolean")), optional: validate(assertValueType("boolean")),
variance: validateOptionalType("Variance"), variance: validateOptionalType("Variance"),
}, },

View File

@ -0,0 +1,11 @@
declare class A {
proto: T;
}
declare class B {
proto x: T;
}
declare class C {
proto +x: T;
}

View File

@ -0,0 +1,433 @@
{
"type": "File",
"start": 0,
"end": 102,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 11,
"column": 1
}
},
"program": {
"type": "Program",
"start": 0,
"end": 102,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 11,
"column": 1
}
},
"sourceType": "module",
"body": [
{
"type": "DeclareClass",
"start": 0,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 14,
"end": 15,
"loc": {
"start": {
"line": 1,
"column": 14
},
"end": {
"line": 1,
"column": 15
},
"identifierName": "A"
},
"name": "A"
},
"typeParameters": null,
"extends": [],
"implements": [],
"mixins": [],
"body": {
"type": "ObjectTypeAnnotation",
"start": 16,
"end": 31,
"loc": {
"start": {
"line": 1,
"column": 16
},
"end": {
"line": 3,
"column": 1
}
},
"callProperties": [],
"properties": [
{
"type": "ObjectTypeProperty",
"start": 20,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 10
}
},
"key": {
"type": "Identifier",
"start": 20,
"end": 25,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 7
},
"identifierName": "proto"
},
"name": "proto"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
"type": "GenericTypeAnnotation",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 10
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 27,
"end": 28,
"loc": {
"start": {
"line": 2,
"column": 9
},
"end": {
"line": 2,
"column": 10
},
"identifierName": "T"
},
"name": "T"
}
},
"variance": null,
"optional": false
}
],
"indexers": [],
"internalSlots": [],
"exact": false
}
},
{
"type": "DeclareClass",
"start": 33,
"end": 66,
"loc": {
"start": {
"line": 5,
"column": 0
},
"end": {
"line": 7,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 47,
"end": 48,
"loc": {
"start": {
"line": 5,
"column": 14
},
"end": {
"line": 5,
"column": 15
},
"identifierName": "B"
},
"name": "B"
},
"typeParameters": null,
"extends": [],
"implements": [],
"mixins": [],
"body": {
"type": "ObjectTypeAnnotation",
"start": 49,
"end": 66,
"loc": {
"start": {
"line": 5,
"column": 16
},
"end": {
"line": 7,
"column": 1
}
},
"callProperties": [],
"properties": [
{
"type": "ObjectTypeProperty",
"start": 53,
"end": 63,
"loc": {
"start": {
"line": 6,
"column": 2
},
"end": {
"line": 6,
"column": 12
}
},
"key": {
"type": "Identifier",
"start": 59,
"end": 60,
"loc": {
"start": {
"line": 6,
"column": 8
},
"end": {
"line": 6,
"column": 9
},
"identifierName": "x"
},
"name": "x"
},
"static": false,
"proto": true,
"kind": "init",
"method": false,
"value": {
"type": "GenericTypeAnnotation",
"start": 62,
"end": 63,
"loc": {
"start": {
"line": 6,
"column": 11
},
"end": {
"line": 6,
"column": 12
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 62,
"end": 63,
"loc": {
"start": {
"line": 6,
"column": 11
},
"end": {
"line": 6,
"column": 12
},
"identifierName": "T"
},
"name": "T"
}
},
"variance": null,
"optional": false
}
],
"indexers": [],
"internalSlots": [],
"exact": false
}
},
{
"type": "DeclareClass",
"start": 68,
"end": 102,
"loc": {
"start": {
"line": 9,
"column": 0
},
"end": {
"line": 11,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 82,
"end": 83,
"loc": {
"start": {
"line": 9,
"column": 14
},
"end": {
"line": 9,
"column": 15
},
"identifierName": "C"
},
"name": "C"
},
"typeParameters": null,
"extends": [],
"implements": [],
"mixins": [],
"body": {
"type": "ObjectTypeAnnotation",
"start": 84,
"end": 102,
"loc": {
"start": {
"line": 9,
"column": 16
},
"end": {
"line": 11,
"column": 1
}
},
"callProperties": [],
"properties": [
{
"type": "ObjectTypeProperty",
"start": 88,
"end": 99,
"loc": {
"start": {
"line": 10,
"column": 2
},
"end": {
"line": 10,
"column": 13
}
},
"key": {
"type": "Identifier",
"start": 95,
"end": 96,
"loc": {
"start": {
"line": 10,
"column": 9
},
"end": {
"line": 10,
"column": 10
},
"identifierName": "x"
},
"name": "x"
},
"static": false,
"proto": true,
"kind": "init",
"method": false,
"value": {
"type": "GenericTypeAnnotation",
"start": 98,
"end": 99,
"loc": {
"start": {
"line": 10,
"column": 12
},
"end": {
"line": 10,
"column": 13
}
},
"typeParameters": null,
"id": {
"type": "Identifier",
"start": 98,
"end": 99,
"loc": {
"start": {
"line": 10,
"column": 12
},
"end": {
"line": 10,
"column": 13
},
"identifierName": "T"
},
"name": "T"
}
},
"variance": {
"type": "Variance",
"start": 94,
"end": 95,
"loc": {
"start": {
"line": 10,
"column": 8
},
"end": {
"line": 10,
"column": 9
}
},
"kind": "plus"
},
"optional": false
}
],
"indexers": [],
"internalSlots": [],
"exact": false
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,3 @@
interface I {
proto p: string;
}

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \":\" (2:8)"
}

View File

@ -0,0 +1 @@
type T = { proto p: string }

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \":\" (1:17)"
}

View File

@ -0,0 +1,3 @@
declare class C {
proto static p: T;
}

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \":\" (2:15)"
}

View File

@ -0,0 +1,3 @@
declare class C {
static proto p: T;
}

View File

@ -0,0 +1,3 @@
{
"throws": "Unexpected token, expected \":\" (2:15)"
}

View File

@ -37,4 +37,3 @@ numbers/underscored_float_whole.js
numbers/underscored_hex.js numbers/underscored_hex.js
numbers/underscored_number.js numbers/underscored_number.js
numbers/underscored_oct.js numbers/underscored_oct.js
types/declare_class/proto.js