add type inferrence that expires when a binding is reassigned
This commit is contained in:
@@ -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
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user