@Override public Void caseFunctionType(FunctionType type) { if (isLiteralFunction(type)) { emit("Function"); return null; } if (type.isConstructor() && !"Function".equals(type.getDisplayName())) { visitConstructorFunctionDeclaration(type); return null; } visitFunctionParameters(type); JSType returnType = type.getReturnType(); if (returnType != null) { emit("=>"); // Closure conflates 'undefined' and 'void', and in general visitType always emits // `undefined` // for that type. // In idiomatic TypeScript, `void` is used for function return types, and the // "void", // "undefined" types are not the same. if (returnType.isVoidType()) { emit("void"); } else { visitType(returnType); } } return null; }
if (isConstructor() || isInterface()) { FunctionType superClass = getSuperClassConstructor(); if (superClass != null) { superClass.addSubType(this); wasAddedToExtendedConstructorSubtypes = true; if (isInterface()) { for (ObjectType interfaceType : getExtendedInterfaces()) { if (interfaceType.getConstructor() != null) { interfaceType.getConstructor().addSubType(this); clearCachedValues();
/** * Given a constructor or an interface type and a property, finds the top-most superclass that has * the property defined (including this constructor). */ public final ObjectType getTopMostDefiningType(String propertyName) { checkState(isConstructor() || isInterface()); checkArgument(getInstanceType().hasProperty(propertyName)); FunctionType ctor = this; if (isInterface()) { return getInstanceType().getTopDefiningInterface(propertyName); } ObjectType topInstanceType = null; do { topInstanceType = ctor.getInstanceType(); ctor = ctor.getSuperClassConstructor(); } while (ctor != null && ctor.getPrototype().hasProperty(propertyName)); return topInstanceType; }
/** Copies all the information from another function type. */ public FunctionBuilder copyFromOtherFunction(FunctionType otherType) { this.name = otherType.getReferenceName(); this.sourceNode = otherType.getSource(); this.parametersNode = otherType.getParametersNode(); this.returnType = otherType.getReturnType(); this.typeOfThis = otherType.getTypeOfThis(); this.templateTypeMap = otherType.getTemplateTypeMap(); this.isConstructor = otherType.isConstructor(); this.isNativeType = otherType.isNativeObjectType(); return this; }
/** Returns the type of the getter, falling back on unknown if the return type was inferred. */ private JSType determineGetterType(FunctionType methodType) { // TODO(sdh): consider only falling back on unknown if the function body is empty? But we // need to not report a conflicting type error if there's different unknowns. return !methodType.isReturnTypeInferred() ? methodType.getReturnType() : unknownType; } } // end ClassScopeBuilder
@Override public void applySingletonGetterOld(FunctionType functionType, FunctionType getterType, ObjectType objectType) { functionType.defineDeclaredProperty("getInstance", getterType, functionType.getSource()); functionType.defineDeclaredProperty("instance_", objectType, functionType.getSource()); }
/** Copies all the information from another function type. */ public FunctionBuilder copyFromOtherFunction(FunctionType otherType) { int isNative = otherType.isNativeObjectType() ? IS_NATIVE : 0; int isAbstract = otherType.isAbstract() ? IS_ABSTRACT : 0; int inferredReturnType = otherType.isReturnTypeInferred() ? INFERRED_RETURN_TYPE : 0; this.name = otherType.getReferenceName(); this.sourceNode = otherType.getSource(); this.parametersNode = otherType.getParametersNode(); this.returnType = otherType.getReturnType(); this.typeOfThis = otherType.getTypeOfThis(); this.templateTypeMap = otherType.getTemplateTypeMap(); this.kind = otherType.getKind(); this.properties = isNative | isAbstract | inferredReturnType; return this; }
FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType()); String functionPrivateName = n.getFirstChild().getString(); if (functionType.isConstructor()) { FunctionType baseConstructor = functionType.getSuperClassConstructor(); if (baseConstructor != getNativeType(OBJECT_FUNCTION_TYPE) && baseConstructor != null && baseConstructor.isInterface()) { compiler.report( t.makeError(n, CONFLICTING_EXTENDED_TYPE, for (JSType baseInterface : functionType.getImplementedInterfaces()) { boolean badImplementedType = false; ObjectType baseInterfaceObj = ObjectType.cast(baseInterface); baseInterfaceObj.getConstructor(); if (interfaceConstructor != null && !interfaceConstructor.isInterface()) { badImplementedType = true; } else if (functionType.isInterface()) { for (ObjectType extInterface : functionType.getExtendedInterfaces()) { if (extInterface.getConstructor() != null && !extInterface.getConstructor().isInterface()) { compiler.report( t.makeError(n, CONFLICTING_EXTENDED_TYPE, if (functionType.getExtendedInterfacesCount() > 1) {
for (Node param : type.getParameters()) { visitOnce(param.getJSType()); visitOnce(type.getReturnType()); if (type.isInterface()) { for (JSType extendedType : type.getExtendedInterfaces()) { visitOnce(extendedType); if (type.isConstructor()) { for (JSType implementedType : type.getOwnImplementedInterfaces()) { visitOnce(implementedType); JSType superClass = type.getPrototype().getImplicitPrototype(); if (superClass != null) { visitOnce(superClass);
emitBreak(); if (type.isNominalConstructor() && !type.isInterface()) { emit("private noStructuralTyping_"); String suffix = type.hasDisplayName() ? escapeForJSProperty(type.getDisplayName()) : ""; emitNoSpace(suffix); emit(": any;"); if (type.isConstructor() && mustEmitConstructor(type) && !isPrivate(type.getJSDocInfo())) { maybeEmitJsDoc(type.getJSDocInfo(), /* ignoreParams */ false); JSType instanceType = type.getTypeOfThis(); checkArgument( instanceType.isObject(), if (type.isDict()) { emitIndexSignature( compiler.getTypeRegistry().getNativeType(STRING_TYPE), if (!type.isInterface()) { Set<String> staticProps = getTypePropertyNamesToEmit(type, true); visitStaticProperties(type, staticProps, /* isInNamespace*/ false);
@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); }
private void visitClassOrInterface(String name, FunctionType ftype) { Set<String> staticProps = getTypePropertyNamesToEmit(ftype, true); if (!staticProps.isEmpty() && ftype.isInterface()) { emitBreak(); if (ftype.isConstructor()) { } else if (ftype.isInterface()) { emit("interface"); } else { if (ftype.getExtendedInterfacesCount() > 0) { emit("extends"); Iterator<ObjectType> it = ftype.getExtendedInterfaces().iterator(); emitCommaSeparatedInterfaces(it); Iterator<ObjectType> it = ftype.getOwnImplementedInterfaces().iterator(); if (it.hasNext()) { emit("implements"); visitObjectType(ftype, ftype.getPrototype(), getTemplateTypeNames(ftype));
/** Gets the symbol for the prototype of the given constructor or interface. */ public Symbol getSymbolForInstancesOf(FunctionType fn) { checkState(fn.isConstructor() || fn.isInterface()); ObjectType pType = fn.getPrototype(); return getSymbolForName(fn.getSource(), pType.getReferenceName()); }
/** Gets the symbol for the given constructor or interface. */ public Symbol getSymbolDeclaredBy(FunctionType fn) { checkState(fn.isConstructor() || fn.isInterface()); ObjectType instanceType = fn.getInstanceType(); return getSymbolForName(fn.getSource(), instanceType.getReferenceName()); }
for (ObjectType extInterface : functionType.getExtendedInterfaces()) { if (extInterface.getConstructor() != null && !extInterface.getConstructor().isInterface()) { compiler.report( t.makeError(n, CONFLICTING_EXTENDED_TYPE, "interface", getBestFunctionName(n))); if (functionType.getExtendedInterfacesCount() > 1) { for (ObjectType interfaceType : functionType.getExtendedInterfaces()) { currentProperties.clear(); checkInterfaceConflictProperties(t, n, getBestFunctionName(n), List<FunctionType> loopPath = functionType.checkExtendsLoop(); if (loopPath != null) { String strPath = ""; for (int i = 0; i < loopPath.size() - 1; i++) { strPath += loopPath.get(i).getDisplayName() + " -> "; strPath += Iterables.getLast(loopPath).getDisplayName(); compiler.report(t.makeError(n, INTERFACE_EXTENDS_LOOP, loopPath.get(0).getDisplayName(), strPath));
@Override public TypeI convertMethodToFunction() { List<JSType> paramTypes = new ArrayList<JSType>(); paramTypes.add(getTypeOfThis()); for (Node param : getParameters()) { paramTypes.add(param.getJSType()); } return registry.createFunctionTypeWithInstanceType( registry.getNativeObjectType(JSTypeNative.UNKNOWN_TYPE), getReturnType(), paramTypes); }
FunctionType baseConstructor = functionType.getSuperClassConstructor(); if (!Objects.equals(baseConstructor, getNativeType(OBJECT_FUNCTION_TYPE)) && baseConstructor != null && baseConstructor.isInterface()) { if (n.isFunction() && baseConstructor != null && baseConstructor.getSource() != null && baseConstructor.getSource().isEs6Class() && !functionType.getSource().isEs6Class()) { n, ES5_CLASS_EXTENDING_ES6_CLASS, functionType.getDisplayName(), baseConstructor.getDisplayName())); for (JSType baseInterface : functionType.getImplementedInterfaces()) { boolean badImplementedType = false; ObjectType baseInterfaceObj = ObjectType.cast(baseInterface); FunctionType interfaceConstructor = baseInterfaceObj.getConstructor(); if (interfaceConstructor != null && !interfaceConstructor.isInterface()) { badImplementedType = true; if (!functionType.isAbstract()) { validator.expectAbstractMethodsImplemented(n, functionType);
FunctionBuilder builder = new FunctionBuilder(registry) .withReturnType(isCall ? getReturnType() : getBindReturnType(-1)) .withTemplateKeys(getTemplateTypeMap().getTemplateKeys()); Node origParams = getParametersNode(); if (origParams != null) { Node params = origParams.cloneTree(); thisTypeNode.setJSType(registry.createOptionalNullableType(getTypeOfThis())); params.addChildToFront(thisTypeNode);
/** * Given a constructor or an interface type, get its superclass constructor * or {@code null} if none exists. */ public FunctionType getSuperClassConstructor() { Preconditions.checkArgument(isConstructor() || isInterface()); ObjectType maybeSuperInstanceType = getPrototype().getImplicitPrototype(); if (maybeSuperInstanceType == null) { return null; } return maybeSuperInstanceType.getConstructor(); }
/** * check whether or not this function type has implemented * the given interface * if this function is an interface, check whether or not * this interface has extended the given interface * @param interfaceType the interface type * @return true if implemented */ public boolean explicitlyImplOrExtInterface(FunctionType interfaceType) { Preconditions.checkArgument(interfaceType.isInterface()); for (ObjectType implementedInterface : getAllImplementedInterfaces()) { FunctionType ctor = implementedInterface.getConstructor(); if (ctor != null && ctor.checkEquivalenceHelper( interfaceType, EquivalenceMethod.IDENTITY)) { return true; } } for (ObjectType implementedInterface : getExtendedInterfaces()) { FunctionType ctor = implementedInterface.getConstructor(); if (ctor != null && ctor.checkEquivalenceHelper( interfaceType, EquivalenceMethod.IDENTITY)) { return true; } else if (ctor != null) { return ctor.explicitlyImplOrExtInterface(interfaceType); } } return false; }