Skip to content

Commit

Permalink
Minor simplification to disambiguate properties.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=225942159
  • Loading branch information
concavelenz authored and blickly committed Dec 18, 2018
1 parent caba0f8 commit 05abf50
Showing 1 changed file with 52 additions and 49 deletions.
101 changes: 52 additions & 49 deletions src/com/google/javascript/jscomp/DisambiguateProperties.java
Expand Up @@ -307,14 +307,13 @@ boolean invalidate() {


/** /**
* Schedule the node to potentially be renamed. * Schedule the node to potentially be renamed.
*
* @param node the node to rename * @param node the node to rename
* @param type the highest type in the prototype chain for which the * @return True if type was accepted without invalidation or if the property was already
* property is defined * invalidated. False if this property was invalidated this time.
* @return True if type was accepted without invalidation or if the property
* was already invalidated. False if this property was invalidated this
* time.
*/ */
boolean scheduleRenaming(Node node, JSType type) { boolean scheduleRenaming(Node node, JSType targetType) {
JSType type = processProperty(targetType);
if (!skipRenaming) { if (!skipRenaming) {
if (invalidatingTypes.isInvalidating(type)) { if (invalidatingTypes.isInvalidating(type)) {
invalidate(); invalidate();
Expand All @@ -324,6 +323,47 @@ boolean scheduleRenaming(Node node, JSType type) {
} }
return true; return true;
} }

@Nullable
private JSType processProperty(JSType type) {
return processProperty(type, null);
}

/**
* Processes a property, adding it to the list of properties to rename.
*
* @param type a type this property is known to be on, not necessarily the highest type
* @param relatedType only for use inside this function, other callers should pass null.
* @return a representative type for the property reference, which will be the highest type on
* the prototype chain of the provided type. In the case of a union type, it will be the
* highest type on the prototype chain of one of the members of the union. Returns null if
* the property is marked as not renamable or the given type is invalidated
*/
@Nullable
private JSType processProperty(JSType type, @Nullable JSType relatedType) {
type = type.restrictByNotNullOrUndefined();
if (this.skipRenaming || invalidatingTypes.isInvalidating(type)) {
return null;
}
Iterable<? extends JSType> alternatives = getTypeAlternatives(type);
if (alternatives != null) {
JSType firstType = relatedType;
for (JSType subType : alternatives) {
JSType lastType = processProperty(subType, firstType);
if (firstType == null) {
firstType = lastType; // maybe null
}
}
return firstType;
} else {
JSType topType = getTypeWithProperty(this.name, type);
if (invalidatingTypes.isInvalidating(topType)) {
return null;
}
this.addType(type, relatedType);
return topType;
}
}
} }


private final Map<String, Property> properties = new LinkedHashMap<>(); private final Map<String, Property> properties = new LinkedHashMap<>();
Expand Down Expand Up @@ -461,7 +501,7 @@ private void handleGetProp(Node n) {
String name = n.getLastChild().getString(); String name = n.getLastChild().getString();
JSType type = getType(n.getFirstChild()); JSType type = getType(n.getFirstChild());
Property prop = getProperty(name); Property prop = getProperty(name);
if (!prop.scheduleRenaming(n.getLastChild(), processProperty(prop, type, null)) if (!prop.scheduleRenaming(n.getLastChild(), type)
&& propertiesToErrorFor.containsKey(name)) { && propertiesToErrorFor.containsKey(name)) {
String suggestion = ""; String suggestion = "";
if (type.isAllType() || type.isUnknownType()) { if (type.isAllType() || type.isUnknownType()) {
Expand Down Expand Up @@ -504,7 +544,7 @@ private void handleObjectLit(Node n) {
String name = child.getString(); String name = child.getString();
JSType objlitType = getType(n); JSType objlitType = getType(n);
Property prop = getProperty(name); Property prop = getProperty(name);
if (!prop.scheduleRenaming(child, processProperty(prop, objlitType, null))) { if (!prop.scheduleRenaming(child, objlitType)) {
// TODO(user): It doesn't look like the user can do much in this // TODO(user): It doesn't look like the user can do much in this
// case right now. // case right now.
if (propertiesToErrorFor.containsKey(name)) { if (propertiesToErrorFor.containsKey(name)) {
Expand Down Expand Up @@ -553,8 +593,7 @@ private void handleClass(Node classNode) {
Property prop = getProperty(name); Property prop = getProperty(name);
JSType ownerType = member.isStaticMember() ? classType : classInstanceType; JSType ownerType = member.isStaticMember() ? classType : classInstanceType;


if (!prop.scheduleRenaming(member, processProperty(prop, ownerType, null)) if (!prop.scheduleRenaming(member, ownerType) && propertiesToErrorFor.containsKey(name)) {
&& propertiesToErrorFor.containsKey(name)) {
String suggestion = ""; String suggestion = "";
List<String> errors = new ArrayList<>(); List<String> errors = new ArrayList<>();
printErrorLocations(errors, ownerType); printErrorLocations(errors, ownerType);
Expand Down Expand Up @@ -594,7 +633,7 @@ private void handleObjectPattern(Node pattern) {
} }
String name = stringKey.getString(); String name = stringKey.getString();
Property prop = getProperty(name); Property prop = getProperty(name);
if (!prop.scheduleRenaming(stringKey, processProperty(prop, objectPatternType, null)) if (!prop.scheduleRenaming(stringKey, objectPatternType)
&& propertiesToErrorFor.containsKey(name)) { && propertiesToErrorFor.containsKey(name)) {
String suggestion = ""; String suggestion = "";
if (objectPatternType.isAllType() || objectPatternType.isUnknownType()) { if (objectPatternType.isAllType() || objectPatternType.isUnknownType()) {
Expand Down Expand Up @@ -662,7 +701,7 @@ private void handlePropertyRenameFunctionCall(Node call, String renameFunctionNa
Node obj = call.getChildAtIndex(2); Node obj = call.getChildAtIndex(2);
JSType type = getType(obj); JSType type = getType(obj);
Property prop = getProperty(propName); Property prop = getProperty(propName);
if (!prop.scheduleRenaming(call.getSecondChild(), processProperty(prop, type, null)) if (!prop.scheduleRenaming(call.getSecondChild(), type)
&& propertiesToErrorFor.containsKey(propName)) { && propertiesToErrorFor.containsKey(propName)) {
String suggestion = ""; String suggestion = "";
if (type.isAllType() || type.isUnknownType()) { if (type.isAllType() || type.isUnknownType()) {
Expand Down Expand Up @@ -708,7 +747,7 @@ private void handleObjectDefineProperties(Node call) {


String propName = key.getString(); String propName = key.getString();
Property prop = getProperty(propName); Property prop = getProperty(propName);
prop.scheduleRenaming(key, processProperty(prop, type, null)); prop.scheduleRenaming(key, type);
} }
} }


Expand All @@ -732,42 +771,6 @@ private void printErrorLocations(List<String> errors, JSType t) {
errors.add(t + " at " + error.sourceName + ":" + error.lineNumber); errors.add(t + " at " + error.sourceName + ":" + error.lineNumber);
} }
} }

/**
* Processes a property, adding it to the list of properties to rename.
*
* @param type a type this property is known to be on, not necessarily the highest type
* @param relatedType only for use inside this function, other callers should pass null.
* @return a representative type for the property reference, which will be the highest type on
* the prototype chain of the provided type. In the case of a union type, it will be the
* highest type on the prototype chain of one of the members of the union. Returns null if
* the property is marked as not renamable or the given type is invalidated
*/
@Nullable
private JSType processProperty(Property prop, JSType type, @Nullable JSType relatedType) {
type = type.restrictByNotNullOrUndefined();
if (prop.skipRenaming || invalidatingTypes.isInvalidating(type)) {
return null;
}
Iterable<? extends JSType> alternatives = getTypeAlternatives(type);
if (alternatives != null) {
JSType firstType = relatedType;
for (JSType subType : alternatives) {
JSType lastType = processProperty(prop, subType, firstType);
if (lastType != null) {
firstType = firstType == null ? lastType : firstType;
}
}
return firstType;
} else {
JSType topType = getTypeWithProperty(prop.name, type);
if (invalidatingTypes.isInvalidating(topType)) {
return null;
}
prop.addType(type, relatedType);
return topType;
}
}
} }


/** Renames all properties with references on more than one type. */ /** Renames all properties with references on more than one type. */
Expand Down

0 comments on commit 05abf50

Please sign in to comment.