Skip to content

Commit

Permalink
Remove reference types from "type by property name" index
Browse files Browse the repository at this point in the history
This is not a major behavioral change but I did find one file with new missing prop errors

PiperOrigin-RevId: 418019197
  • Loading branch information
lauraharker authored and copybara-github committed Dec 23, 2021
1 parent 5249124 commit 4f69363
Showing 1 changed file with 32 additions and 32 deletions.
64 changes: 32 additions & 32 deletions src/com/google/javascript/rhino/jstype/JSTypeRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,14 @@ public final class JSTypeRegistry {
private final transient Set<String> forwardDeclaredTypes;

// A map of properties to the types on which those properties have been declared.
private transient Multimap<String, JSType> typesIndexedByProperty =
// "Reference" types are excluded because those already exist in eachRefTypeIndexedByProperty to
// avoid blowing up the size of this map.
private final transient SetMultimap<String, JSType> nonRefTypesIndexedByProperty =
MultimapBuilder.hashKeys().linkedHashSetValues().build();

private JSType sentinelObjectLiteral;

// To avoid blowing up the size of typesIndexedByProperty, we use the sentinel object
// To avoid blowing up the size of nonRefTypesIndexedByProperty, we use the sentinel object
// literal instead of registering arbitrarily many types.
// But because of the way unions are constructed, some properties of record types in unions
// are getting dropped and cause spurious "non-existent property" warnings.
Expand All @@ -209,7 +211,7 @@ public final class JSTypeRegistry {
// canPropertyBeDefined, if the type has a property in propertiesOfSupertypesInUnions, we
// consider it to possibly have any property in droppedPropertiesOfUnions. This is a loose
// check, but we restrict it to records that may be present in unions, and it allows us to
// keep typesIndexedByProperty small.
// keep nonRefTypesIndexedByProperty small.
private final Set<String> propertiesOfSupertypesInUnions = new HashSet<>();
private final Set<String> droppedPropertiesOfUnions = new HashSet<>();

Expand Down Expand Up @@ -1080,31 +1082,22 @@ void registerDroppedPropertiesInUnion(RecordType subtype, RecordType supertype)
* show up in the type registry").
*/
public void registerPropertyOnType(String propertyName, JSType type) {
if (isObjectLiteralThatCanBeSkipped(type)) {
type = getSentinelObjectLiteral();
}

if (type.isUnionType()) {
typesIndexedByProperty.putAll(propertyName, type.toMaybeUnionType().getAlternates());
} else {
typesIndexedByProperty.put(propertyName, type);
for (JSType alternate : type.toMaybeUnionType().getAlternates()) {
registerPropertyOnType(propertyName, alternate);
}
return;
}

addReferenceTypeIndexedByProperty(propertyName, type);
}
if (isObjectLiteralThatCanBeSkipped(type)) {
type = getSentinelObjectLiteral();
}

private void addReferenceTypeIndexedByProperty(
String propertyName, JSType type) {
if (type instanceof ObjectType && ((ObjectType) type).hasReferenceName()) {
ObjectType objType = (ObjectType) type;
eachRefTypeIndexedByProperty.put(propertyName, objType);
} else if (type instanceof NamedType) {
addReferenceTypeIndexedByProperty(
propertyName, ((NamedType) type).getReferencedType());
} else if (type.isUnionType()) {
for (JSType alternate : type.toMaybeUnionType().getAlternates()) {
addReferenceTypeIndexedByProperty(propertyName, alternate);
}
} else {
nonRefTypesIndexedByProperty.put(propertyName, type);
}
}

Expand Down Expand Up @@ -1148,19 +1141,26 @@ public PropDefinitionKind canPropertyBeDefined(JSType type, String propertyName)
}
}

if (typesIndexedByProperty.containsKey(propertyName)) {
for (JSType alternative : typesIndexedByProperty.get(propertyName)) {
JSType greatestSubtype = alternative.getGreatestSubtype(type);
if (!greatestSubtype.isEmptyType()) {
// We've found a type with this property. Now we just have to make
// sure it's not a type used for internal bookkeeping.
RecordType maybeRecordType = greatestSubtype.toMaybeRecordType();
if (maybeRecordType != null && maybeRecordType.isSynthetic()) {
continue;
}
Iterable<JSType> associatedTypes = ImmutableList.of();
if (nonRefTypesIndexedByProperty.containsKey(propertyName)) {
associatedTypes = nonRefTypesIndexedByProperty.get(propertyName);
}
if (eachRefTypeIndexedByProperty.containsKey(propertyName)) {
associatedTypes =
Iterables.concat(associatedTypes, eachRefTypeIndexedByProperty.get(propertyName));
}

return PropDefinitionKind.LOOSE;
for (JSType alternative : associatedTypes) {
JSType greatestSubtype = alternative.getGreatestSubtype(type);
if (!greatestSubtype.isEmptyType()) {
// We've found a type with this property. Now we just have to make
// sure it's not a type used for internal bookkeeping.
RecordType maybeRecordType = greatestSubtype.toMaybeRecordType();
if (maybeRecordType != null && maybeRecordType.isSynthetic()) {
continue;
}

return PropDefinitionKind.LOOSE;
}
}

Expand Down

0 comments on commit 4f69363

Please sign in to comment.