Skip to content

Commit b19daa1

Browse files
rahul-kamatcopybara-github
authored andcommitted
Quote string key properties in Polymer behaviors
Polymer behaviors with string key property on `listeners` and `hostAttributes` need to be marked as quoted. Otherwise we run the risk of renaming them. PiperOrigin-RevId: 715517294
1 parent cd82e21 commit b19daa1

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ public void process(Node externs, Node root) {
7575

7676
Node externsAndJsRoot = root.getParent();
7777
NodeTraversal.traverse(compiler, externsAndJsRoot, this);
78-
PolymerPassSuppressBehaviors suppressBehaviorsCallback =
79-
new PolymerPassSuppressBehaviors(compiler);
78+
PolymerPassSuppressBehaviorsAndProtectKeys suppressBehaviorsCallback =
79+
new PolymerPassSuppressBehaviorsAndProtectKeys(compiler);
8080
NodeTraversal.traverse(compiler, externsAndJsRoot, suppressBehaviorsCallback);
8181
}
8282

src/com/google/javascript/jscomp/PolymerPassSuppressBehaviors.java src/com/google/javascript/jscomp/PolymerPassSuppressBehaviorsAndProtectKeys.java

+20-2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@
2525
/**
2626
* For every Polymer Behavior, strip property type annotations and add suppress checktypes on
2727
* functions.
28+
*
29+
* <p>Also find listener and hostAttribute keys in the behavior, and mark them as quoted. This
30+
* protects the keys from being renamed.
2831
*/
29-
final class PolymerPassSuppressBehaviors extends ExternsSkippingCallback {
32+
final class PolymerPassSuppressBehaviorsAndProtectKeys extends ExternsSkippingCallback {
3033

3134
private final AbstractCompiler compiler;
3235

33-
PolymerPassSuppressBehaviors(AbstractCompiler compiler) {
36+
PolymerPassSuppressBehaviorsAndProtectKeys(AbstractCompiler compiler) {
3437
this.compiler = compiler;
3538
}
3639

@@ -42,6 +45,10 @@ public void visit(NodeTraversal t, Node n, Node parent) {
4245
return;
4346
}
4447

48+
// Find listener and hostAttribute keys in the behavior, and mark them as quoted.
49+
// This ensures that the keys are not renamed.
50+
traverseBehaviorandfindListenerAndHostAttributeAndMarkKeysAsQuoted(n);
51+
4552
// Add @nocollapse.
4653
JSDocInfo.Builder newDocs = JSDocInfo.Builder.maybeCopyFrom(n.getJSDocInfo());
4754
newDocs.recordNoCollapse();
@@ -55,6 +62,17 @@ public void visit(NodeTraversal t, Node n, Node parent) {
5562
}
5663
}
5764

65+
/** Traverse the behavior, find listener and hostAttribute keys, and mark them as quoted. */
66+
private void traverseBehaviorandfindListenerAndHostAttributeAndMarkKeysAsQuoted(Node n) {
67+
if (n.isObjectLit()) {
68+
PolymerPassStaticUtils.quoteListenerAndHostAttributeKeys(n, compiler);
69+
}
70+
71+
for (Node child = n.getFirstChild(); child != null; child = child.getNext()) {
72+
traverseBehaviorandfindListenerAndHostAttributeAndMarkKeysAsQuoted(child);
73+
}
74+
}
75+
5876
/** Strip property type annotations and add suppressions on functions. */
5977
private void suppressBehavior(Node behaviorValue, Node reportNode) {
6078
if (behaviorValue == null) {

test/com/google/javascript/jscomp/PolymerPassSuppressBehaviorsTest.java test/com/google/javascript/jscomp/PolymerPassSuppressBehaviorsAndProtectKeysTest.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import org.junit.runner.RunWith;
2222
import org.junit.runners.JUnit4;
2323

24-
/** Unit tests for {@link PolymerPassSuppressBehaviors} */
24+
/** Unit tests for {@link PolymerPassSuppressBehaviorsAndProtectKeys} */
2525
@RunWith(JUnit4.class)
26-
public class PolymerPassSuppressBehaviorsTest extends CompilerTestCase {
26+
public class PolymerPassSuppressBehaviorsAndProtectKeysTest extends CompilerTestCase {
2727

2828
private static final String EXTERNS =
2929
lines(
@@ -58,7 +58,7 @@ public class PolymerPassSuppressBehaviorsTest extends CompilerTestCase {
5858
"var Polymer = function(a) {};",
5959
"var alert = function(msg) {};");
6060

61-
public PolymerPassSuppressBehaviorsTest() {
61+
public PolymerPassSuppressBehaviorsAndProtectKeysTest() {
6262
super(EXTERNS);
6363
}
6464

@@ -67,8 +67,8 @@ protected CompilerPass getProcessor(final Compiler compiler) {
6767
return new CompilerPass() {
6868
@Override
6969
public void process(Node externs, Node root) {
70-
PolymerPassSuppressBehaviors suppressBehaviorsCallback =
71-
new PolymerPassSuppressBehaviors(compiler);
70+
PolymerPassSuppressBehaviorsAndProtectKeys suppressBehaviorsCallback =
71+
new PolymerPassSuppressBehaviorsAndProtectKeys(compiler);
7272
NodeTraversal.traverse(compiler, root, suppressBehaviorsCallback);
7373
}
7474
};

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

+29
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,35 @@ public void testListenersAndHostAttributeKeysQuoted() {
10521052
"X.prototype.handleClick;"));
10531053
}
10541054

1055+
@Test
1056+
public void testPolymerBehaviorListenersAndHostAttributeKeysQuoted() {
1057+
// Polymer behaviors with string key property on listeners and hostAttributes need to be marked
1058+
// as quoted.
1059+
// This is the bugfix for b/388337323.
1060+
test(
1061+
srcs(
1062+
lines(
1063+
"/** @polymerBehavior */",
1064+
"exports.CheckedOnTapBehavior = {",
1065+
" listeners: {tap: 'onTap'},",
1066+
" hostAttributes: {foo: 1},",
1067+
" onTap() {",
1068+
" this.checked = true;",
1069+
" },",
1070+
"};")),
1071+
expected(
1072+
lines(
1073+
"/** @polymerBehavior @nocollapse */",
1074+
"exports.CheckedOnTapBehavior = {",
1075+
" listeners: {'tap': 'onTap'},",
1076+
" hostAttributes: {'foo': 1},",
1077+
" /** @suppress {checkTypes|globalThis|visibility} */",
1078+
" onTap() {",
1079+
" this.checked = true;",
1080+
" },",
1081+
"};")));
1082+
}
1083+
10551084
@Test
10561085
public void testNativeElementExtension() {
10571086
String js = lines("Polymer({", " is: 'x-input',", " extends: 'input',", "});");

0 commit comments

Comments
 (0)