private FunctionBuilder nativeConstructorBuilder(String name) { return new FunctionBuilder(this) .forNativeType() .forConstructor() .withName(name); }
/** * Creates a new function type based on an existing function type but * with a new return type. * @param existingFunctionType the existing function type. * @param returnType the new return type. */ public FunctionType createFunctionTypeWithNewReturnType( FunctionType existingFunctionType, JSType returnType) { return new FunctionBuilder(this) .copyFromOtherFunction(existingFunctionType) .withReturnType(returnType) .build(); }
/** * @param parameters the function's parameters or {@code null} to indicate that the parameter * types are unknown. * @param returnType the function's return type or {@code null} to indicate that the return type * is unknown. */ public FunctionType createFunctionType(JSType returnType, Node parameters) { return new FunctionBuilder(this).withParamsNode(parameters).withReturnType(returnType).build(); }
/** * Creates a new function type based on an existing function type but * with a new return type. * @param existingFunctionType the existing function type. * @param returnType the new return type. */ public FunctionType createFunctionTypeWithNewReturnType( FunctionType existingFunctionType, JSType returnType) { return new FunctionBuilder(this) .copyFromOtherFunction(existingFunctionType) .withReturnType(returnType) .build(); }
/** * @param parameters the function's parameters or {@code null} * to indicate that the parameter types are unknown. * @param returnType the function's return type or {@code null} to indicate * that the return type is unknown. */ public FunctionType createFunctionType( JSType returnType, Node parameters) { return new FunctionBuilder(this) .withParamsNode(parameters) .withReturnType(returnType) .build(); }
/** * Creates a function type in which {@code this} refers to an object instance. * * @param instanceType the type of {@code this} * @param returnType the function's return type * @param parameterTypes the parameters' types */ public JSType createFunctionTypeWithInstanceType(ObjectType instanceType, JSType returnType, List<JSType> parameterTypes) { Node paramsNode = createParameters(parameterTypes.toArray(new JSType[parameterTypes.size()])); return new FunctionBuilder(this) .withParamsNode(paramsNode) .withReturnType(returnType) .withTypeOfThis(instanceType) .build(); }
/** * Creates a function type in which {@code this} refers to an object instance. * * @param instanceType the type of {@code this} * @param returnType the function's return type * @param parameterTypes the parameters' types */ public JSType createFunctionTypeWithInstanceType(ObjectType instanceType, JSType returnType, List<JSType> parameterTypes) { Node paramsNode = createParameters(parameterTypes.toArray(new JSType[parameterTypes.size()])); return new FunctionBuilder(this) .withParamsNode(paramsNode) .withReturnType(returnType) .withTypeOfThis(instanceType) .build(); }
private FunctionType createNativeFunctionType( JSType returnType, Node parameters) { return new FunctionBuilder(this) .withParamsNode(parameters) .withReturnType(returnType) .forNativeType() .build(); }
private FunctionType createNativeFunctionType( JSType returnType, Node parameters) { return new FunctionBuilder(this) .withParamsNode(parameters) .withReturnType(returnType) .forNativeType() .build(); }
private FunctionType nativeInterface(String name, TemplateType... templateKeys) { FunctionBuilder builder = new FunctionBuilder(this) .forNativeType() .forInterface() .withName(name); if (templateKeys.length > 0) { builder.withTemplateKeys(templateKeys); } return builder.build(); } }
private SuperPropertyWrapperInfo createNewInfo(Node firstSuperDotPropertyNode) { checkArgument(firstSuperDotPropertyNode.isGetProp(), firstSuperDotPropertyNode); String propertyName = firstSuperDotPropertyNode.getLastChild().getString(); JSType propertyType = firstSuperDotPropertyNode.getJSType(); final String wrapperFunctionName = ASYNC_SUPER_PROP_GETTER_PREFIX + propertyName; final JSType wrapperFunctionType; if (propertyType == null) { // type checking hasn't run, so we don't need type information. wrapperFunctionType = null; } else { wrapperFunctionType = new FunctionBuilder(registry).withReturnType(propertyType).build(); } return new SuperPropertyWrapperInfo( firstSuperDotPropertyNode, wrapperFunctionName, wrapperFunctionType); }
/** * Creates an interface function type. * * @param name the function's name * @param source the node defining this function. Its type ({@link Node#getToken()}) must be * {@link Token#FUNCTION}. * @param templateKeys the templatized types for the interface. */ public FunctionType createInterfaceType( String name, Node source, ImmutableList<TemplateType> templateKeys, boolean struct) { FunctionType fn = new FunctionBuilder(this) .forInterface() .withName(name) .withSourceNode(source) .withEmptyParams() .withTemplateKeys(templateKeys) .build(); if (struct) { fn.setStruct(); } return fn; }
/** Create a new constructor with the parameters and return type stripped. */ public final FunctionType forgetParameterAndReturnTypes() { FunctionType result = new FunctionBuilder(registry) .withName(getReferenceName()) .withSourceNode(source) .withTypeOfThis(getInstanceType()) .withKind(kind) .build(); result.setPrototypeBasedOn(getInstanceType()); return result; }
Node createZeroArgArrowFunctionForExpression(Node expression) { Node result = IR.arrowFunction(IR.name(""), IR.paramList(), expression); if (isAddingTypes()) { // It feels like we should be adding type-of-this here, but it should remain unknown, // because you're allowed to supply any kind of value of `this` when calling an arrow // function. It will just be ignored in favor of the `this` in the scope where the // arrow was defined. FunctionType functionType = new FunctionBuilder(registry) .withReturnType(expression.getJSTypeRequired()) .withParamsNode(IR.paramList()) .build(); result.setJSType(functionType); } return result; }
@Override public JSType getPropertyType(String name) { if (!hasOwnProperty(name)) { // Define the "call", "apply", and "bind" functions lazily. boolean isCall = "call".equals(name); boolean isBind = "bind".equals(name); if (isCall || isBind) { defineDeclaredProperty(name, getCallOrBindSignature(isCall), source); } else if ("apply".equals(name)) { // Define the "apply" function lazily. FunctionParamBuilder builder = new FunctionParamBuilder(registry); // ECMA-262 says that apply's second argument must be an Array // or an arguments object. We don't model the arguments object, // so let's just be forgiving for now. // TODO(nicksantos): Model the Arguments object. builder.addOptionalParams( registry.createNullableType(getTypeOfThis()), registry.createNullableType( registry.getNativeType(JSTypeNative.OBJECT_TYPE))); defineDeclaredProperty(name, new FunctionBuilder(registry) .withParamsNode(builder.build()) .withReturnType(getReturnType()) .withTemplateKeys(getTemplateTypeMap().getTemplateKeys()) .build(), source); } } return super.getPropertyType(name); }
@Override public final JSType getPropertyType(String name) { if (!hasOwnProperty(name)) { // Define the "call", "apply", and "bind" functions lazily. boolean isCall = "call".equals(name); boolean isBind = "bind".equals(name); if (isCall || isBind) { defineDeclaredProperty(name, getCallOrBindSignature(isCall), source); } else if ("apply".equals(name)) { // Define the "apply" function lazily. FunctionParamBuilder builder = new FunctionParamBuilder(registry); // ECMA-262 says that apply's second argument must be an Array // or an arguments object. We don't model the arguments object, // so let's just be forgiving for now. // TODO(nicksantos): Model the Arguments object. builder.addOptionalParams( registry.createNullableType(getTypeOfThis()), registry.createNullableType(registry.getNativeType(JSTypeNative.OBJECT_TYPE))); defineDeclaredProperty( name, new FunctionBuilder(registry) .withParamsNode(builder.build()) .withReturnType(getReturnType()) .withTemplateKeys(getTemplateTypeMap().getTemplateKeys()) .build(), source); } } return super.getPropertyType(name); }
/** * Take the current function type, and try to match the expected function * type. This is a form of backwards-inference, like record-type constraint * matching. */ private FunctionType matchFunction( FunctionType expectedType, FunctionType currentType, boolean declared) { if (declared) { // If the function was declared but it doesn't have a known "this" // but the expected type does, back fill it. if (currentType.getTypeOfThis().isUnknownType() && !expectedType.getTypeOfThis().isUnknownType()) { FunctionType replacement = new FunctionBuilder(registry) .copyFromOtherFunction(currentType) .withTypeOfThis(expectedType.getTypeOfThis()) .build(); return replacement; } } else { // For now, we just make sure the current type has enough // arguments to match the expected type, and return the // expected type if it does. if (currentType.getMaxArguments() <= expectedType.getMaxArguments()) { return expectedType; } } return currentType; }
/** * Take the current function type, and try to match the expected function * type. This is a form of backwards-inference, like record-type constraint * matching. */ private FunctionType matchFunction( FunctionType expectedType, FunctionType currentType, boolean declared) { if (declared) { // If the function was declared but it doesn't have a known "this" // but the expected type does, back fill it. if (currentType.getTypeOfThis().isUnknownType() && !expectedType.getTypeOfThis().isUnknownType()) { FunctionType replacement = new FunctionBuilder(registry) .copyFromOtherFunction(currentType) .withTypeOfThis(expectedType.getTypeOfThis()) .build(); return replacement; } } else { // For now, we just make sure the current type has enough // arguments to match the expected type, and return the // expected type if it does. if (currentType.getMaxArity() <= expectedType.getMaxArity()) { return expectedType; } } return currentType; }
/** * Get the return value of calling "bind" on this function with the specified number of arguments. * * <p>If -1 is passed, then we will return a result that accepts any parameters. */ public final FunctionType getBindReturnType(int argsToBind) { FunctionBuilder builder = new FunctionBuilder(registry) .withReturnType(getReturnType()) .withTemplateKeys(getTemplateTypeMap().getTemplateKeys()); if (argsToBind >= 0) { Node origParams = getParametersNode(); if (origParams != null) { Node params = origParams.cloneTree(); for (int i = 1; i < argsToBind && params.getFirstChild() != null; i++) { if (params.getFirstChild().isVarArgs()) { break; } params.removeFirstChild(); } builder.withParamsNode(params); } } return builder.build(); }
/** * Get the return value of calling "bind" on this function * with the specified number of arguments. * * If -1 is passed, then we will return a result that accepts * any parameters. */ public FunctionType getBindReturnType(int argsToBind) { FunctionBuilder builder = new FunctionBuilder(registry) .withReturnType(getReturnType()) .withTemplateKeys(getTemplateTypeMap().getTemplateKeys()); if (argsToBind >= 0) { Node origParams = getParametersNode(); if (origParams != null) { Node params = origParams.cloneTree(); for (int i = 1; i < argsToBind && params.getFirstChild() != null; i++) { if (params.getFirstChild().isVarArgs()) { break; } params.removeFirstChild(); } builder.withParamsNode(params); } } return builder.build(); }