private void handleLineTooLongSmartly() {
// search for closest breakable alignment, using tiebreak rules
// look for outermost breakable one
int relativeDepth = 0, outerMostDepth = -1;
Alignment targetAlignment = this.currentAlignment;
int previousKind = -1;
int insideMessage = 0;
boolean insideStringConcat = false;
while (targetAlignment != null){
boolean couldBreak = targetAlignment.tieBreakRule == Alignment.R_OUTERMOST ||
(!insideStringConcat &&
insideMessage > 0 && targetAlignment.kind == Alignment.MESSAGE_ARGUMENTS &&
(!targetAlignment.wasReset() || previousKind != Alignment.MESSAGE_SEND));
if (couldBreak && targetAlignment.couldBreak()){
outerMostDepth = relativeDepth;
}
switch (targetAlignment.kind) {
case Alignment.MESSAGE_ARGUMENTS:
case Alignment.MESSAGE_SEND:
insideMessage++;
break;
case Alignment.STRING_CONCATENATION:
insideStringConcat = true;
break;
}
previousKind = targetAlignment.kind;
targetAlignment = targetAlignment.enclosing;
relativeDepth++;
}
if (outerMostDepth >= 0) {
throw new AlignmentException(AlignmentException.LINE_TOO_LONG, outerMostDepth);
}
// look for innermost breakable one
relativeDepth = 0;
targetAlignment = this.currentAlignment;
AlignmentException alignmentException = null;
int msgArgsDepth = -1;
while (targetAlignment != null) {
if (targetAlignment.kind == Alignment.MESSAGE_ARGUMENTS) {
msgArgsDepth = relativeDepth;
}
if (alignmentException == null) {
if (targetAlignment.couldBreak()) {
// do not throw the exception immediately to have a chance to reset
// previously broken alignments (see bug 203588)
alignmentException = new AlignmentException(AlignmentException.LINE_TOO_LONG, relativeDepth);
if (insideStringConcat) throw alignmentException;
}
} else if (targetAlignment.wasSplit) {
// reset the nearest already broken outermost alignment.
// Note that it's not done twice to avoid infinite loop while raising
// the exception on an innermost alignment...
if (!targetAlignment.wasReset()) {
targetAlignment.reset();
if (msgArgsDepth > alignmentException.relativeDepth) {
alignmentException.relativeDepth = msgArgsDepth;
}
throw alignmentException;
}