Skip to content

Commit

Permalink
[NTI] Bugfix to JSType#withoutStrayProperties for prototypes and name…
Browse files Browse the repository at this point in the history
…spaces.

NOTE: the new unit tests actually pass before this CL as well, but it's good to have these tests. I wasn't able to find a unit test for the behavior this CL is fixing. It can be observed by adding prints to ambiguation and disambiguation, to see the types associated with each property.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=175599577
  • Loading branch information
dimvar authored and Tyler Breisacher committed Nov 14, 2017
1 parent 2b16efe commit afe3249
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/com/google/javascript/jscomp/newtypes/JSType.java
Original file line number Diff line number Diff line change
Expand Up @@ -2355,8 +2355,17 @@ public Set<String> getPropertyNames() {
public ObjectTypeI withoutStrayProperties() {
ObjectType obj = getObjTypeIfSingletonObj();
NominalType nt = getNominalTypeIfSingletonObj();
return nt.isLiteralObject() || obj.isPrototypeObject() || obj.isNamespace()
? this : nt.getInstanceAsJSType();
if (nt.isLiteralObject()) {
return this;
}
if (obj.isPrototypeObject()) {
// The canonical prototype, without any specialized properties
return obj.getOwnerFunction().getInstanceTypeOfCtor().getPrototypeObject();
}
if (obj.isNamespace()) {
return obj.getNamespaceType();
}
return nt.getInstanceAsJSType();
}

@Override
Expand Down
4 changes: 4 additions & 0 deletions src/com/google/javascript/jscomp/newtypes/ObjectType.java
Original file line number Diff line number Diff line change
Expand Up @@ -1696,6 +1696,10 @@ Node getDefSite() {
return null;
}

JSType getNamespaceType() {
return this.ns.toJSType();
}

@Override
public String toString() {
return appendTo(new StringBuilder(), ToStringContext.TO_STRING).toString();
Expand Down
88 changes: 88 additions & 0 deletions test/com/google/javascript/jscomp/DisambiguatePropertiesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2345,6 +2345,94 @@ public void testIgnoreSpecializedProperties() {
testSets("", js, output, "{a=[[Bar], [Foo]], b=[[Bar], [Foo]], f=[[Foo.prototype]]}");
}

public void testIgnoreSpecializedProperties2() {
String js = lines(
"/** @const */",
"var ns = function() {};",
"/** @type {?number} */",
"ns.num;",
"function f() {",
" if (ns.num !== null) {",
" return ns.num + 1;",
" }",
"}",
"/** @constructor */",
"function Foo() {",
" this.num = 123;",
"}");

String otiOutput = lines(
"/** @const */",
"var ns = function() {};",
"/** @type {?number} */",
"ns.function____undefined$num;",
"function f() {",
" if (ns.function____undefined$num !== null) {",
" return ns.function____undefined$num + 1;",
" }",
"}",
"/** @constructor */",
"function Foo() {",
" this.Foo$num = 123;",
"}");

this.mode = TypeInferenceMode.OTI_ONLY;
testSets("", js, otiOutput, "{num=[[Foo], [function(): undefined]]}");

String ntiOutput = lines(
"/** @const */",
"var ns = function() {};",
"/** @type {?number} */",
"ns.ns$num;",
"function f() {",
" if (ns.ns$num !== null) {",
" return ns.ns$num + 1;",
" }",
"}",
"/** @constructor */",
"function Foo() {",
" this.Foo$num = 123;",
"}");

this.mode = TypeInferenceMode.NTI_ONLY;
testSets("", js, ntiOutput, "{num=[[Foo], [ns]]}");
}

public void testIgnoreSpecializedProperties3() {
String js = lines(
"/** @constructor */",
"function Foo() {}",
"/** @type {?number} */",
"Foo.prototype.num;",
"function f() {",
" if (Foo.prototype.num != null) {",
" return Foo.prototype.num;",
" }",
"}",
"/** @constructor */",
"function Bar() {",
" this.num = 123;",
"}");

String output = lines(
"/** @constructor */",
"function Foo() {}",
"/** @type {?number} */",
"Foo.prototype.Foo_prototype$num;",
"function f() {",
" if (Foo.prototype.Foo_prototype$num != null) {",
" return Foo.prototype.Foo_prototype$num;",
" }",
"}",
"/** @constructor */",
"function Bar() {",
" this.Bar$num = 123;",
"}");

this.mode = TypeInferenceMode.NTI_ONLY;
testSets("", js, output, "{num=[[Bar], [Foo.prototype]]}");
}

public void testErrorOnProtectedProperty() {
test(
srcs("function addSingletonGetter(foo) { foo.foobar = 'a'; };"),
Expand Down

0 comments on commit afe3249

Please sign in to comment.