I'm extremely stupid and didn't commit as I go. To anyone reading this
I'm extremely sorry. A lot of these changes are very broad and I plan on
releasing Babel 6.0.0 today live on stage at Ember Camp London so I'm
afraid I couldn't wait. If you're ever in London I'll buy you a beer
(or assorted beverage!) to make up for it, also I'll kiss your feet and
give you a back massage, maybe.
This commit is contained in:
Sebastian McKenzie
2015-10-29 17:51:24 +00:00
parent 3974dd762d
commit ae7d5367f1
1501 changed files with 16477 additions and 19786 deletions

View File

@@ -1,3 +1,5 @@
/* @flow */
import type NodePath from "./index";
import * as inferers from "./inferers";
import * as t from "babel-types";
@@ -6,10 +8,10 @@ import * as t from "babel-types";
* Infer the type of the current `NodePath`.
*/
export function getTypeAnnotation() {
export function getTypeAnnotation(): Object {
if (this.typeAnnotation) return this.typeAnnotation;
var type = this._getTypeAnnotation() || t.anyTypeAnnotation();
let type = this._getTypeAnnotation() || t.anyTypeAnnotation();
if (t.isTypeAnnotation(type)) type = type.typeAnnotation;
return this.typeAnnotation = type;
}
@@ -19,20 +21,20 @@ export function getTypeAnnotation() {
*/
export function _getTypeAnnotation(): ?Object {
var node = this.node;
let node = this.node;
if (!node) {
// handle initializerless variables, add in checks for loop initializers too
if (this.key === "init" && this.parentPath.isVariableDeclarator()) {
var declar = this.parentPath.parentPath;
var declarParent = declar.parentPath;
let declar = this.parentPath.parentPath;
let declarParent = declar.parentPath;
// for (var NODE in bar) {}
// for (let NODE in bar) {}
if (declar.key === "left" && declarParent.isForInStatement()) {
return t.stringTypeAnnotation();
}
// for (var NODE of bar) {}
// for (let NODE of bar) {}
if (declar.key === "left" && declarParent.isForOfStatement()) {
return t.anyTypeAnnotation();
}
@@ -47,7 +49,7 @@ export function _getTypeAnnotation(): ?Object {
return node.typeAnnotation;
}
var inferer = inferers[node.type];
let inferer = inferers[node.type];
if (inferer) {
return inferer.call(this, node);
}
@@ -58,7 +60,7 @@ export function _getTypeAnnotation(): ?Object {
}
}
export function isBaseType(baseName: string, soft?): boolean {
export function isBaseType(baseName: string, soft?: boolean): boolean {
return _isBaseType(baseName, this.getTypeAnnotation(), soft);
}
@@ -85,11 +87,11 @@ function _isBaseType(baseName: string, type?, soft?): boolean {
}
export function couldBeBaseType(name: string): boolean {
var type = this.getTypeAnnotation();
let type = this.getTypeAnnotation();
if (t.isAnyTypeAnnotation(type)) return true;
if (t.isUnionTypeAnnotation(type)) {
for (var type2 of (type.types: Array)) {
for (let type2 of (type.types: Array<Object>)) {
if (t.isAnyTypeAnnotation(type2) || _isBaseType(name, type2, true)) {
return true;
}
@@ -101,7 +103,7 @@ export function couldBeBaseType(name: string): boolean {
}
export function baseTypeStrictlyMatches(right: NodePath) {
var left = this.getTypeAnnotation();
let left = this.getTypeAnnotation();
right = right.getTypeAnnotation();
if (!t.isAnyTypeAnnotation(left) && t.isFlowBaseAnnotation(left)) {
@@ -110,6 +112,6 @@ export function baseTypeStrictlyMatches(right: NodePath) {
}
export function isGenericType(genericName: string): boolean {
var type = this.getTypeAnnotation();
let type = this.getTypeAnnotation();
return t.isGenericTypeAnnotation(type) && t.isIdentifier(type.id, { name: genericName });
}

View File

@@ -1,11 +1,14 @@
/* @flow */
import type NodePath from "../index";
import * as t from "babel-types";
export default function (node) {
export default function (node: Object) {
if (!this.isReferenced()) return;
// check if a binding exists of this value and if so then return a union type of all
// possible types that the binding could be
var binding = this.scope.getBinding(node.name);
let binding = this.scope.getBinding(node.name);
if (binding) {
if (binding.identifier.typeAnnotation) {
return binding.identifier.typeAnnotation;
@@ -25,17 +28,17 @@ export default function (node) {
}
function getTypeAnnotationBindingConstantViolations(path, name) {
var binding = path.scope.getBinding(name);
let binding = path.scope.getBinding(name);
var types = [];
let types = [];
path.typeAnnotation = t.unionTypeAnnotation(types);
var functionConstantViolations = [];
var constantViolations = getConstantViolationsBefore(binding, path, functionConstantViolations);
let functionConstantViolations = [];
let constantViolations = getConstantViolationsBefore(binding, path, functionConstantViolations);
var testType = getConditionalAnnotation(path, name);
let testType = getConditionalAnnotation(path, name);
if (testType) {
var testConstantViolations = getConstantViolationsBefore(binding, testType.ifStatement);
let testConstantViolations = getConstantViolationsBefore(binding, testType.ifStatement);
// remove constant violations observed before the IfStatement
constantViolations = constantViolations.filter((path) => testConstantViolations.indexOf(path) < 0);
@@ -47,11 +50,11 @@ function getTypeAnnotationBindingConstantViolations(path, name) {
if (constantViolations.length) {
// pick one constant from each scope which will represent the last possible
// control flow path that it could've taken/been
var rawConstantViolations = constantViolations.reverse();
var visitedScopes = [];
let rawConstantViolations = constantViolations.reverse();
let visitedScopes = [];
constantViolations = [];
for (let violation of (rawConstantViolations: Array)) {
var violationScope = violation.scope;
for (let violation of (rawConstantViolations: Array<NodePath>)) {
let violationScope = violation.scope;
if (visitedScopes.indexOf(violationScope) >= 0) continue;
visitedScopes.push(violationScope);
@@ -67,7 +70,7 @@ function getTypeAnnotationBindingConstantViolations(path, name) {
constantViolations = constantViolations.concat(functionConstantViolations);
// push on inferred types of violated paths
for (let violation of (constantViolations: Array)) {
for (let violation of (constantViolations: Array<NodePath>)) {
types.push(violation.getTypeAnnotation());
}
}
@@ -78,23 +81,23 @@ function getTypeAnnotationBindingConstantViolations(path, name) {
}
function getConstantViolationsBefore(binding, path, functions) {
var violations = binding.constantViolations.slice();
let violations = binding.constantViolations.slice();
violations.unshift(binding.path);
return violations.filter((violation) => {
violation = violation.resolve();
var status = violation._guessExecutionStatusRelativeTo(path);
let status = violation._guessExecutionStatusRelativeTo(path);
if (functions && status === "function") functions.push(violation);
return status === "before";
});
}
function inferAnnotationFromBinaryExpression(name, path) {
var operator = path.node.operator;
let operator = path.node.operator;
var right = path.get("right").resolve();
var left = path.get("left").resolve();
let right = path.get("right").resolve();
let left = path.get("left").resolve();
var target;
let target;
if (left.isIdentifier({ name })) {
target = right;
} else if (right.isIdentifier({ name })) {
@@ -113,8 +116,8 @@ function inferAnnotationFromBinaryExpression(name, path) {
}
//
var typeofPath;
var typePath;
let typeofPath;
let typePath;
if (left.isUnaryExpression({ operator: "typeof" })) {
typeofPath = left;
typePath = right;
@@ -129,7 +132,7 @@ function inferAnnotationFromBinaryExpression(name, path) {
if (!typePath.isLiteral()) return;
// and that it's a string so we can infer it
var typeValue = typePath.node.value;
let typeValue = typePath.node.value;
if (typeof typeValue !== "string") return;
// and that the argument of the typeof path references us!
@@ -140,7 +143,7 @@ function inferAnnotationFromBinaryExpression(name, path) {
}
function getParentConditionalPath(path) {
var parentPath;
let parentPath;
while (parentPath = path.parentPath) {
if (parentPath.isIfStatement() || parentPath.isConditionalExpression()) {
if (path.key === "test") {
@@ -155,12 +158,12 @@ function getParentConditionalPath(path) {
}
function getConditionalAnnotation(path, name) {
var ifStatement = getParentConditionalPath(path);
let ifStatement = getParentConditionalPath(path);
if (!ifStatement) return;
var test = ifStatement.get("test");
var paths = [test];
var types = [];
let test = ifStatement.get("test");
let paths = [test];
let types = [];
do {
let path = paths.shift().resolve();
@@ -171,7 +174,7 @@ function getConditionalAnnotation(path, name) {
}
if (path.isBinaryExpression()) {
var type = inferAnnotationFromBinaryExpression(name, path);
let type = inferAnnotationFromBinaryExpression(name, path);
if (type) types.push(type);
}
} while(paths.length);

View File

@@ -1,9 +1,11 @@
/* @flow */
import * as t from "babel-types";
export { default as Identifier } from "./inferer-reference";
export function VariableDeclarator() {
var id = this.get("id");
let id = this.get("id");
if (id.isIdentifier()) {
return this.get("init").getTypeAnnotation();
@@ -51,8 +53,8 @@ export function BinaryExpression(node) {
} else if (t.BOOLEAN_BINARY_OPERATORS.indexOf(operator) >= 0) {
return t.booleanTypeAnnotation();
} else if (operator === "+") {
var right = this.get("right");
var left = this.get("left");
let right = this.get("right");
let left = this.get("left");
if (left.isBaseType("number") && right.isBaseType("number")) {
// both numbers so this will be a number
@@ -99,13 +101,24 @@ export function UpdateExpression(node) {
}
}
export function Literal(node) {
var value = node.value;
if (typeof value === "string") return t.stringTypeAnnotation();
if (typeof value === "number") return t.numberTypeAnnotation();
if (typeof value === "boolean") return t.booleanTypeAnnotation();
if (value === null) return t.voidTypeAnnotation();
if (node.regex) return t.genericTypeAnnotation(t.identifier("RegExp"));
export function StringLiteral() {
return t.stringTypeAnnotation();
}
export function NumberLiteral() {
return t.numberTypeAnnotation();
}
export function BooleanLiteral() {
return t.booleanTypeAnnotation();
}
export function NullLiteral() {
return t.voidTypeAnnotation();
}
export function RegexLiteral() {
return t.genericTypeAnnotation(t.identifier("RegExp"));
}
export function ObjectExpression() {