Skip to content

Commit

Permalink
[NTI] Migrate AmbiguateProperties to TypeI
Browse files Browse the repository at this point in the history
Extracts some common functionality between AmbiguateProperties and InlineProperties into InvalidatingTypes.

Of additional note is the removal of FunctionTypeI#getDirectImplementors.  This has been folded into the newly-implemented FunctionTypeI#getSubTypes, which now no longer ever returns null.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=160329292
  • Loading branch information
shicks authored and brad4d committed Jun 28, 2017
1 parent d1b1536 commit c27f830
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 246 deletions.
259 changes: 95 additions & 164 deletions src/com/google/javascript/jscomp/AmbiguateProperties.java

Large diffs are not rendered by default.

Expand Up @@ -829,7 +829,7 @@ private boolean isInvalidatingType(TypeI type) {
// isUnknownObject to return false for object literals. I deliberately followed the behavior // isUnknownObject to return false for object literals. I deliberately followed the behavior
// of OTI to help with the migration, but can revisit in the future to improve // of OTI to help with the migration, but can revisit in the future to improve
// disambiguation. // disambiguation.
return objType.isUnknownObject() return objType.isAmbiguousObject()
// Invalidate constructors of already-invalidated types // Invalidate constructors of already-invalidated types
|| (ft != null && ft.isConstructor() && isInvalidatingType(ft.getInstanceType())); || (ft != null && ft.isConstructor() && isInvalidatingType(ft.getInstanceType()));
} }
Expand Down
2 changes: 1 addition & 1 deletion src/com/google/javascript/jscomp/InvalidatingTypes.java
Expand Up @@ -50,7 +50,7 @@ boolean isInvalidating(TypeI type) {
ObjectTypeI objType = type.toMaybeObjectType(); ObjectTypeI objType = type.toMaybeObjectType();
return objType == null return objType == null
|| types.contains(objType) || types.contains(objType)
|| objType.isUnknownObject() || objType.isAmbiguousObject()
|| objType.isUnknownType() || objType.isUnknownType()
|| objType.isBottom() || objType.isBottom()
|| objType.isEnumObject() || objType.isEnumObject()
Expand Down
13 changes: 4 additions & 9 deletions src/com/google/javascript/jscomp/newtypes/JSType.java
Expand Up @@ -1732,7 +1732,7 @@ public final boolean isUnknownType() {
public final boolean isSomeUnknownType() { public final boolean isSomeUnknownType() {
FunctionType ft = this.getFunTypeIfSingletonObj(); FunctionType ft = this.getFunTypeIfSingletonObj();
return isUnknown() return isUnknown()
|| (isUnknownObject() && isLoose()) || (isAmbiguousObject() && isLoose())
|| (ft != null && ft.isTopFunction()); || (ft != null && ft.isTopFunction());
} }


Expand Down Expand Up @@ -2021,14 +2021,9 @@ public final boolean isPrototypeObject() {
} }


@Override @Override
public final boolean isUnknownObject() { public final boolean isAmbiguousObject() {
if (isSingletonObj()) { ObjectType obj = getObjTypeIfSingletonObj();
ObjectType obj = getObjTypeIfSingletonObj(); return obj != null && obj.isAmbiguousObject();
NominalType nt = getNominalTypeIfSingletonObj();
return (nt.isBuiltinObject() || nt.isLiteralObject())
&& !obj.isEnumObject() && !obj.isPrototypeObject();
}
return false;
} }


final boolean isBuiltinObjectPrototype() { final boolean isBuiltinObjectPrototype() {
Expand Down
30 changes: 26 additions & 4 deletions src/com/google/javascript/jscomp/newtypes/ObjectType.java
Expand Up @@ -1563,14 +1563,36 @@ ObjectType substituteGenerics(Map<String, JSType> typeMap) {


/** /**
* Looks for the given property name (which must be a non-qualified * Looks for the given property name (which must be a non-qualified
* identifier) on any nominal subtypes. The built-in object type * identifier) on any nominal subtypes. The built-in object type
* always returns true. * always returns true.
*/ */
boolean isPropDefinedOnSubtype(QualifiedName pname) { boolean isPropDefinedOnSubtype(QualifiedName pname) {
checkArgument(pname.isIdentifier()); checkArgument(pname.isIdentifier());
return this.nominalType.isBuiltinObject() || this.nominalType.isPropDefinedOnSubtype(pname); return this.nominalType.isBuiltinObject() || this.nominalType.isPropDefinedOnSubtype(pname);
} }


/**
* Returns true if this object refers to the type of an ambiguous object
*/
boolean isAmbiguousObject() {
// TODO(sdh): It's somewhat odd that we treat function namespaces differently
// from object namespaces. The reason is for consistency with OTI, which treats
// most object literals as anonymous objects, but not so for functions. We
// could remove the 'fn' check and simply return true for all namespaces, but
// we'll need to update a bunch of expectations in DisambiguatePropertiesTest
// (which will then differ from OTI).
if (isEnumObject() || isPrototypeObject() || (this.ns != null && this.fn != null)) {
return false;
}
// All constructors have "Function" as their nominalType, so look at instance
// types instead for these cases.
NominalType nt =
(fn != null && fn.isSomeConstructorOrInterface())
? fn.getInstanceTypeOfCtor().getObjTypeIfSingletonObj().nominalType
: this.nominalType;
return nt.isFunction() || nt.isBuiltinObject() || nt.isLiteralObject();
}

@Override @Override
public String toString() { public String toString() {
return appendTo(new StringBuilder(), ToStringContext.TO_STRING).toString(); return appendTo(new StringBuilder(), ToStringContext.TO_STRING).toString();
Expand All @@ -1590,9 +1612,9 @@ StringBuilder appendTo(StringBuilder builder, ToStringContext ctx) {
} }
return this.nominalType.appendTo(builder, ctx); return this.nominalType.appendTo(builder, ctx);
} }
if (!nominalType.getName().equals("Function") if (!nominalType.isFunction()
&& !nominalType.getName().equals("Object") && !nominalType.isBuiltinObject()
&& !nominalType.getName().equals(JSTypes.OBJLIT_CLASS_NAME)) { && !nominalType.isLiteralObject()) {
nominalType.appendTo(builder, ctx); nominalType.appendTo(builder, ctx);
} else if (isStruct()) { } else if (isStruct()) {
builder.append("struct"); builder.append("struct");
Expand Down
7 changes: 4 additions & 3 deletions src/com/google/javascript/rhino/ObjectTypeI.java
Expand Up @@ -115,10 +115,11 @@ public interface ObjectTypeI extends TypeI {
ObjectTypeI normalizeObjectForCheckAccessControls(); ObjectTypeI normalizeObjectForCheckAccessControls();


/** /**
* Returns true if this object is an anonymous object type (i.e. the builtin Object type, or an * Returns true if this object is an anonymous object or function type (i.e. the builtin Object
* object literal). Everything else has a named reference type and returns false. * or Function type, or a record or function literal). These types are ambiguous and should not
* participate in property renaming. Everything else has a named reference type and returns false.
*/ */
boolean isUnknownObject(); boolean isAmbiguousObject();


/** /**
* The old type checker uses NamedType to wrap types (e.g., defined by typedefs), and to represent * The old type checker uses NamedType to wrap types (e.g., defined by typedefs), and to represent
Expand Down
2 changes: 1 addition & 1 deletion src/com/google/javascript/rhino/jstype/ObjectType.java
Expand Up @@ -252,7 +252,7 @@ public boolean hasReferenceName() {
} }


@Override @Override
public final boolean isUnknownObject() { public final boolean isAmbiguousObject() {
return !hasReferenceName(); return !hasReferenceName();
} }


Expand Down

0 comments on commit c27f830

Please sign in to comment.