case CellRange.NO_INTERSECTION:
break;
case CellRange.CONTAINED: {
final ExpressionNode expr = buildExpressionModelForInnerRange( inner, next );
elts.add( expr );
next = null;
break;
}
case CellRange.FLOW_TILES: {
final CellRange before = tiling[ CellRange.FLOW_BEFORE ];
if (null != before) {
/*
* This is where we rely on proper sorting. It ensures that `before` cannot
* possibly overlap one of the remaining inner section to scan.
*/
if (shaped) {
elts.add( buildExpressionModelForLocalRange( before ) );
}
else {
buildExpressionModelsForLocalRangeCells( before, elts );
}
}
elts.add( buildExpressionModelForInnerRange( inner, tiling[ CellRange.FLOW_INNER ] ) );
next = tiling[ CellRange.FLOW_AFTER ];
break;
}
default:
throw new SpreadsheetException.SectionSpan( range.getShortName(), inner.toString() );
}
if (null == next) break;
}
if (null != next) {
if (0 == elts.size() || !shaped) {
buildExpressionModelsForLocalRangeCells( next, elts );
}
else {
elts.add( buildExpressionModelForLocalRange( next ) );
}
}
final CellIndex from = range.getFrom();
final ExpressionNode result = (shaped) ? new ExpressionNodeForArrayReference( new ArrayDescriptor(
from.getSheetIndex(), from.getRowIndex(), from.getColumnIndex(), sheets, rows, cols ) )
: new ExpressionNodeForSubstitution();
result.arguments().addAll( elts );
return result;
}