6.0.0
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:
@@ -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 });
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user