in java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java [5570:5899]
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);
}