Skip to content

Commit

Permalink
Support Flow's proto modifier syntax for declared classes (babel#7978)
Browse files Browse the repository at this point in the history
<!--
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 facebook/flow@eb815be 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.
  • Loading branch information
samwgoldman authored and existentialism committed May 25, 2018
1 parent 814c931 commit 5514996
Show file tree
Hide file tree
Showing 56 changed files with 152 additions and 5 deletions.
40 changes: 35 additions & 5 deletions src/plugins/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>

// Interfaces

flowParseInterfaceish(node: N.FlowDeclare, isClass?: boolean): void {
flowParseInterfaceish(
node: N.FlowDeclare,
isClass?: boolean = false,
): void {
node.id = this.flowParseRestrictedIdentifier(/*liberal*/ !isClass);

if (this.isRelational("<")) {
Expand Down Expand Up @@ -460,7 +463,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} while (this.eat(tt.comma));
}

node.body = this.flowParseObjectType(true, false, false);
node.body = this.flowParseObjectType(true, false, false, isClass);
}

flowParseInterfaceExtends(): N.FlowInterfaceExtends {
Expand Down Expand Up @@ -653,7 +656,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} 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");
}
Expand Down Expand Up @@ -755,6 +758,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
allowStatic: boolean,
allowExact: boolean,
allowSpread: boolean,
allowProto: boolean,
): N.FlowObjectTypeAnnotation {
const oldInType = this.state.inType;
this.state.inType = true;
Expand Down Expand Up @@ -782,8 +786,19 @@ export default (superClass: Class<Parser>): Class<Parser> =>

while (!this.match(endDelim)) {
let isStatic = false;
let protoStart: ?number = null;
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")) {
const lookahead = this.lookahead();

Expand All @@ -797,6 +812,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
const variance = this.flowParseVariance();

if (this.eat(tt.bracketL)) {
if (protoStart != null) {
this.unexpected(protoStart);
}
if (this.eat(tt.bracketL)) {
if (variance) {
this.unexpected(variance.start);
Expand All @@ -810,6 +828,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
);
}
} else if (this.match(tt.parenL) || this.isRelational("<")) {
if (protoStart != null) {
this.unexpected(protoStart);
}
if (variance) {
this.unexpected(variance.start);
}
Expand All @@ -835,6 +856,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
this.flowParseObjectTypeProperty(
node,
isStatic,
protoStart,
variance,
kind,
allowSpread,
Expand All @@ -857,6 +879,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
flowParseObjectTypeProperty(
node: N.FlowObjectTypeProperty | N.FlowObjectTypeSpreadProperty,
isStatic: boolean,
protoStart: ?number,
variance: ?N.FlowVariance,
kind: string,
allowSpread: boolean,
Expand All @@ -868,6 +891,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
"Spread operator cannot appear in class or interface definitions",
);
}
if (protoStart != null) {
this.unexpected(protoStart);
}
if (variance) {
this.unexpected(
variance.start,
Expand All @@ -881,13 +907,17 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} else {
node.key = this.flowParseObjectPropertyKey();
node.static = isStatic;
node.proto = protoStart != null;
node.kind = kind;

let optional = false;
if (this.isRelational("<") || this.match(tt.parenL)) {
// This is a method property
node.method = true;

if (protoStart != null) {
this.unexpected(protoStart);
}
if (variance) {
this.unexpected(variance.start);
}
Expand Down Expand Up @@ -1116,10 +1146,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
);

case tt.braceL:
return this.flowParseObjectType(false, false, true);
return this.flowParseObjectType(false, false, true, false);

case tt.braceBarL:
return this.flowParseObjectType(false, true, true);
return this.flowParseObjectType(false, true, true, false);

case tt.bracketL:
return this.flowParseTupleType();
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/call-properties/3/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@
"name": "y"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/flow/class-properties/getter-setter/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "a"
},
"static": false,
"proto": false,
"kind": "get",
"method": true,
"value": {
Expand Down Expand Up @@ -181,6 +182,7 @@
"name": "b"
},
"static": false,
"proto": false,
"kind": "set",
"method": true,
"value": {
Expand Down Expand Up @@ -302,6 +304,7 @@
"value": "c"
},
"static": false,
"proto": false,
"kind": "get",
"method": true,
"value": {
Expand Down Expand Up @@ -374,6 +377,7 @@
"value": "d"
},
"static": false,
"proto": false,
"kind": "set",
"method": true,
"value": {
Expand Down Expand Up @@ -495,6 +499,7 @@
"value": 1
},
"static": false,
"proto": false,
"kind": "get",
"method": true,
"value": {
Expand Down Expand Up @@ -567,6 +572,7 @@
"value": 2
},
"static": false,
"proto": false,
"kind": "set",
"method": true,
"value": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "static"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/flow/comment/02-type-include/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -161,6 +162,7 @@
"name": "bar"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -213,6 +215,7 @@
"name": "baz"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/flow/comment/03-type-flow-include/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -161,6 +162,7 @@
"name": "bar"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -213,6 +215,7 @@
"name": "baz"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/declare-export/export-class/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"name": "meth"
},
"static": false,
"proto": false,
"kind": "init",
"method": true,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/declare-module/10/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": true,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/declare-module/5/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": true,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/declare-module/6/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": true,
"value": {
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/flow/declare-statements/10/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "foo"
},
"static": true,
"proto": false,
"kind": "init",
"method": true,
"value": {
Expand Down Expand Up @@ -181,6 +182,7 @@
"name": "x"
},
"static": true,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/flow/declare-statements/15/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -254,6 +255,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/flow/declare-statements/17/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "a"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -164,6 +165,7 @@
"name": "b"
},
"static": true,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -216,6 +218,7 @@
"name": "c"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/declare-statements/7/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "didAnimate"
},
"static": false,
"proto": false,
"kind": "init",
"method": true,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/declare-statements/9/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@
"name": "x"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/interface-types/basic/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
"name": "p"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
"name": "p"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/flow/interface-types/extends/output.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@
"name": "p"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
"name": "x"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down Expand Up @@ -214,6 +215,7 @@
"name": "y"
},
"static": true,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"name": "foo"
},
"static": false,
"proto": false,
"kind": "init",
"method": false,
"value": {
Expand Down
Loading

0 comments on commit 5514996

Please sign in to comment.