private void handleConstructorAnnotation( String functionName, Node funNode, RawNominalType constructorType, NominalType parentClass, ImmutableSet<NominalType> implementedIntfs, DeclaredTypeRegistry registry, FunctionTypeBuilder builder) { String className = constructorType.toString(); NominalType builtinObject = registry.getCommonTypes().getObjectType(); if (parentClass == null && !functionName.equals("Object")) { parentClass = builtinObject; } if (parentClass != null) { if (!constructorType.addSuperClass(parentClass)) { warnings.add(JSError.make(funNode, INHERITANCE_CYCLE, className)); } else if (parentClass != builtinObject) { if (constructorType.isStruct() && !parentClass.isStruct()) { warnings.add(JSError.make(funNode, CONFLICTING_SHAPE_TYPE, "struct", className)); } else if (constructorType.isDict() && !parentClass.isDict()) { warnings.add(JSError.make(funNode, CONFLICTING_SHAPE_TYPE, "dict", className)); } } } if (constructorType.isDict() && !implementedIntfs.isEmpty()) { warnings.add(JSError.make(funNode, DICT_IMPLEMENTS_INTERF, className)); } boolean noCycles = constructorType.addInterfaces(implementedIntfs); Preconditions.checkState(noCycles); builder.addNominalType(constructorType.getInstanceAsJSType()); }
private JSType lookupTypeByName( String name, Node n, DeclaredTypeRegistry registry, ImmutableList<String> outerTypeParameters) throws UnknownTypeException { String tvar = UniqueNameGenerator.findGeneratedName(name, outerTypeParameters); if (tvar != null) { return JSType.fromTypeVar(tvar); } Declaration decl = registry.getDeclaration(QualifiedName.fromQualifiedString(name), true); if (decl == null) { unknownTypeNames.put(n, name); throw new UnknownTypeException("Unhandled type: " + name); } // It's either a typedef, an enum, a type variable or a nominal type if (decl.getTypedef() != null) { return getTypedefType(decl.getTypedef(), registry); } if (decl.getEnum() != null) { return getEnumPropType(decl.getEnum(), registry); } if (decl.isTypeVar()) { howmanyTypeVars++; return decl.getTypeOfSimpleDecl(); } if (decl.getNominal() != null) { return getNominalTypeHelper(decl.getNominal(), n, registry, outerTypeParameters); } return JSType.UNKNOWN; }
// Computes a type from a jsdoc that includes a function type, rather than // one that includes @param, @return, etc. private JSType getFunTypeHelper( Node jsdocNode, DeclaredTypeRegistry registry, ImmutableList<String> typeParameters) throws UnknownTypeException { FunctionTypeBuilder builder = new FunctionTypeBuilder(); fillInFunTypeBuilder(jsdocNode, null, registry, typeParameters, builder); return registry.getCommonTypes().fromFunctionType(builder.buildFunction()); }
private JSType getNamedTypeHelper( Node n, DeclaredTypeRegistry registry, ImmutableList<String> outerTypeParameters) throws UnknownTypeException { String typeName = n.getString(); switch (typeName) { case "boolean": return JSType.BOOLEAN; case "null": return JSType.NULL; case "number": return JSType.NUMBER; case "string": return JSType.STRING; case "undefined": case "void": return JSType.UNDEFINED; case "Function": return maybeMakeNullable(registry.getCommonTypes().qmarkFunction()); case "Object": // We don't generally handle parameterized Object<...>, but we want to // at least not warn about inexistent properties on it, so we type it // as @dict. return maybeMakeNullable(n.hasChildren() ? JSType.TOP_DICT : JSType.TOP_OBJECT); default: return lookupTypeByName(typeName, n, registry, outerTypeParameters); } }
private void handleInterfaceAnnotation( JSDocInfo jsdoc, String functionName, Node funNode, RawNominalType constructorType, ImmutableSet<NominalType> implementedIntfs, ImmutableList<String> typeParameters, DeclaredTypeRegistry registry, FunctionTypeBuilder builder) { if (!implementedIntfs.isEmpty()) { warnings.add(JSError.make(funNode, CONFLICTING_IMPLEMENTED_TYPE, functionName)); } ImmutableSet<NominalType> extendedInterfaces = getExtendedInterfaces(jsdoc, registry, typeParameters); boolean noCycles = constructorType.addInterfaces( extendedInterfaces.isEmpty() ? ImmutableSet.of(registry.getCommonTypes().getObjectType()) : extendedInterfaces); if (!noCycles) { warnings.add(JSError.make(funNode, INHERITANCE_CYCLE, constructorType.toString())); } builder.addNominalType(constructorType.getInstanceAsJSType()); }