src/com/google/javascript/rhino/Node.java
/**
   * @param compareType Whether to compare the JSTypes of the nodes.
   * @param recurse Whether to compare the children of the current node. If not, only the count
   *     of the children are compared.
   * @param jsDoc Whether to check that the JsDoc of the nodes are equivalent.
   * @param sideEffect Whether to check that the side-effect flags of the nodes are equivalent.
   * @return Whether this node is equivalent semantically to the provided node.
   */
@param compareType Whether to compare the JSTypes of the nodes.
@param recurse Whether to compare the children of the current node. If not, only the count
of the children are compared.
@param jsDoc Whether to check that the JsDoc of the nodes are equivalent.
@param sideEffect Whether to check that the side-effect flags of the nodes are equivalent.
@return Whether this node is equivalent semantically to the provided node.
@param compareType Whether to compare the JSTypes of the nodes . @param recurse Whether to compare the children of the current node . If not only the count of the children are compared . @param jsDoc Whether to check that the JsDoc of the nodes are equivalent . @param sideEffect Whether to check that the side - effect flags of the nodes are equivalent . @return Whether this node is equivalent semantically to the provided node .
public boolean isEquivalentTo(
      Node node, boolean compareType, boolean recurse, boolean jsDoc, boolean sideEffect) {
    if (token != node.token
        || getChildCount() != node.getChildCount()
        || this.getClass() != node.getClass()) {
      return false;
    }
    if (compareType && !JSType.isEquivalent(getJSType(), node.getJSType())) {
      return false;
    }
    if (jsDoc && !JSDocInfo.areEquivalent(getJSDocInfo(), node.getJSDocInfo())) {
      return false;
    }
    TypeDeclarationNode thisTDN = this.getDeclaredTypeExpression();
    TypeDeclarationNode thatTDN = node.getDeclaredTypeExpression();
    if ((thisTDN != null || thatTDN != null)
        && (thisTDN == null
            || thatTDN == null
            || !thisTDN.isEquivalentTo(thatTDN, compareType, recurse, jsDoc))) {
      return false;
    }
    if (token == Token.INC || token == Token.DEC) {
      int post1 = this.getIntProp(INCRDECR_PROP);
      int post2 = node.getIntProp(INCRDECR_PROP);
      if (post1 != post2) {
        return false;
      }
    } else if (token == Token.STRING || token == Token.STRING_KEY) {
      if (token == Token.STRING_KEY) {
        int quoted1 = this.getIntProp(QUOTED_PROP);
        int quoted2 = node.getIntProp(QUOTED_PROP);
        if (quoted1 != quoted2) {
          return false;
        }
      }
      int slashV1 = this.getIntProp(SLASH_V);
      int slashV2 = node.getIntProp(SLASH_V);
      if (slashV1 != slashV2) {
        return false;
      }
    } else if (token == Token.CALL) {
      if (this.getBooleanProp(FREE_CALL) != node.getBooleanProp(FREE_CALL)) {
        return false;
      }
    } else if (token == Token.FUNCTION) {
      if (this.isArrowFunction() != node.isArrowFunction()) {
        return false;
      }
    }
    if (sideEffect) {
      if (this.getSideEffectFlags() != node.getSideEffectFlags()) {
        return false;
      }
      if (this.isUnusedParameter() != node.isUnusedParameter()) {
        return false;
      }
    }
    if (recurse) {
      for (Node n = first, n2 = node.first;
           n != null;
           n = n.next, n2 = n2.next) {
        if (!n.isEquivalentTo(n2, compareType, recurse, jsDoc, sideEffect)) {
          return false;
        }
      }
    }
    return true;
  }
public boolean isEquivalentTo ( Node node , boolean compareType , boolean recurse , boolean jsDoc , boolean sideEffect ) { if ( token != node . token || getChildCount ( ) != node . getChildCount ( ) || this . getClass ( ) != node . getClass ( ) ) { return false ; } if ( compareType && ! JSType . isEquivalent ( getJSType ( ) , node . getJSType ( ) ) ) { return false ; } if ( jsDoc && ! JSDocInfo . areEquivalent ( getJSDocInfo ( ) , node . getJSDocInfo ( ) ) ) { return false ; } TypeDeclarationNode thisTDN = this . getDeclaredTypeExpression ( ) ; TypeDeclarationNode thatTDN = node . getDeclaredTypeExpression ( ) ; if ( ( thisTDN != null || thatTDN != null ) && ( thisTDN == null || thatTDN == null || ! thisTDN . isEquivalentTo ( thatTDN , compareType , recurse , jsDoc ) ) ) { return false ; } if ( token == Token . INC || token == Token . DEC ) { int post1 = this . getIntProp ( INCRDECR_PROP ) ; int post2 = node . getIntProp ( INCRDECR_PROP ) ; if ( post1 != post2 ) { return false ; } } else if ( token == Token . STRING || token == Token . STRING_KEY ) { if ( token == Token . STRING_KEY ) { int quoted1 = this . getIntProp ( QUOTED_PROP ) ; int quoted2 = node . getIntProp ( QUOTED_PROP ) ; if ( quoted1 != quoted2 ) { return false ; } } int slashV1 = this . getIntProp ( SLASH_V ) ; int slashV2 = node . getIntProp ( SLASH_V ) ; if ( slashV1 != slashV2 ) { return false ; } } else if ( token == Token . CALL ) { if ( this . getBooleanProp ( FREE_CALL ) != node . getBooleanProp ( FREE_CALL ) ) { return false ; } } else if ( token == Token . FUNCTION ) { if ( this . isArrowFunction ( ) != node . isArrowFunction ( ) ) { return false ; } } if ( sideEffect ) { if ( this . getSideEffectFlags ( ) != node . getSideEffectFlags ( ) ) { return false ; } if ( this . isUnusedParameter ( ) != node . isUnusedParameter ( ) ) { return false ; } } if ( recurse ) { for ( Node n = first , n2 = node . first ; n != null ; n = n . next , n2 = n2 . next ) { if ( ! n . isEquivalentTo ( n2 , compareType , recurse , jsDoc , sideEffect ) ) { return false ; } } } return true ; }
@param compareType Whether to compare the JSTypes of the nodes.
@param compareType Whether to compare the JSTypes of the nodes .