mbeckerle commented on code in PR #1137:
URL: https://github.com/apache/daffodil/pull/1137#discussion_r1462378649


##########
daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala:
##########
@@ -744,21 +744,41 @@ abstract class PathExpression() extends Expression {
    * about an array such as its current count.
    */
   lazy val isPathToOneWholeArray: Boolean = {
-    if (steps == Nil) false // root is never an array
+    isNotRootOrSelf &&
+    steps.last.isArray &&
+    priorStepsHaveIndexingPredicates
+  }
+
+  /**
+   * Path to a single array element without a [N] predicate qualifying it
+   * or to an optional element.
+   *
+   * That is, the kind of path expression used to access information
+   * about an array or optional such as its current count.
+   */
+  lazy val isPathToOneWholeArrayOrOptional: Boolean = {
+    isNotRootOrSelf &&
+    (steps.last.isArray || steps.last.isOptional) &&
+    priorStepsHaveIndexingPredicates
+  }
+
+  private lazy val isNotRootOrSelf: Boolean = {
     if (steps == Nil) false // root is never an array
     else if (isSelf) false // self path is never an array
-    else
-      steps.last.isArray &&
-      !steps.last.pred.isDefined && // 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.
-        step =>
-          if (step.isInstanceOf[Up]) true
-          else if (step.isArray) step.pred.isDefined
-          else true
-      }
+    else true
+  }
+
+  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.
+      step =>
+        if (step.isInstanceOf[Up]) true
+        else if (step.isArray) step.pred.isDefined // no special case to check 
for optional

Review Comment:
   Looking at the code, [exp] is supposed to be tolerated so long as exp 
evaluates to 1, even on scalars. 
   There is a TODO in the code saying "implement this".
   
   Blech. 
   
   This was part of the misguided (I now think) approach the DFDL work group 
used where there was this notion that DFDL expressions could be implemented by 
re-purposing an XPath interpreter. When you have no schema, then you have no 
idea what's an array, what's optional, what's scalar. Every XPath expression is 
potentially a query that returns a node list. Every element is potentially an 
array or optional. 
   
   When you have a schema compiler it is decidedly NON helpful to allow 
expressions which are almost always mistakes when you have the information from 
the schema which tells you that you are indexing something where that's not 
meaningful. 
   
   So the DFDL spec says an implementation can issue a warning about these 
things. I would go further and say that these things should have 3 states: 
allow, warning, error. But I would default these to error, and make people 
express that they want warning or allow. 
   
   Frankly, i don't want to bother implementing warning nor allow unless 
someone complains about it. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to