Skip to content

Commit

Permalink
Update array length checks
Browse files Browse the repository at this point in the history
DAFFODIL-2711

Expression.scala: Update login to check prior steps for indexing predicates, require path expressions for arrays and optionals used in fn:count function.

Functions.tdml: Add tests for count function. Note that using a group reference for an optional when combined with an array will throw a ClassCastException, this may be a bug.

TestDFDLExpressions.scala: Add tests for count expressions.
  • Loading branch information
pkatlic committed Jan 29, 2024
1 parent ff0912e commit 210cdc3
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -780,17 +780,10 @@ abstract class PathExpression() extends Expression {
private lazy val priorStepsHaveIndexingPredicates: Boolean = {
steps.last.pred.isEmpty && // last cannot have a [N] pred
steps.dropRight(1).forall {
// for all the prior steps
// if they mention an array element, there
// must be a [N] predicate.
// neither Up (..) nor Self (.) steps should have indexing
step =>
if (step.isInstanceOf[Up]) true
else if (step.isInstanceOf[Up2]) SDE("Up2 step must not have indexing")
else if (step.isInstanceOf[Self]) SDE("Self step must not have indexing")
else if (step.isInstanceOf[Self2]) SDE("Self2 step must not have indexing")
else if (step.isArray) step.pred.isDefined // no special case to check for optional
else true
case _: Up => true
case _: Up2 => SDE("Up2 step must not have indexing")
case _: SelfStepExpression => SDE("Self step must not have indexing")
case step => !step.isArray || step.pred.isDefined
}
}

Expand Down Expand Up @@ -2342,17 +2335,15 @@ abstract class FunctionCallBase(
protected def checkArgArrayOrOptional(): Unit = {
lazy val isArrayOrOptional = expressions.head match {
case pe: PathExpression => pe.isPathToOneWholeArrayOrOptional
case ie: IfExpression => {
val tp = ie.thenPart
val ep = ie.elsePart
tp.isPathToOneWholeArrayOrOptional || ep.isPathToOneWholeArrayOrOptional
}
case _ => true
case _ => false
}
if (!isArrayOrOptional) argArrayOrOptionalErr()
}
protected def argArrayOrOptionalErr() = {
SDE("The %s function requires an array or optional.", functionQName.toPrettyString)
SDE(
"The %s function requires an array or optional path expression.",
functionQName.toPrettyString,
)
}

final def checkArgCount(n: Int): Unit = {
Expand Down
Loading

0 comments on commit 210cdc3

Please sign in to comment.