@Override public final boolean isInterface() { return referencedType.isInterface(); }
@Override public boolean isInterface() { return referencedType.isInterface(); }
private boolean isConstructor(Node n) { // If type checking is enabled (not just a per-file lint check), // we can check constructor properties too. But it isn't required. JSType type = n.getJSType(); return type != null && (type.isConstructor() || type.isInterface()); } }
private boolean isInterface(JSType type) { ObjectType objType = type.toObjectType(); if (objType != null) { JSType constructor = objType.getConstructor(); return constructor != null && constructor.isInterface(); } return false; }
private boolean isConstructor(Node n) { // If type checking is enabled (not just a per-file lint check), // we can check constructor properties too. But it isn't required. JSType type = n.getJSType(); return type != null && (type.isConstructor() || type.isInterface()); }
private boolean isInterface(JSType type) { ObjectType objType = type.toObjectType(); if (objType != null) { JSType constructor = objType.getConstructor(); return constructor != null && constructor.isInterface(); } return false; }
private boolean isAliasedClassOrInterface(TypedVar symbol, JSType type) { // Confusingly typedefs are constructors. However, they cannot be aliased AFAICT. if (type.isNoType()) return false; if (!type.isConstructor() && !type.isInterface()) return false; String symbolName = symbol.getName(); String typeName = type.getDisplayName(); // Turns out that for aliases the symbol and type name differ. return !symbolName.equals(typeName) || KNOWN_CLASS_ALIASES.containsKey(symbolName); }
/** * Returns true if {@code propType} is creating a new type in the TypeScript sense - i.e. it's a * constructor function (class or interface), enum, or typedef. */ private boolean isDefiningType(JSType propType) { return isClassLike(propType) || propType.isEnumType() || propType.isInterface() || isTypedef(propType); }
@Override public boolean isStaticProperty() { Node lhs = assignNode.getFirstChild(); if (lhs.isGetProp()) { // something.propName = someValue Node getPropLhs = lhs.getFirstChild(); JSType typeI = getPropLhs.getJSType(); return typeI != null && (typeI.isConstructor() || typeI.isInterface()); } else { return false; } }
/** * Whether this type is the original constructor of a nominal type. * Does not include structural constructors. */ public final boolean isNominalConstructor() { if (isConstructor() || isInterface()) { FunctionType fn = toMaybeFunctionType(); if (fn == null) { return false; } // Programmer-defined constructors will have a link // back to the original function in the source tree. // Structural constructors will not. if (fn.getSource() != null) { return true; } // Native constructors are always nominal. return fn.isNativeObjectType(); } return false; }
/** * Returns true for types that are class like, i.e. that define a constructor or interface, but * excludes typedefs and the built-in constructor functions such as {@code Function}. */ private boolean isClassLike(JSType propType) { // Confusingly, the typedef type returns true on isConstructor checks, so we need to filter // the NoType through this utility method. return !isTypedef(propType) && (propType.isConstructor() || propType.isInterface()) // "Function" is a constructor, but does not define a new type for our purposes. && !propType.toMaybeObjectType().isNativeObjectType() && !propType.isFunctionPrototypeType(); }
/** * Whether this type is the original constructor of a nominal type. * Does not include structural constructors. */ public final boolean isNominalConstructor() { if (isConstructor() || isInterface()) { FunctionType fn = toMaybeFunctionType(); if (fn == null) { return false; } // Programmer-defined constructors will have a link // back to the original function in the source tree. // Structural constructors will not. if (fn.getSource() != null) { return true; } // Native constructors are always nominal. return fn.isNativeObjectType(); } return false; }
private boolean needsAlias(Set<String> shadowedSymbols, String provide, TypedVar symbol) { if (collidingProvides.contains(provide)) { return true; } if (!shadowedSymbols.contains(provide)) { return false; } // Emit var foo : any for provided but not declared symbols. if (symbol == null) { return true; } JSType type = symbol.getType(); if (type == null) { return false; } // Emit var foo : PrivateType for private symbols. if (isPrivate(type.getJSDocInfo()) && !isConstructor(type.getJSDocInfo())) { return true; } // Only var declarations have collisions, while class, interface, function, and typedef can // coexist with namespaces. if (type.isInterface() || type.isConstructor() || type.isFunctionType() || isTypedef(type)) { return false; } return isDefaultExport(symbol); }
private boolean isDefaultExport(TypedVar symbol) { if (symbol.getType() == null) return true; ObjectType otype = symbol.getType().toMaybeObjectType(); if (otype != null && otype.getOwnPropertyNames().size() == 0) return true; return !symbol.getType().isObject() || symbol.getType().isInterface() || symbol.getType().isInstanceType() || symbol.getType().isEnumType() || symbol.getType().isFunctionType() || isTypedef(symbol.getType()); }
/** * Returns the type that best represents the instance type for {@code type}. * * <ul> * <li>Prototype type => The instance type having that prototype * <li>Instance type => The type * <li>Constructor type => The type that constructor instantiates * <li>Object-literal type => The type * </ul> */ @Nullable private static ObjectType instanceTypeFor(JSType type) { if (type == null) { return null; } else if (type.isUnionType()) { return null; // A union has no meaningful instance type. } else if (type.isInstanceType() || type.isUnknownType()) { return type.toMaybeObjectType(); } else if (type.isConstructor() || type.isInterface()) { return type.toMaybeFunctionType().getInstanceType(); } else if (type.isFunctionPrototypeType()) { return instanceTypeFor(type.toMaybeObjectType().getOwnerFunction()); } return type.toMaybeObjectType(); }
private JSType getType(String typeName) { JSType type = registry.getType(typeEnv, typeName); if (type != null) { return type; } StaticTypedSlot slot = typeEnv.getSlot(typeName); type = slot != null ? slot.getType() : null; if (type != null) { if (type.isConstructor() || type.isInterface()) { return type.toMaybeFunctionType().getInstanceType().getRawType(); } if (type.isEnumElementType()) { return type.getEnumeratedTypeOfEnumElement(); } return type; } JSDocInfo jsdoc = slot == null ? null : slot.getJSDocInfo(); if (jsdoc != null && jsdoc.hasTypedefType()) { return this.registry.evaluateTypeExpression(jsdoc.getTypedefType(), typeEnv); } return null; }
/** Visits a CLASS node. */ private void visitClass(NodeTraversal t, Node n) { FunctionType functionType = JSType.toMaybeFunctionType(n.getJSType()); Node extendsClause = n.getSecondChild(); if (!extendsClause.isEmpty()) { // Ensure that the `extends` clause is actually a constructor or interface. If it is, but // it's the wrong one then checkConstructor or checkInterface will warn. JSType superType = extendsClause.getJSType(); if (superType.isConstructor() || superType.isInterface()) { validator.expectExtends(n, functionType, superType.toMaybeFunctionType()); } else if (!superType.isUnknownType()) { // Only give this error for supertypes *known* to be wrong - unresolved types are OK here. compiler.report( t.makeError( n, CONFLICTING_EXTENDED_TYPE, functionType.isConstructor() ? "constructor" : "interface", getBestFunctionName(n))); } } if (functionType.isConstructor()) { checkConstructor(t, n, functionType); } else if (functionType.isInterface()) { checkInterface(t, n, functionType); } else { throw new IllegalStateException( "CLASS node's type must be either constructor or interface: " + functionType); } }
} else if (slotType.isFunctionType() && (slotType.isConstructor() || slotType.isInterface())) { setReferencedAndResolvedType(slotType.toMaybeFunctionType().getInstanceType(), reporter); } else if (slotType.isNoObjectType()) {
/** * Resolves a named type by looking up its first component in the scope, and * subsequent components as properties. The scope must have been fully * parsed and a symbol table constructed. */ private void resolveViaProperties(ErrorReporter reporter, StaticTypedScope<JSType> enclosing) { JSType value = lookupViaProperties(reporter, enclosing); // last component of the chain if (value != null && value.isFunctionType() && (value.isConstructor() || value.isInterface())) { FunctionType functionType = value.toMaybeFunctionType(); setReferencedAndResolvedType(functionType.getInstanceType(), reporter); } else if (value != null && value.isNoObjectType()) { setReferencedAndResolvedType( registry.getNativeFunctionType( JSTypeNative.NO_OBJECT_TYPE).getInstanceType(), reporter); } else if (value instanceof EnumType) { setReferencedAndResolvedType( ((EnumType) value).getElementsType(), reporter); } else { // We've been running into issues where people forward-declare // non-named types. (This is legitimate...our dependency management // code doubles as our forward-declaration code.) // // So if the type does resolve to an actual value, but it's not named, // then don't respect the forward declaration. handleUnresolvedType(reporter, value == null || value.isUnknownType()); } }
if (rawType != null) { if ((rawType.isConstructor() || rawType.isInterface()) && rawType.isFunctionType() && rawType.isNominalConstructor()) { return rawType.toMaybeFunctionType().getInstanceType();