use of com.google.javascript.jscomp.newtypes.QualifiedName in project closure-compiler by google.
the class NewTypeInference method analyzeLValueFwd.
private LValueResultFwd analyzeLValueFwd(Node expr, TypeEnv inEnv, JSType requiredType, boolean insideQualifiedName) {
LValueResultFwd lvalResult = null;
switch(expr.getToken()) {
case THIS:
{
mayWarnAboutGlobalThis(expr);
if (this.currentScope.hasThis()) {
lvalResult = new LValueResultFwd(inEnv, envGetType(inEnv, THIS_ID), this.currentScope.getDeclaredTypeOf(THIS_ID), new QualifiedName(THIS_ID));
} else {
lvalResult = new LValueResultFwd(inEnv, UNKNOWN, null, null);
}
break;
}
case NAME:
{
String varName = expr.getString();
JSType varType = analyzeExprFwd(expr, inEnv).type;
lvalResult = new LValueResultFwd(inEnv, varType, this.currentScope.getDeclaredTypeOf(varName), varType.hasNonScalar() ? new QualifiedName(varName) : null);
break;
}
case GETPROP:
case GETELEM:
{
Node obj = expr.getFirstChild();
Node prop = expr.getLastChild();
QualifiedName pname = expr.isGetProp() || prop.isString() ? new QualifiedName(prop.getString()) : null;
LValueResultFwd recvLvalue = analyzeReceiverLvalFwd(obj, pname, inEnv, requiredType);
if (!recvLvalue.type.isSubtypeOf(TOP_OBJECT)) {
EnvTypePair pair = analyzeExprFwd(prop, recvLvalue.env, requiredType);
lvalResult = new LValueResultFwd(pair.env, requiredType, null, null);
break;
}
JSType indexType = recvLvalue.type.getIndexType();
// (1) A getelem where the receiver is an IObject
if (expr.isGetElem() && indexType != null) {
lvalResult = analyzeIObjectElmLvalFwd(prop, recvLvalue, indexType);
break;
}
// (2) A getelem where the prop is a string literal is like a getprop
if (expr.isGetProp() || prop.isString()) {
lvalResult = analyzePropLValFwd(obj, pname, recvLvalue, requiredType, insideQualifiedName);
break;
}
// (3) All other getelems
// TODO(dimvar): there is some recomputation here; the receiver will be
// analyzed again. Some more refactoring can fix this.
EnvTypePair pair = analyzeExprFwd(expr, recvLvalue.env, requiredType);
lvalResult = new LValueResultFwd(pair.env, pair.type, null, null);
break;
}
case VAR:
{
// Can happen iff its parent is a for/in or for/of.
checkState(expr.getParent().isForIn() || expr.getParent().isForOf());
Node nameNode = expr.getFirstChild();
String name = nameNode.getString();
// For/in and for/of can never have rhs of its VAR
checkState(!nameNode.hasChildren());
maybeSetTypeI(nameNode, requiredType);
if (expr.getParent().isForIn()) {
return new LValueResultFwd(inEnv, STRING, null, new QualifiedName(name));
} else {
JSType declType = this.currentScope.getDeclaredTypeOf(name);
return new LValueResultFwd(inEnv, requiredType, declType, new QualifiedName(name));
}
}
default:
{
// Expressions that aren't lvalues should be handled because they may
// be, e.g., the left child of a getprop.
// We must check that they are not the direct lvalues.
checkState(insideQualifiedName);
EnvTypePair pair = analyzeExprFwd(expr, inEnv, requiredType);
return new LValueResultFwd(pair.env, pair.type, null, null);
}
}
maybeSetTypeI(expr, lvalResult.type);
mayWarnAboutUnknownType(expr, lvalResult.type);
return lvalResult;
}
use of com.google.javascript.jscomp.newtypes.QualifiedName in project closure-compiler by google.
the class NewTypeInference method isFunctionBind.
private boolean isFunctionBind(Node callee, TypeEnv env, boolean isFwd) {
if (NodeUtil.isFunctionBind(callee)) {
if (isFwd) {
analyzeExprFwdIgnoreResult(callee, env);
}
return true;
}
if (!callee.isGetProp() || !callee.isQualifiedName() || !callee.getLastChild().getString().equals("bind")) {
return false;
}
Node recv = callee.getFirstChild();
JSType recvType;
if (isFwd) {
recvType = analyzeExprFwd(recv, env).type;
maybeSetTypeI(callee, recvType.getProp(new QualifiedName("bind")));
} else {
recvType = analyzeExprBwd(recv, env).type;
}
return !recvType.isUnknown() && recvType.isSubtypeOf(commonTypes.topFunction());
}
use of com.google.javascript.jscomp.newtypes.QualifiedName in project closure-compiler by google.
the class NewTypeInference method analyzeEnumObjLitBwd.
private EnvTypePair analyzeEnumObjLitBwd(Node objLit, TypeEnv outEnv, JSType requiredType) {
if (objLit.getFirstChild() == null) {
return new EnvTypePair(outEnv, requiredType);
}
String pname = NodeUtil.getObjectLitKeyName(objLit.getFirstChild());
JSType enumeratedType = requiredType.getProp(new QualifiedName(pname)).getEnumeratedTypeOfEnumElement();
if (enumeratedType == null) {
return new EnvTypePair(outEnv, requiredType);
}
TypeEnv env = outEnv;
for (Node prop = objLit.getLastChild(); prop != null; prop = prop.getPrevious()) {
env = analyzeExprBwd(prop, env, enumeratedType).env;
}
return new EnvTypePair(env, requiredType);
}
use of com.google.javascript.jscomp.newtypes.QualifiedName in project closure-compiler by google.
the class SimpleInference method inferPropAccess.
private JSType inferPropAccess(Node recv, String pname, NTIScope scope) {
if (recv.isGetProp() && recv.getLastChild().getString().equals("prototype")) {
return inferPrototypeProperty(recv.getFirstChild(), pname, scope);
}
QualifiedName propQname = new QualifiedName(pname);
JSType recvType = null;
if (recv.isQualifiedName()) {
QualifiedName recvQname = QualifiedName.fromNode(recv);
Declaration decl = scope.getDeclaration(recvQname, false);
if (decl != null) {
EnumType et = decl.getEnum();
if (et != null && et.enumLiteralHasKey(pname)) {
return et.getPropType();
}
Namespace ns = decl.getNamespace();
if (ns != null) {
return inferDeclaration(ns.getDeclaration(propQname));
}
recvType = decl.getTypeOfSimpleDecl();
}
}
if (recvType == null) {
recvType = inferExprRecur(recv, scope);
}
if (recvType == null) {
return null;
}
if (recvType.isScalar()) {
recvType = recvType.autobox();
}
FunctionType ft = recvType.getFunTypeIfSingletonObj();
if (ft != null && pname.equals("call")) {
return this.commonTypes.fromFunctionType(ft.transformByCallProperty());
} else if (ft != null && pname.equals("apply")) {
return this.commonTypes.fromFunctionType(ft.transformByApplyProperty());
}
if (recvType.mayHaveProp(propQname)) {
return recvType.getProp(propQname);
}
return null;
}
use of com.google.javascript.jscomp.newtypes.QualifiedName in project closure-compiler by google.
the class SimpleInference method inferInstantiatedCallee.
FunctionType inferInstantiatedCallee(Node call, FunctionType calleeType, boolean bailForUntypedArguments, NTIScope scope) {
Node callee = call.getFirstChild();
Preconditions.checkArgument(calleeType.isGeneric(), "Expected generic type for %s but found %s", callee, calleeType);
// The receiver type is useful for inference when calleeType has a @this annotation
// that includes a type variable.
JSType recvType = null;
if (callee.isGetProp() && callee.getFirstChild().isQualifiedName()) {
Node recv = callee.getFirstChild();
QualifiedName recvQname = QualifiedName.fromNode(recv);
Declaration decl = scope.getDeclaration(recvQname, false);
if (decl != null) {
recvType = decl.getTypeOfSimpleDecl();
}
}
ImmutableList.Builder<JSType> argTypes = ImmutableList.builder();
for (Node argNode = call.getSecondChild(); argNode != null; argNode = argNode.getNext()) {
JSType t = inferExprRecur(argNode, scope);
if (t == null) {
if (bailForUntypedArguments && !argNode.isFunction()) {
// Used for @const inference, where we want to be strict.
return null;
} else {
// Used when inferring a signature for unannotated callbacks passed to generic
// functions. Whatever type variable we can't infer will become unknown.
t = this.commonTypes.BOTTOM;
}
}
argTypes.add(t);
}
return calleeType.instantiateGenericsFromArgumentTypes(recvType, argTypes.build());
}
Aggregations