From 0a4fc16ca02db4fbd3986e93061207bf5f9f76a2 Mon Sep 17 00:00:00 2001 From: Sebastian McKenzie Date: Fri, 13 Feb 2015 15:08:58 +1100 Subject: [PATCH] add type inferrence that expires when a binding is reassigned --- lib/6to5/traversal/scope.js | 52 +++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/lib/6to5/traversal/scope.js b/lib/6to5/traversal/scope.js index 40927123ac..979f6cfc31 100644 --- a/lib/6to5/traversal/scope.js +++ b/lib/6to5/traversal/scope.js @@ -185,16 +185,24 @@ Scope.prototype.inferType = function (node) { target = node.init; } + if (t.isArrayExpression(target)) { + return t.genericTypeAnnotation(t.identifier("Array")); + } + + if (t.isObjectExpression(target)) { + return; + } + + if (t.isLiteral(target)) { + return; + } + if (t.isCallExpression(target)) { // todo: resolve this to a return type } - if (t.isMemberExpression(target)) { - // todo: crawl this and find the correct type, bail on anything that we cannot possibly be 100% confident on - } - if (t.isIdentifier(target)) { - // todo + return; } }; @@ -217,7 +225,12 @@ Scope.prototype.assignType = function (name, type) { info.identifier.typeAnnotation = info.typeAnnotation = type; }; -Scope.prototype.getTypeAnnotation = function (key, id, node) { +Scope.prototype.getTypeAnnotation = function (name, id, node) { + var info = { + annotation: null, + inferred: false + }; + var type; if (id.typeAnnotation) { @@ -225,13 +238,16 @@ Scope.prototype.getTypeAnnotation = function (key, id, node) { } if (!type) { + info.inferred = true; type = this.inferType(node); } if (type) { if (t.isTypeAnnotation(type)) type = type.typeAnnotation; - return type; + info.annotation = type; } + + return info; }; Scope.prototype.toArray = function (node, i) { @@ -284,7 +300,14 @@ Scope.prototype.registerBindingReassignment = function (node) { var ids = t.getBindingIdentifiers(node); for (var name in ids) { var info = this.getBindingInfo(name); - if (info) info.reassigned = true; + if (info) { + info.reassigned = true; + + if (info.typeAnnotationInferred) { + // destroy the inferred typeAnnotation + info.typeAnnotation = null; + } + } } }; @@ -298,12 +321,15 @@ Scope.prototype.registerBinding = function (kind, node) { this.checkBlockScopedCollisions(kind, name, id); + var typeInfo = this.getTypeAnnotation(name, id, node); + this.bindings[name] = { - typeAnnotation: this.getTypeAnnotation(name, id, node), - reassigned: false, - identifier: id, - scope: this, - kind: kind + typeAnnotationInferred: typeInfo.inferred, + typeAnnotation: typeInfo.annotation, + reassigned: false, + identifier: id, + scope: this, + kind: kind }; } };