From 7bb038f4b3221d7e16949b4f40cb6bf6e063ad9d Mon Sep 17 00:00:00 2001 From: lharker Date: Mon, 7 Aug 2023 12:08:02 -0700 Subject: [PATCH] Fix ConcretizeStaticInheritanceForInlining bug adding semi-random new static props In theory, these properties were always dead-code eliminated and this won't affect the optimized code. There's a small chance some code accidentally referenced the added properties & will break. Such references should have caused type errors, though. PiperOrigin-RevId: 554551433 --- ...oncretizeStaticInheritanceForInlining.java | 8 ++++++- ...etizeStaticInheritanceForInliningTest.java | 22 ++++--------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInlining.java b/src/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInlining.java index f44c8a2e830..372b500229f 100644 --- a/src/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInlining.java +++ b/src/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInlining.java @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback; import com.google.javascript.rhino.IR; @@ -325,6 +326,9 @@ private void visitFunctionClassDef(Node n) { JSDocInfo classInfo = NodeUtil.getBestJSDocInfo(n); if (classInfo != null && classInfo.isConstructor()) { String name = NodeUtil.getName(n); + if (name == null) { + return; + } if (classByAlias.containsKey(name)) { duplicateClassNames.add(name); } else { @@ -334,6 +338,8 @@ private void visitFunctionClassDef(Node n) { } private void setAlias(String original, String alias) { + Preconditions.checkNotNull(original, "original is null"); + Preconditions.checkNotNull(alias, "alias is null"); checkArgument(classByAlias.containsKey(original)); classByAlias.put(alias, classByAlias.get(original)); } @@ -369,7 +375,7 @@ private void visitVariableDeclaration(Node n) { return; } String maybeOriginalName = child.getFirstChild().getQualifiedName(); - if (classByAlias.containsKey(maybeOriginalName)) { + if (maybeOriginalName != null && classByAlias.containsKey(maybeOriginalName)) { String maybeAlias = child.getQualifiedName(); if (maybeAlias != null) { setAlias(maybeOriginalName, maybeAlias); diff --git a/test/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInliningTest.java b/test/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInliningTest.java index 31c53d9e3a3..acdbb6d3bb6 100644 --- a/test/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInliningTest.java +++ b/test/com/google/javascript/jscomp/ConcretizeStaticInheritanceForInliningTest.java @@ -628,20 +628,9 @@ public void testAddSingletonGetter() { @Test public void testNonQnameConstructor_doesntPolluteListOfAssignments() { - // Reproduce a pretty bad bug caused by accidentally reading/writing 'null' keys from a map. - test( - lines( - "const ns = {};", - "/** @constructor */", - "ns['NOT_A_NAME'] = function() {};", - "ns['NOT_A_NAME'].staticMethod = function() { alert(1); }", - "", - "/** @constructor */", - "const Example = function() {}", - "", - "/** @constructor @extends {Example} */", - "function Subclass() {}", - "$jscomp.inherits(Subclass, Example);"), + // Reproduce a bug that once created a nonsensical assignment: + // Subclass.staticMethod = Example.staticMethod; + testSame( lines( "const ns = {};", "/** @constructor */", @@ -653,9 +642,6 @@ public void testNonQnameConstructor_doesntPolluteListOfAssignments() { "", "/** @constructor @extends {Example} */", "function Subclass() {}", - "$jscomp.inherits(Subclass, Example);", - // TODO(b/293320792) - stop producing this assignment, there's no - // actual Example.staticMethod. - "Subclass.staticMethod = Example.staticMethod;")); + "$jscomp.inherits(Subclass, Example);")); } }