Skip to content

Commit e1d5129

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 1ecfd75 + 630f755 commit e1d5129

14 files changed

+245
-39
lines changed

externs/browser/html5.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -3766,7 +3766,8 @@ XMLHttpRequest.prototype.response;
37663766
* refreshPolicy: string,
37673767
* signRequestData: string,
37683768
* includeTimestampHeader: boolean,
3769-
* additionalSignedHeaders: !Array<string>
3769+
* additionalSignedHeaders: (!Array<string>|undefined),
3770+
* additionalSigningData: (string|undefined)
37703771
* }}
37713772
* @see https://docs.google.com/document/d/1qUjtKgA7nMv9YGMhi0xWKEojkSITKzGLdIcZgoz6ZkI
37723773
*/

src/com/google/javascript/jscomp/GlobalNamespace.java

+5-32
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ private void collect(JSModule module, Scope scope, Node n) {
444444
type = getValueType(n.getFirstChild());
445445
break;
446446
case NAME:
447+
case GETPROP:
447448
// TODO(b/127505242): CAST parents may indicate a set.
448449
// This may be a variable get or set.
449450
switch (parent.getToken()) {
@@ -492,7 +493,9 @@ private void collect(JSModule module, Scope scope, Node n) {
492493
case ITER_REST:
493494
case OBJECT_REST:
494495
// This may be a set.
495-
if (NodeUtil.isLhsByDestructuring(n)) {
496+
// TODO(b/120303257): this should extend to qnames too, but doing
497+
// so causes invalid output. Covered in CollapsePropertiesTest
498+
if (n.isName() && NodeUtil.isLhsByDestructuring(n)) {
496499
isSet = true;
497500
type = NameType.OTHER;
498501
}
@@ -506,42 +509,12 @@ private void collect(JSModule module, Scope scope, Node n) {
506509
type = NameType.OTHER;
507510
}
508511
}
509-
name = n.getString();
510-
break;
511-
case GETPROP:
512-
// TODO(b/117673791): Merge this case with NAME case to fix.
513-
// TODO(b/120303257): Merging this case with the NAME case makes this a breaking bug.
514-
// TODO(b/127505242): CAST parents may indicate a set.
515-
// This may be a namespaced name get or set.
516-
if (parent != null) {
517-
switch (parent.getToken()) {
518-
case ASSIGN:
519-
if (parent.getFirstChild() == n) {
520-
isSet = true;
521-
type = getValueType(n.getNext());
522-
}
523-
break;
524-
case GETPROP:
525-
// This is nested in another getprop. Return and only create a Ref for the outermost
526-
// getprop in the chain.
527-
return;
528-
case INC:
529-
case DEC:
530-
case ITER_SPREAD:
531-
case OBJECT_SPREAD:
532-
break; // isSet = false, type = OTHER.
533-
default:
534-
if (NodeUtil.isAssignmentOp(parent) && parent.getFirstChild() == n) {
535-
isSet = true;
536-
type = NameType.OTHER;
537-
}
538-
}
539-
}
540512
if (!n.isQualifiedName()) {
541513
return;
542514
}
543515
name = n.getQualifiedName();
544516
break;
517+
545518
case CALL:
546519
if (isObjectHasOwnPropertyCall(n)) {
547520
String qname = n.getFirstFirstChild().getQualifiedName();

src/com/google/javascript/jscomp/colors/Color.java

+2
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,7 @@ public interface Color {
2525

2626
boolean isUnion();
2727

28+
boolean isObject();
29+
2830
ImmutableCollection<Color> getAlternates();
2931
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2020 The Closure Compiler Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.javascript.jscomp.colors;
18+
19+
import com.google.auto.value.AutoValue;
20+
import com.google.common.collect.ImmutableCollection;
21+
22+
/**
23+
* A user-defined object type. For now each type is defined by a unique class name and file source.
24+
*/
25+
@AutoValue
26+
public abstract class ObjectColor implements Color {
27+
28+
public static ObjectColor create(String className, String fileName) {
29+
return new AutoValue_ObjectColor(className, fileName);
30+
}
31+
32+
@Override
33+
public boolean isPrimitive() {
34+
return false;
35+
}
36+
37+
@Override
38+
public boolean isUnion() {
39+
return false;
40+
}
41+
42+
@Override
43+
public boolean isObject() {
44+
return true;
45+
}
46+
47+
@Override
48+
public ImmutableCollection<Color> getAlternates() {
49+
throw new UnsupportedOperationException();
50+
}
51+
52+
public abstract String getClassName();
53+
54+
public abstract String getFilename();
55+
}

src/com/google/javascript/jscomp/colors/PrimitiveColor.java

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public boolean isUnion() {
4040
return false;
4141
}
4242

43+
@Override
44+
public boolean isObject() {
45+
return false;
46+
}
47+
4348
@Override
4449
public ImmutableCollection<Color> getAlternates() {
4550
// In theory we could consider a primitive a union of a single value. It's not clear whether

src/com/google/javascript/jscomp/colors/UnionColor.java

+5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public boolean isUnion() {
5353
return true;
5454
}
5555

56+
@Override
57+
public boolean isObject() {
58+
return false;
59+
}
60+
5661
@Override
5762
public abstract ImmutableCollection<Color> getAlternates();
5863
}

src/com/google/javascript/jscomp/resources/resources.json

+1-1
Large diffs are not rendered by default.

src/com/google/javascript/jscomp/testing/ColorSubject.java

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ public void isUnion() {
5656
check("isUnion").that(actualNonNull().isUnion()).isTrue();
5757
}
5858

59+
public void isObject() {
60+
check("isObject").that(actualNonNull().isObject()).isTrue();
61+
}
62+
5963
public void hasAlternates(Color... alternates) {
6064
isUnion();
6165
check("getAlternates().containsExactly()")

test/com/google/javascript/jscomp/AmbiguatePropertiesTest.java

+42
Original file line numberDiff line numberDiff line change
@@ -1249,6 +1249,48 @@ public void testGenericPrototypeObject() {
12491249
test(js, output);
12501250
}
12511251

1252+
@Test
1253+
public void testRelatedInstanceAndPrototypePropNotAmbiguated() {
1254+
test(
1255+
lines(
1256+
"class Foo {", //
1257+
" constructor() {",
1258+
" this.y = 0;",
1259+
" }",
1260+
" x() {}",
1261+
"}"),
1262+
lines(
1263+
"class Foo {", //
1264+
" constructor() {",
1265+
" this.b = 0;",
1266+
" }",
1267+
" a() {}",
1268+
"}"));
1269+
}
1270+
1271+
@Test
1272+
public void testRelatedInstanceAndSuperclassPrototypePropNotAmbiguated() {
1273+
test(
1274+
lines(
1275+
"class Foo {", //
1276+
" x() {}",
1277+
"}",
1278+
"class Bar extends Foo {",
1279+
" constructor() {",
1280+
" this.y = 0;",
1281+
" }",
1282+
"}"),
1283+
lines(
1284+
"class Foo {", //
1285+
" a() {}",
1286+
"}",
1287+
"class Bar extends Foo {",
1288+
" constructor() {",
1289+
" this.b = 0;",
1290+
" }",
1291+
"}"));
1292+
}
1293+
12521294
@Test
12531295
public void testPropertiesWithTypesThatHaveBeenNarrowed() {
12541296
String js = lines(

test/com/google/javascript/jscomp/GlobalNamespaceTest.java

+23-5
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,34 @@
4545
import org.junit.runner.RunWith;
4646
import org.junit.runners.JUnit4;
4747

48-
/**
49-
* Tests for {@link GlobalNamespace}.
50-
*
51-
* @author nicksantos@google.com (Nick Santos)
52-
*/
48+
/** Tests for {@link GlobalNamespace}. */
5349
@RunWith(JUnit4.class)
5450
public final class GlobalNamespaceTest {
5551

5652
@Nullable private Compiler lastCompiler = null;
5753

54+
@Test
55+
public void detectsPropertySetsInAssignmentOperators() {
56+
GlobalNamespace namespace = parse("const a = {b: 0}; a.b += 1; a.b = 2;");
57+
58+
assertThat(namespace.getSlot("a.b").getGlobalSets()).isEqualTo(3);
59+
}
60+
61+
@Test
62+
public void detectsPropertySetsInDestructuring() {
63+
GlobalNamespace namespace = parse("const a = {b: 0}; [a.b] = [1]; ({b: a.b} = {b: 2});");
64+
65+
// TODO(b/120303257): this should be 3
66+
assertThat(namespace.getSlot("a.b").getGlobalSets()).isEqualTo(1);
67+
}
68+
69+
@Test
70+
public void detectsPropertySetsInIncDecOperators() {
71+
GlobalNamespace namespace = parse("const a = {b: 0}; a.b++; a.b--;");
72+
73+
assertThat(namespace.getSlot("a.b").getGlobalSets()).isEqualTo(3);
74+
}
75+
5876
@Test
5977
public void firstGlobalAssignmentIsConsideredDeclaration() {
6078
GlobalNamespace namespace = parse("");

test/com/google/javascript/jscomp/InlineAliasesTest.java

+24
Original file line numberDiff line numberDiff line change
@@ -652,4 +652,28 @@ public void testForwardedExportNested() {
652652
" const proto = 0;",
653653
"}"));
654654
}
655+
656+
@Test
657+
public void testQualifiedNameSetViaUnaryDecrementNotInlined() {
658+
testSame(
659+
lines(
660+
"const a = {b: 0, c: 0};",
661+
"const v1 = a.b;",
662+
"a.b--;",
663+
"const v2 = a.b;",
664+
"a.b--;",
665+
"use(v1 + v2);"));
666+
}
667+
668+
@Test
669+
public void testQualifiedNameSetViaUnaryIncrementNotInlined() {
670+
testSame(
671+
lines(
672+
"const a = {b: 0};",
673+
"const v1 = a.b;",
674+
"a.b++;",
675+
"const v2 = a.b;",
676+
"a.b++;",
677+
"use(v1 + v2);"));
678+
}
655679
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2020 The Closure Compiler Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.javascript.jscomp.colors;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
import static com.google.javascript.jscomp.testing.ColorSubject.assertThat;
21+
22+
import org.junit.Test;
23+
import org.junit.runner.RunWith;
24+
import org.junit.runners.JUnit4;
25+
26+
@RunWith(JUnit4.class)
27+
public class ObjectColorTest {
28+
@Test
29+
public void isPrimitiveReturnsFalse() {
30+
ObjectColor foo = ObjectColor.create("Foo", "test.js");
31+
32+
assertThat(foo.isPrimitive()).isFalse();
33+
}
34+
35+
@Test
36+
public void isObjectReturnsTrue() {
37+
ObjectColor foo = ObjectColor.create("Foo", "test.js");
38+
39+
assertThat(foo).isObject();
40+
}
41+
42+
@Test
43+
public void isUnionHandlesReturnsFalse() {
44+
ObjectColor foo = ObjectColor.create("Foo", "test.js");
45+
46+
assertThat(foo.isUnion()).isFalse();
47+
}
48+
49+
@Test
50+
public void objectEqualityBasedOnClassAndFileName() {
51+
assertThat(ObjectColor.create("Foo", "test.js"))
52+
.isEqualTo(ObjectColor.create("Foo", "test.js"));
53+
}
54+
}

test/com/google/javascript/jscomp/colors/PrimitiveColorTest.java

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public void isPrimitiveReturnsTrue() {
3232
assertThat((Color) PrimitiveColor.UNKNOWN).isPrimitive();
3333
}
3434

35+
@Test
36+
public void isObjectReturnsFalse() {
37+
assertThat(PrimitiveColor.UNKNOWN.isObject()).isFalse();
38+
}
39+
3540
@Test
3641
public void isUnionReturnsFalse() {
3742
assertThat(PrimitiveColor.NUMBER.isUnion()).isFalse();

test/com/google/javascript/jscomp/colors/UnionColorTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ public void isPrimitiveReturnsFalse() {
3535
assertThat(numberOrString.isPrimitive()).isFalse();
3636
}
3737

38+
@Test
39+
public void isObjectReturnsFalse() {
40+
UnionColor numberOrString =
41+
UnionColor.create(ImmutableSet.of(PrimitiveColor.STRING, PrimitiveColor.NUMBER));
42+
43+
assertThat(numberOrString.isObject()).isFalse();
44+
}
45+
3846
@Test
3947
public void isUnionHandlesReturnsTrue() {
4048
UnionColor union =
@@ -91,4 +99,14 @@ public void unknownTypeIsNotSpecialCased() {
9199
assertThat(union).isUnion();
92100
assertThat(union.getAlternates()).hasSize(2);
93101
}
102+
103+
@Test
104+
public void unionOfEquivalentObjectsNotAllowed() {
105+
assertThrows(
106+
IllegalArgumentException.class,
107+
() ->
108+
UnionColor.create(
109+
ImmutableSet.of(
110+
ObjectColor.create("Foo", "test.js"), ObjectColor.create("Foo", "test.js"))));
111+
}
94112
}

0 commit comments

Comments
 (0)