code: private void removeUnreferencedVarsAndPolyfills() {
      for (Entry<Var, VarInfo> entry : varInfoMap.entrySet()) {
        Var var = entry.getKey();
        VarInfo varInfo = entry.getValue();
  
        if (!varInfo.isRemovable()) {
          continue;
        }
  
        // Regardless of what happens to the original declaration,
        // we need to remove all assigns, because they may contain references
        // to other unreferenced variables.
        varInfo.removeAllRemovables();
  
        Node nameNode = var.nameNode;
        Node toRemove = nameNode.getParent();
        if (toRemove == null || alreadyRemoved(toRemove)) {
          // assignedVarInfo.removeAllRemovables () already removed it
        } else if (NodeUtil.isFunctionExpression(toRemove)) {
          // TODO(bradfordcsmith): Add a Removable for this case.
          if (!preserveFunctionExpressionNames) {
            Node fnNameNode = toRemove.getFirstChild();
            compiler.reportChangeToEnclosingScope(fnNameNode);
            fnNameNode.setString("");
          }
        } else {
          // Removables are not created for theses cases.
          // function foo(unused1 = someSideEffectingValue, ...unused2) {}
          // removeUnreferencedFunctionArgs() is responsible for removing these.
          // TODO(bradfordcsmith): handle parameter declarations with removables
          checkState(
              toRemove.isParamList()
                  || (toRemove.getParent().isParamList()
                      && (toRemove.isDefaultValue() || toRemove.isRest())),
              "unremoved code: %s",
              toRemove);
        }
      }
  
      Iterator<PolyfillInfo> iter = polyfills.values().iterator();
      while (iter.hasNext()) {
        PolyfillInfo polyfill = iter.next();
        if (polyfill.isRemovable) {
          polyfill.removable.remove(compiler);
          iter.remove();
        }
      }
    }
docs: Removes any vars in the scope that were not referenced. Removes any assignments to those
  variables as well.