code: private boolean isSafeAssign(Node n, boolean seenSideEffects) {
      if (n.isAssign()) {
        Node lhs = n.getFirstChild();
        switch (lhs.getToken()) {
          case NAME:
            return true;
          case GETPROP:
            return !isExpressionTreeUnsafe(lhs.getFirstChild(), seenSideEffects);
          case GETELEM:
            return !isExpressionTreeUnsafe(lhs.getFirstChild(), seenSideEffects)
                && !isExpressionTreeUnsafe(lhs.getLastChild(), seenSideEffects);
          default:
            break;
        }
      }
      return false;
    }
docs: It is always safe to inline "foo()" for expressions such as "a = b = c = foo();" As the
  assignment is unaffected by side effect of "foo()" and the names assigned-to can not influence
  the state before the call to foo.
  
  <p>It is also safe in cases where the object is constant:
  
  <pre>
  CONST_NAME.a = foo()
  CONST_NAME[CONST_VALUE] = foo();
  </pre>
  
  <p>This is not true of more complex LHS values, such as
  
  <pre>
  a.x = foo();
  next().x = foo();
  </pre>
  
  in these cases the checks below are necessary.
  
  @param seenSideEffects If true, check to see if node-tree maybe affected by side-effects,
  otherwise if the tree has side-effects. @see isExpressionTreeUnsafe
  @return Whether the assignment is safe from side-effects.