code: static TernaryValue getPureBooleanValue(Node n) {
      switch (n.getToken()) {
        case TEMPLATELIT:
          if (n.hasOneChild()) {
            return getPureBooleanValue(n.getFirstChild());
          }
          break;
        case TEMPLATELIT_STRING:
          return TernaryValue.forBoolean(
              null != n.getCookedString() && !n.getCookedString().isEmpty());
  
        case STRING:
          return TernaryValue.forBoolean(n.getString().length() > 0);
  
        case NUMBER:
          return TernaryValue.forBoolean(n.getDouble() != 0);
  
        case NOT:
          return getPureBooleanValue(n.getLastChild()).not();
  
        case NULL:
        case FALSE:
          return TernaryValue.FALSE;
  
        case VOID:
          if (!mayHaveSideEffects(n.getFirstChild())) {
            return TernaryValue.FALSE;
          }
          break;
  
        case NAME:
          String name = n.getString();
          if ("undefined".equals(name)
              || "NaN".equals(name)) {
            // We assume here that programs don't change the value of the keyword
            // undefined to something other than the value undefined.
            return TernaryValue.FALSE;
          } else if ("Infinity".equals(name)) {
            return TernaryValue.TRUE;
          }
          break;
  
        case TRUE:
        case REGEXP:
          return TernaryValue.TRUE;
  
        case FUNCTION:
        case CLASS:
        case NEW:
        case ARRAYLIT:
        case OBJECTLIT:
          if (!mayHaveSideEffects(n)) {
            return TernaryValue.TRUE;
          }
          break;
        default:
          break;
      }
  
      return TernaryValue.UNKNOWN;
    }
docs: Gets the boolean value of a node that represents a literal. This method
  effectively emulates the <code>Boolean()</code> JavaScript cast function
  except it return UNKNOWN for known values with side-effects, use
  getImpureBooleanValue if you don't care about side-effects.