src/com/google/javascript/jscomp/NodeUtil.java
/**
   * Returns true if this is a literal value. We define a literal value
   * as any node that evaluates to the same thing regardless of when or
   * where it is evaluated. So /xyz/ and [3, 5] are literals, but
   * the name a is not.
   *
   * <p>Function literals do not meet this definition, because they
   * lexically capture variables. For example, if you have
   * <code>
   * function() { return a; }
   * </code>
   * If it is evaluated in a different scope, then it
   * captures a different variable. Even if the function did not read
   * any captured variables directly, it would still fail this definition,
   * because it affects the lifecycle of variables in the enclosing scope.
   *
   * <p>However, a function literal with respect to a particular scope is
   * a literal.
   *
   * @param includeFunctions If true, all function expressions will be
   *     treated as literals.
   */
Returns true if this is a literal value. We define a literal value
as any node that evaluates to the same thing regardless of when or
where it is evaluated. So /xyz/ and [3, 5] are literals, but
the name a is not.

Function literals do not meet this definition, because they
lexically capture variables. For example, if you have

function() { return a; }

If it is evaluated in a different scope, then it
captures a different variable. Even if the function did not read
any captured variables directly, it would still fail this definition,
because it affects the lifecycle of variables in the enclosing scope.

However, a function literal with respect to a particular scope is
a literal.

@param includeFunctions If true, all function expressions will be
treated as literals.
Returns true if this is a literal value . We define a literal value as any node that evaluates to the same thing regardless of when or where it is evaluated . So / xyz / and [ 3 5 ] are literals but the name a is not . Function literals do not meet this definition because they lexically capture variables . For example if you have function () { return a ; } If it is evaluated in a different scope then it captures a different variable . Even if the function did not read any captured variables directly it would still fail this definition because it affects the lifecycle of variables in the enclosing scope . However a function literal with respect to a particular scope is a literal . @param includeFunctions If true all function expressions will be treated as literals .
public static boolean isLiteralValue(Node n, boolean includeFunctions) {
    switch (n.getToken()) {
      case CAST:
        return isLiteralValue(n.getFirstChild(), includeFunctions);
      case ARRAYLIT:
        for (Node child = n.getFirstChild(); child != null; child = child.getNext()) {
          if ((!child.isEmpty()) && !isLiteralValue(child, includeFunctions)) {
            return false;
          }
        }
        return true;
      case REGEXP:
        for (Node child = n.getFirstChild(); child != null; child = child.getNext()) {
          if (!isLiteralValue(child, includeFunctions)) {
            return false;
          }
        }
        return true;
      case OBJECTLIT:
        for (Node child = n.getFirstChild(); child != null; child = child.getNext()) {
          if (child.isMemberFunctionDef() || NodeUtil.isGetOrSetKey(child)) {
            if (!includeFunctions) {
              return false;
            }
          } else if (child.isComputedProp()) {
            if (!isLiteralValue(child.getFirstChild(), includeFunctions)
                || !isLiteralValue(child.getLastChild(), includeFunctions)) {
              return false;
            }
          } else if (child.isSpread()) {
            if (!isLiteralValue(child.getOnlyChild(), includeFunctions)) {
              return false;
            }
          } else {
            checkState(child.isStringKey(), child);
            if (!isLiteralValue(child.getOnlyChild(), includeFunctions)) {
              return false;
            }
          }
        }
        return true;
      case FUNCTION:
        return includeFunctions && !NodeUtil.isFunctionDeclaration(n);
      case TEMPLATELIT:
        for (Node child = n.getFirstChild(); child != null; child = child.getNext()) {
          if (child.isTemplateLitSub()) {
            if (!isLiteralValue(child.getFirstChild(), includeFunctions)) {
              return false;
            }
          }
        }
        return true;
      default:
        return isImmutableValue(n);
    }
  }
public static boolean isLiteralValue ( Node n , boolean includeFunctions ) { switch ( n . getToken ( ) ) { case CAST : return isLiteralValue ( n . getFirstChild ( ) , includeFunctions ) ; case ARRAYLIT : for ( Node child = n . getFirstChild ( ) ; child != null ; child = child . getNext ( ) ) { if ( ( ! child . isEmpty ( ) ) && ! isLiteralValue ( child , includeFunctions ) ) { return false ; } } return true ; case REGEXP : for ( Node child = n . getFirstChild ( ) ; child != null ; child = child . getNext ( ) ) { if ( ! isLiteralValue ( child , includeFunctions ) ) { return false ; } } return true ; case OBJECTLIT : for ( Node child = n . getFirstChild ( ) ; child != null ; child = child . getNext ( ) ) { if ( child . isMemberFunctionDef ( ) || NodeUtil . isGetOrSetKey ( child ) ) { if ( ! includeFunctions ) { return false ; } } else if ( child . isComputedProp ( ) ) { if ( ! isLiteralValue ( child . getFirstChild ( ) , includeFunctions ) || ! isLiteralValue ( child . getLastChild ( ) , includeFunctions ) ) { return false ; } } else if ( child . isSpread ( ) ) { if ( ! isLiteralValue ( child . getOnlyChild ( ) , includeFunctions ) ) { return false ; } } else { checkState ( child . isStringKey ( ) , child ) ; if ( ! isLiteralValue ( child . getOnlyChild ( ) , includeFunctions ) ) { return false ; } } } return true ; case FUNCTION : return includeFunctions && ! NodeUtil . isFunctionDeclaration ( n ) ; case TEMPLATELIT : for ( Node child = n . getFirstChild ( ) ; child != null ; child = child . getNext ( ) ) { if ( child . isTemplateLitSub ( ) ) { if ( ! isLiteralValue ( child . getFirstChild ( ) , includeFunctions ) ) { return false ; } } } return true ; default : return isImmutableValue ( n ) ; } }
Returns true if this is a literal value.
Returns true if this is a literal value .
// Return true only if all descendants are const. // { methodName() {...} } // { get propertyName() {...} } // { set propertyName(value) {...} } // { [key_expression]: value, ... } // { [key_expression](args) {...}, ... } // { key: value, ... } // { "quoted_key": value, ... }