private int diffTreeImpl0()

in java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java [5451:5780]


    private int diffTreeImpl0(JCTree oldT, JCTree newT, JCTree parent /*used only for modifiers*/, int[] elementBounds) {
        innerCommentsProcessed = false;
        if (oldT == null && newT != null)
            throw new IllegalArgumentException("Null is not allowed in parameters.");

        if (oldT == newT) {
            copyTo(elementBounds[0], elementBounds[1]);
            return elementBounds[1];
        }

        if (newT == null) {
            tokenSequence.move(elementBounds[1]);
            if (!tokenSequence.moveNext()) {
                return elementBounds[1];
            }
            while (tokenSequence.token().id() == JavaTokenId.WHITESPACE && tokenSequence.moveNext())
                ;
            return tokenSequence.offset();
        }

        if (printer.handlePossibleOldTrees(Collections.singletonList(newT), true)) {
            return getCommentCorrectedEndPos(oldT);
        }
        
        boolean handleImplicitLambda = parent != null && parent.hasTag(Tag.LAMBDA) && ((JCLambda)parent).params.size() == 1
                && ((JCLambda)parent).params.get(0) == oldT &&((JCLambda)parent).paramKind == JCLambda.ParameterKind.IMPLICIT
                && newT.hasTag(Tag.VARDEF) && ((JCVariableDecl)newT).getType() != null;
        if (handleImplicitLambda) {
            tokenSequence.move(getOldPos(parent));
            if (tokenSequence.moveNext() && tokenSequence.token().id() == JavaTokenId.LPAREN) {
                handleImplicitLambda = false;
            } else {
                printer.print("(");
            }
        }

        if (oldT.getTag() != newT.getTag()) {
            if (((compAssign.contains(oldT.getKind()) && compAssign.contains(newT.getKind())) == false) &&
                ((binaries.contains(oldT.getKind()) && binaries.contains(newT.getKind())) == false) &&
                ((unaries.contains(oldT.getKind()) && unaries.contains(newT.getKind())) == false)) {
                // different kind of trees found, print the whole new one.
                int[] oldBounds = getBounds(oldT);
                elementBounds[0] = getPosAfterCommentStart(oldT, elementBounds[0]);
                if (oldBounds[0] > elementBounds[0]) {
                    copyTo(elementBounds[0], oldBounds[0]);
                }
                printer.print(newT);
                // the printer will print attached traling comments, skip in the obsolete comments in the stream, so they don't duplicate.    
                return getPosAfterTreeComments(oldT, oldBounds[1]);
            }
        }
        
        // if comments are the same, diffPredComments will skip them so that printer.print(newT) will
        // not emit them from the new element. But if printer.print() won't be used (the newT will be merged in rather
        // than printed anew), then surviving comments have to be printed.
        int predComments = diffPrecedingComments(oldT, newT, getOldPos(oldT), elementBounds[0], 
                oldT.getTag() == Tag.TOPLEVEL && diffContext.forceInitialComment);
        int retVal = -1;
//        if (predComments < 0 && elementBounds[0] < -predComments) {
//            copyTo(elementBounds[0], -predComments);
//        }
        elementBounds[0] = Math.abs(predComments);
        int elementEnd = elementBounds[1];
        int commentsStart = Math.min(commentStart(diffContext, comments.getComments(oldT), CommentSet.RelativePosition.INLINE, endPos(oldT)), commentStart(diffContext, comments.getComments(oldT), CommentSet.RelativePosition.TRAILING, endPos(oldT)));
        if (commentsStart < elementBounds[1]) {
            int lastIndex;
            tokenSequence.move(commentsStart);
            elementBounds = Arrays.copyOf(elementBounds, elementBounds.length);
            elementBounds[1] = tokenSequence.movePrevious() && tokenSequence.token().id() == JavaTokenId.WHITESPACE &&
                    (lastIndex = tokenSequence.token().text().toString().lastIndexOf('\n')) > -1 ?
                    tokenSequence.offset() + lastIndex + 1 : commentsStart;
        }

        switch (oldT.getTag()) {
          case TOPLEVEL:
              diffTopLevel((JCCompilationUnit)oldT, (JCCompilationUnit)newT, elementBounds);
              break;
          case MODULEDEF:
              retVal = diffModuleDef((JCModuleDecl)oldT, (JCModuleDecl)newT, elementBounds);
              break;
          case REQUIRES:
              retVal = diffRequires((JCRequires)oldT, (JCRequires)newT, elementBounds);
              break;
          case EXPORTS:
              retVal = diffExports((JCExports)oldT, (JCExports)newT, elementBounds);
              break;
          case OPENS:
              retVal = diffOpens((JCOpens)oldT, (JCOpens)newT, elementBounds);
              break;
          case PROVIDES:
              retVal = diffProvides((JCProvides)oldT, (JCProvides)newT, elementBounds);
              break;
          case USES:
              retVal = diffUses((JCUses)oldT, (JCUses)newT, elementBounds);
              break;
          case PACKAGEDEF:
              retVal = diffPackage((JCPackageDecl)oldT, (JCPackageDecl)newT, getOldPos(oldT));
              break;
          case IMPORT:
              retVal = diffImport((JCImport)oldT, (JCImport)newT, elementBounds);
              break;
          case CLASSDEF:
              retVal = diffClassDef((JCClassDecl)oldT, (JCClassDecl)newT, elementBounds);
              break;
          case METHODDEF:
              retVal = diffMethodDef((JCMethodDecl)oldT, (JCMethodDecl)newT, elementBounds);
              break;
          case VARDEF:
              retVal = diffVarDef((JCVariableDecl)oldT, (JCVariableDecl)newT, elementBounds);
              break;
          case SKIP:
              copyTo(elementBounds[0], elementBounds[1]);
              retVal = elementBounds[1];
              break;
          case BLOCK:
              retVal = diffBlock((JCBlock)oldT, (JCBlock)newT, elementBounds);
              break;
          case DOLOOP:
              retVal = diffDoLoop((JCDoWhileLoop)oldT, (JCDoWhileLoop)newT, elementBounds);
              break;
          case WHILELOOP:
              retVal = diffWhileLoop((JCWhileLoop)oldT, (JCWhileLoop)newT, elementBounds);
              break;
          case FORLOOP:
              retVal = diffForLoop((JCForLoop)oldT, (JCForLoop)newT, elementBounds);
              break;
          case FOREACHLOOP:
              retVal = diffForeachLoop((JCEnhancedForLoop)oldT, (JCEnhancedForLoop)newT, elementBounds);
              break;
          case LABELLED:
              retVal = diffLabelled((JCLabeledStatement)oldT, (JCLabeledStatement)newT, elementBounds);
              break;
          case SWITCH:
              retVal = diffSwitch((JCSwitch)oldT, (JCSwitch)newT, elementBounds);
              break;
          case CASE:
              retVal = diffCase((JCCase)oldT, (JCCase)newT, elementBounds);
              break;
          case SYNCHRONIZED:
              retVal = diffSynchronized((JCSynchronized)oldT, (JCSynchronized)newT, elementBounds);
              break;
          case TRY:
              retVal = diffTry((JCTry)oldT, (JCTry)newT, elementBounds);
              break;
          case CATCH:
              retVal = diffCatch((JCCatch)oldT, (JCCatch)newT, elementBounds);
              break;
          case CONDEXPR:
              retVal = diffConditional((JCConditional)oldT, (JCConditional)newT, elementBounds);
              break;
          case IF:
              retVal = diffIf((JCIf)oldT, (JCIf)newT, elementBounds);
              break;
          case EXEC:
              retVal = diffExec((JCExpressionStatement)oldT, (JCExpressionStatement)newT, elementBounds);
              break;
          case BREAK:
              retVal = diffBreak((JCBreak)oldT, (JCBreak)newT, elementBounds);
              break;
          case CONTINUE:
              retVal = diffContinue((JCContinue)oldT, (JCContinue)newT, elementBounds);
              break;
          case RETURN:
              retVal = diffReturn((JCReturn)oldT, (JCReturn)newT, elementBounds);
              break;
          case THROW:
              retVal = diffThrow((JCThrow)oldT, (JCThrow)newT,elementBounds);
              break;
          case ASSERT:
              retVal = diffAssert((JCAssert)oldT, (JCAssert)newT, elementBounds);
              break;
          case APPLY:
              retVal = diffApply((JCMethodInvocation)oldT, (JCMethodInvocation)newT, elementBounds);
              break;
          case NEWCLASS:
              retVal = diffNewClass((JCNewClass)oldT, (JCNewClass)newT, elementBounds);
              break;
          case NEWARRAY:
              retVal = diffNewArray((JCNewArray)oldT, (JCNewArray)newT, elementBounds);
              break;
          case PARENS:
              retVal = diffParens((JCParens)oldT, (JCParens)newT, elementBounds);
              break;
          case ASSIGN:
              retVal = diffAssign((JCAssign)oldT, (JCAssign)newT, parent, elementBounds);
              break;
          case TYPECAST:
              retVal = diffTypeCast((JCTypeCast)oldT, (JCTypeCast)newT, elementBounds);
              break;
          case TYPETEST:
              retVal = diffTypeTest((JCInstanceOf)oldT, (JCInstanceOf)newT, elementBounds);
              break;
          case INDEXED:
              retVal = diffIndexed((JCArrayAccess)oldT, (JCArrayAccess)newT, elementBounds);
              break;
          case SELECT:
              retVal = diffSelect((JCFieldAccess)oldT, (JCFieldAccess)newT, elementBounds);
              break;
          case IDENT:
              retVal = diffIdent((JCIdent)oldT, (JCIdent)newT, elementBounds);
              break;
          case LITERAL:
              retVal = diffLiteral((JCLiteral)oldT, (JCLiteral)newT, elementBounds);
              break;
          case TYPEIDENT:
              retVal = diffTypeIdent((JCPrimitiveTypeTree)oldT, (JCPrimitiveTypeTree)newT, elementBounds);
              break;
          case TYPEARRAY:
              retVal = diffTypeArray((JCArrayTypeTree)oldT, (JCArrayTypeTree)newT, elementBounds);
              break;
          case TYPEAPPLY:
              retVal = diffTypeApply((JCTypeApply)oldT, (JCTypeApply)newT, elementBounds);
              break;
          case TYPEPARAMETER:
              retVal = diffTypeParameter((JCTypeParameter)oldT, (JCTypeParameter)newT, elementBounds);
              break;
          case WILDCARD:
              retVal = diffWildcard((JCWildcard)oldT, (JCWildcard)newT, elementBounds);
              break;
          case TYPEBOUNDKIND:
              retVal = diffTypeBoundKind((TypeBoundKind)oldT, (TypeBoundKind)newT, elementBounds);
              break;
          case ANNOTATION: case TYPE_ANNOTATION:
              retVal = diffAnnotation((JCAnnotation)oldT, (JCAnnotation)newT, elementBounds);
              break;
          case LETEXPR:
              diffLetExpr((LetExpr)oldT, (LetExpr)newT);
              break;
          case POS:
          case NEG:
          case NOT:
          case COMPL:
          case PREINC:
          case PREDEC:
          case POSTINC:
          case POSTDEC:
          case NULLCHK:
              retVal = diffUnary((JCUnary)oldT, (JCUnary)newT, elementBounds);
              break;
          case OR:
          case AND:
          case BITOR:
          case BITXOR:
          case BITAND:
          case EQ:
          case NE:
          case LT:
          case GT:
          case LE:
          case GE:
          case SL:
          case SR:
          case USR:
          case PLUS:
          case MINUS:
          case MUL:
          case DIV:
          case MOD:
              retVal = diffBinary((JCBinary)oldT, (JCBinary)newT, elementBounds);
              break;
          case BITOR_ASG:
          case BITXOR_ASG:
          case BITAND_ASG:
          case SL_ASG:
          case SR_ASG:
          case USR_ASG:
          case PLUS_ASG:
          case MINUS_ASG:
          case MUL_ASG:
          case DIV_ASG:
          case MOD_ASG:
              retVal = diffAssignop((JCAssignOp)oldT, (JCAssignOp)newT, elementBounds);
              break;
          case ERRONEOUS:
              retVal = diffErroneous((JCErroneous)oldT, (JCErroneous)newT, elementBounds);
              break;
          case MODIFIERS:
              retVal = diffModifiers((JCModifiers) oldT, (JCModifiers) newT, parent, elementBounds[0]);
              copyTo(retVal, elementBounds[1]);
              break;
          case TYPEUNION:
              retVal = diffUnionType((JCTypeUnion) oldT, (JCTypeUnion) newT, elementBounds);
              break;
          case LAMBDA:
              retVal = diffLambda((JCLambda) oldT, (JCLambda) newT, elementBounds);
              break;
          case REFERENCE:
              retVal = diffMemberReference((JCMemberReference) oldT, (JCMemberReference) newT, elementBounds);
              break;
          case ANNOTATED_TYPE:
              retVal = diffAnnotatedType((JCAnnotatedType)oldT, (JCAnnotatedType)newT, elementBounds);
              break;
          case SWITCH_EXPRESSION:
              retVal = diffSwitchExpression((JCSwitchExpression) oldT, (JCSwitchExpression) newT, elementBounds);
              break;
          case BINDINGPATTERN:
              retVal = diffBindingPattern((JCBindingPattern) oldT, (JCBindingPattern) newT, elementBounds);
              break;
          case DEFAULTCASELABEL:
              copyTo(elementBounds[0], elementBounds[1]);
              retVal = elementBounds[1];
              break;
          case CONSTANTCASELABEL:
              retVal = diffConstantCaseLabel((JCConstantCaseLabel) oldT, (JCConstantCaseLabel) newT, elementBounds);
              break;
          case RECORDPATTERN:
              retVal = diffRecordPattern((JCRecordPattern) oldT, (JCRecordPattern) newT, elementBounds);
              break;
          default:
              // handle special cases like field groups and enum constants
              if (oldT.getKind() == Kind.OTHER) {
                  if (oldT instanceof FieldGroupTree) {
                      return diffFieldGroup((FieldGroupTree) oldT, (FieldGroupTree) newT, elementBounds);
                  }
                  break;
              }
              String msg = "Diff not implemented: " +
                  ((com.sun.source.tree.Tree)oldT).getKind().toString() +
                  " " + oldT.getClass().getName();
              throw new AssertionError(msg);
        }
        if (handleImplicitLambda) {
            printer.print(")");
        }
        if (!innerCommentsProcessed) {
            retVal = diffInnerComments(oldT, newT, retVal);
        }
        int endComment = getCommentCorrectedEndPos(oldT);
        return diffTrailingComments(oldT, newT, retVal, endComment);
    }