Skip to content

Commit

Permalink
Don't convert goog.object.createSet calls with one argument to object…
Browse files Browse the repository at this point in the history
… literals

The method spec says:
If only one argument is provided and it is an array then this is used as the arguments, otherwise the arguments are used as the property names.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=225461926
  • Loading branch information
lauraharker authored and blickly committed Dec 15, 2018
1 parent c8db816 commit 52e2b9c
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 14 deletions.
Expand Up @@ -190,6 +190,15 @@ private void processObjectCreateSetCall(Node callNode) {
* Returns whether the given call to goog.object.createSet can be converted to an object literal.
*/
private boolean canOptimizeObjectCreateSet(Node firstParam) {
if (firstParam != null
&& firstParam.getNext() == null
&& !(firstParam.isNumber() || firstParam.isString())) {
// if there is only one argument, and it's an array, then the method uses the array elements
// as keys. Don't optimize it to {[arr]: true}. We only special-case number and string
// arguments in order to not regress ES5-out behavior
return false;
}

Node curParam = firstParam;
Set<String> keys = new HashSet<>();
while (curParam != null) {
Expand Down
Expand Up @@ -115,23 +115,23 @@ public void testObjectCreateNonConstKeyNotEs6() {
}

@Test
public void testObjectCreateSet1() {
public void testObjectCreateSetZeroArg() {
test("var a = goog.object.createSet()", "var a = {}");
}

@Test
public void testObjectCreateSet2() {
public void testObjectCreateSetTwoNumericalArgs() {
test("var a = goog.object.createSet(1,2)", "var a = {1:true,2:true}");
}

@Test
public void testObjectCreateSet3() {
public void testObjectCreateSetOneNumericalArg() {
test("alert(goog.object.createSet(1).toString())",
"alert({1:true}.toString())");
}

@Test
public void testObjectCreateSet4() {
public void testObjectCreateSetOneStringArg() {
test("goog.object.createSet('a').toString()", "({'a':true}).toString()");
}

Expand All @@ -155,9 +155,9 @@ public void testObjectCreateSetNonConstKey2() {
}

@Test
public void testObjectCreateSetNonConstKey3() {
test("goog.object.createSet(() => {}).toString()",
"({[() => {}]: true}).toString()");
public void testObjectCreateSetNonConstSingleKey() {
// this triggers the 'first argument may be an array' case and we back off
testSame("goog.object.createSet(() => {}).toString()");
}

@Test
Expand All @@ -166,6 +166,19 @@ public void testObjectCreateSetNonConstKeyNotEs6() {
testSame("var a = goog.object.createSet(foo, bar);");
}

@Test
public void testObjectCreateSetSingleNonLiteralArg() {
testSame("const arr = [1, 2, 3]; const s = goog.object.createSet(arr);");
testSame("const num = 1; const s = goog.object.createSet(num);");
testSame("const s = goog.object.createSet(undefined || [1, 2, 3]);");
}

@Test
public void testObjectCreateSetSingleLiteralArg() {
test("const s = goog.object.createSet(3);", "const s = {3: true};");
test("const s = goog.object.createSet('a');", "const s = {'a': true};");
}

@Test
public void testDomTagName() {
testSame("goog.dom.TagName.A = 'A';");
Expand All @@ -190,11 +203,13 @@ public void testPropertyReflectionAdvanced() {
}

@Test
public void testEs6Compatibility() {
public void testEs6ArrowCompatibility() {
// Arrow
test("var f = () => goog.object.create(1, 2);", "var f = () => ({1: 2});");
}

// Class
@Test
public void testEs6ClassCompatibility() {
test(
lines(
"class C {",
Expand All @@ -208,8 +223,10 @@ public void testEs6Compatibility() {
" this.x = {1: 2};",
" }",
"}"));
}

// Shorthand methods
@Test
public void testEs6MemberFunctionDefCompatibility() {
test(
lines(
"var obj = {",
Expand All @@ -223,8 +240,10 @@ public void testEs6Compatibility() {
" return {'a': 2};",
" }",
"}"));
}

// Computed Prop
@Test
public void testEs6ComputedPropCompatibility() {
test(
lines(
"var obj = {",
Expand All @@ -234,8 +253,10 @@ public void testEs6Compatibility() {
"var obj = {",
" [{1: 2}]: 42",
"}"));
}

// Template Literals
@Test
public void testEs6TemplateLitCompatibility() {
test(
lines(
"function tag(strings) {",
Expand All @@ -247,11 +268,15 @@ public void testEs6Compatibility() {
" return {'a': 2};",
"}",
"tag`template`"));
}

// Destructuring
@Test
public void testEs6DestructuringCompatibility() {
test("var {a: x} = goog.object.create('a', 2);", "var {a: x} = {'a': 2};");
}

// Async
@Test
public void testEs6AsyncCompatibility() {
test(
lines(
"async function foo() {",
Expand Down

0 comments on commit 52e2b9c

Please sign in to comment.