use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.
the class SymbolTable method getAllSymbolsForType.
/**
* Gets all symbols associated with the given type.
* For union types, this may be multiple symbols.
* For instance types, this will return the constructor of
* that instance.
*/
public List<Symbol> getAllSymbolsForType(JSType type) {
if (type == null) {
return ImmutableList.of();
}
UnionType unionType = type.toMaybeUnionType();
if (unionType != null) {
List<Symbol> result = new ArrayList<>(2);
for (JSType alt : unionType.getAlternates()) {
// Our type system never has nested unions.
Symbol altSym = getSymbolForTypeHelper(alt, true);
if (altSym != null) {
result.add(altSym);
}
}
return result;
}
Symbol result = getSymbolForTypeHelper(type, true);
return result == null ? ImmutableList.of() : ImmutableList.of(result);
}
use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.
the class TypeInference method updateBind.
/**
* When "bind" is called on a function, we infer the type of the returned
* "bound" function by looking at the number of parameters in the call site.
* We also infer the "this" type of the target, if it's a function expression.
*/
private void updateBind(Node n) {
CodingConvention.Bind bind = compiler.getCodingConvention().describeFunctionBind(n, false, true);
if (bind == null) {
return;
}
Node target = bind.target;
FunctionType callTargetFn = getJSType(target).restrictByNotNullOrUndefined().toMaybeFunctionType();
if (callTargetFn == null) {
return;
}
if (bind.thisValue != null && target.isFunction()) {
JSType thisType = getJSType(bind.thisValue);
if (thisType.toObjectType() != null && !thisType.isUnknownType() && callTargetFn.getTypeOfThis().isUnknownType()) {
callTargetFn = new FunctionBuilder(registry).copyFromOtherFunction(callTargetFn).withTypeOfThis(thisType.toObjectType()).build();
target.setJSType(callTargetFn);
}
}
n.setJSType(callTargetFn.getBindReturnType(// getBindReturnType expects the 'this' argument to be included.
bind.getBoundParameterCount() + 1));
}
use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.
the class TypeInference method getPropertyType.
private JSType getPropertyType(JSType objType, String propName, Node n, FlowScope scope) {
// We often have a couple of different types to choose from for the
// property. Ordered by accuracy, we have
// 1) A locally inferred qualified name (which is in the FlowScope)
// 2) A globally declared qualified name (which is in the FlowScope)
// 3) A property on the owner type (which is on objType)
// 4) A name in the type registry (as a last resort)
JSType propertyType = null;
boolean isLocallyInferred = false;
// Scopes sometimes contain inferred type info about qualified names.
String qualifiedName = n.getQualifiedName();
StaticTypedSlot<JSType> var = qualifiedName != null ? scope.getSlot(qualifiedName) : null;
if (var != null) {
JSType varType = var.getType();
if (varType != null) {
boolean isDeclared = !var.isTypeInferred();
isLocallyInferred = (var != currentScope.getSlot(qualifiedName));
if (isDeclared || isLocallyInferred) {
propertyType = varType;
}
}
}
if (propertyType == null && objType != null) {
JSType foundType = objType.findPropertyType(propName);
if (foundType != null) {
propertyType = foundType;
}
}
if (propertyType != null && objType != null) {
JSType restrictedObjType = objType.restrictByNotNullOrUndefined();
if (!restrictedObjType.getTemplateTypeMap().isEmpty() && propertyType.hasAnyTemplateTypes()) {
TemplateTypeMap typeMap = restrictedObjType.getTemplateTypeMap();
TemplateTypeMapReplacer replacer = new TemplateTypeMapReplacer(registry, typeMap);
propertyType = propertyType.visit(replacer);
}
}
if ((propertyType == null || propertyType.isUnknownType()) && qualifiedName != null) {
// If we find this node in the registry, then we can infer its type.
ObjectType regType = ObjectType.cast(registry.getType(qualifiedName));
if (regType != null) {
propertyType = regType.getConstructor();
}
}
if (propertyType == null) {
return unknownType;
} else if (propertyType.isEquivalentTo(unknownType) && isLocallyInferred) {
// then use CHECKED_UNKNOWN_TYPE instead to indicate that.
return getNativeType(CHECKED_UNKNOWN_TYPE);
} else {
return propertyType;
}
}
use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.
the class TypeInference method dereferencePointer.
/**
* If we access a property of a symbol, then that symbol is not
* null or undefined.
*/
private FlowScope dereferencePointer(Node n, FlowScope scope) {
if (n.isQualifiedName()) {
JSType type = getJSType(n);
JSType narrowed = type.restrictByNotNullOrUndefined();
if (!type.equals(narrowed)) {
scope = narrowScope(scope, n, narrowed);
}
}
return scope;
}
use of com.google.javascript.rhino.jstype.JSType in project closure-compiler by google.
the class TypeInference method maybeResolveTemplatedType.
private void maybeResolveTemplatedType(JSType paramType, JSType argType, Map<TemplateType, JSType> resolvedTypes, Set<JSType> seenTypes) {
if (paramType.isTemplateType()) {
// example: @param {T}
resolvedTemplateType(resolvedTypes, paramType.toMaybeTemplateType(), argType);
} else if (paramType.isUnionType()) {
// example: @param {Array.<T>|NodeList|Arguments|{length:number}}
UnionType unionType = paramType.toMaybeUnionType();
for (JSType alernative : unionType.getAlternates()) {
maybeResolveTemplatedType(alernative, argType, resolvedTypes, seenTypes);
}
} else if (paramType.isFunctionType()) {
FunctionType paramFunctionType = paramType.toMaybeFunctionType();
FunctionType argFunctionType = argType.restrictByNotNullOrUndefined().collapseUnion().toMaybeFunctionType();
if (argFunctionType != null && argFunctionType.isSubtype(paramType)) {
// infer from return type of the function type
maybeResolveTemplatedType(paramFunctionType.getTypeOfThis(), argFunctionType.getTypeOfThis(), resolvedTypes, seenTypes);
// infer from return type of the function type
maybeResolveTemplatedType(paramFunctionType.getReturnType(), argFunctionType.getReturnType(), resolvedTypes, seenTypes);
// infer from parameter types of the function type
maybeResolveTemplateTypeFromNodes(paramFunctionType.getParameters(), argFunctionType.getParameters(), resolvedTypes, seenTypes);
}
} else if (paramType.isRecordType() && !paramType.isNominalType()) {
// example: @param {{foo:T}}
if (seenTypes.add(paramType)) {
ObjectType paramRecordType = paramType.toObjectType();
ObjectType argObjectType = argType.restrictByNotNullOrUndefined().toObjectType();
if (argObjectType != null && !argObjectType.isUnknownType() && !argObjectType.isEmptyType()) {
Set<String> names = paramRecordType.getPropertyNames();
for (String name : names) {
if (paramRecordType.hasOwnProperty(name) && argObjectType.hasProperty(name)) {
maybeResolveTemplatedType(paramRecordType.getPropertyType(name), argObjectType.getPropertyType(name), resolvedTypes, seenTypes);
}
}
}
seenTypes.remove(paramType);
}
} else if (paramType.isTemplatizedType()) {
// example: @param {Array<T>}
TemplatizedType templatizedParamType = paramType.toMaybeTemplatizedType();
int keyCount = templatizedParamType.getTemplateTypes().size();
// types with no type arguments.
if (keyCount > 0) {
ObjectType referencedParamType = templatizedParamType.getReferencedType();
JSType argObjectType = argType.restrictByNotNullOrUndefined().collapseUnion();
if (argObjectType.isSubtypeOf(referencedParamType)) {
// If the argument type is a subtype of the parameter type, resolve any
// template types amongst their templatized types.
TemplateTypeMap paramTypeMap = paramType.getTemplateTypeMap();
ImmutableList<TemplateType> keys = paramTypeMap.getTemplateKeys();
TemplateTypeMap argTypeMap = argObjectType.getTemplateTypeMap();
for (int index = keys.size() - keyCount; index < keys.size(); index++) {
TemplateType key = keys.get(index);
maybeResolveTemplatedType(paramTypeMap.getResolvedTemplateType(key), argTypeMap.getResolvedTemplateType(key), resolvedTypes, seenTypes);
}
}
}
}
}
Aggregations