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


##########
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 {

Review Comment:
   Method Definition: def init: List[A]
   Return Type: It returns all the elements of the list except the last one.
   
   // For all the initial steps, if they mention an array element, there must 
be a [N] element.
   
   I agree with Steve, let's call steps.init and rename this function to 
initStepsHaveIndexingPredicates.



##########
daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala:
##########
@@ -2295,6 +2295,18 @@ abstract class FunctionCallBase(
     res
   }
 
+  final def checkArgArray(): Unit = {
+    lazy val isArray = expressions.head match {
+      case rpe: RelativePathExpression => rpe.steps.last.isArray
+      case rpe: RootPathExpression => rpe.steps.last.isArray
+      case _ => true

Review Comment:
   Best to add a test to check so we can know for sure.



##########
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:
   Mike, please weigh in.



##########
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

Review Comment:
   Mike, do you concur?



##########
daffodil-core/src/main/scala/org/apache/daffodil/core/dpath/Expression.scala:
##########
@@ -969,16 +989,27 @@ sealed abstract class StepExpression(val step: String, 
val pred: Option[Predicat
   }
 
   final lazy val isArray: Boolean = {
-    val (arrays, scalars) = stepElements.partition { _.isArray }
-    (arrays.length, scalars.length) match {
+    checkAmbiguousPath
+    stepElements.exists(_.isArray)
+  }
+
+  final lazy val isOptional: Boolean = {
+    checkAmbiguousPath
+    stepElements.exists(_.isOptional)
+  }

Review Comment:
   Agreed.



##########
daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_functions/Functions.tdml:
##########
@@ -5150,6 +5147,51 @@
       </xs:complexType>
     </xs:element>
 
+    <xs:element name="count07">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="int" type="xs:int" minOccurs="2" maxOccurs="2" 
dfdl:representation="binary" />
+          <xs:element name="count" type="xs:int" dfdl:representation="binary" 
dfdl:inputValueCalc="{ fn:count(../ex:int) }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="count08">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="int" type="xs:int" dfdl:representation="binary" />
+          <xs:element name="count" type="xs:int" dfdl:representation="binary" 
dfdl:inputValueCalc="{ fn:count(../ex:int) }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="count09">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="int" type="xs:int" minOccurs="0" maxOccurs="1" 
dfdl:representation="binary" />
+          <xs:element name="count" type="xs:int" dfdl:representation="binary" 
dfdl:inputValueCalc="{ fn:count(../ex:int) }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="count10">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="int" type="xs:int" dfdl:representation="binary" />
+          <xs:element name="count" type="xs:int" dfdl:representation="binary" 
dfdl:outputValueCalc="{ fn:count(../ex:int) }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>
+
+    <xs:element name="count11">
+      <xs:complexType>
+        <xs:sequence>
+          <xs:element name="int" type="xs:int" dfdl:representation="binary" />
+          <xs:element name="count" type="xs:int" dfdl:representation="binary" 
dfdl:occursCountKind="expression" dfdl:occursCount="{ fn:count(../ex:int) }" />
+        </xs:sequence>
+      </xs:complexType>
+    </xs:element>

Review Comment:
   Makes sense.



##########
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

Review Comment:
   Mike, please weigh in.



-- 
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