Code with Finding: |
class JSTypeRegistry {
/**
* Tells the type system that {@code owner} may have a property named
* {@code propertyName}. This allows the registry to keep track of what
* types a property is defined upon.
*
* This is NOT the same as saying that {@code owner} must have a property
* named type. ObjectType#hasProperty attempts to minimize false positives
* ("if we're not sure, then don't type check this property"). The type
* registry, on the other hand, should attempt to minimize false negatives
* ("if this property is assigned anywhere in the program, it must
* show up in the type registry").
*/
public void registerPropertyOnType(String propertyName, JSType type) {
UnionTypeBuilder typeSet = typesIndexedByProperty.get(propertyName);
if (typeSet == null) {
typeSet = new UnionTypeBuilder(this);
typesIndexedByProperty.put(propertyName, typeSet);
}
typeSet.addAlternate(type);
addReferenceTypeIndexedByProperty(propertyName, type);
// Clear cached values that depend on typesIndexedByProperty.
greatestSubtypeByProperty.remove(propertyName);
}
}
class JSTypeRegistry {
/**
* Gets the greatest subtype of the {@code type} that has a property
* {@code propertyName} defined on it.
*/
public JSType getGreatestSubtypeWithProperty(
JSType type, String propertyName) {
if (greatestSubtypeByProperty.containsKey(propertyName)) {
return greatestSubtypeByProperty.get(propertyName)
.getGreatestSubtype(type);
}
if (typesIndexedByProperty.containsKey(propertyName)) {
JSType built = typesIndexedByProperty.get(propertyName).build();
greatestSubtypeByProperty.put(propertyName, built);
return built.getGreatestSubtype(type);
}
return getNativeType(NO_TYPE);
}
}
|