This is an automated email from the ASF dual-hosted git repository.

mbeckerle pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-daffodil.git


The following commit(s) were added to refs/heads/master by this push:
     new 82028c1  Throw SDE in the case of inputValueCalc containing 
checkConstraints(.)
82028c1 is described below

commit 82028c1ae85fd2461e633450cf9b13be4292e066
Author: Steinberger <[email protected]>
AuthorDate: Fri Sep 4 10:57:04 2020 -0400

    Throw SDE in the case of inputValueCalc containing checkConstraints(.)
    
    For inputValueCalc, you cannot use checkConstraints(.)
    because the inputValueCalc expression is computing that value.
    
    This commit also addresses the case of test_assertFailShowsValue2
    indicated in Daffodil-1043
    
    Daffodil-1035 Daffodil-1025 Daffodil-1043
---
 .../daffodil/debugger/InteractiveDebugger.scala    |   2 +-
 .../scala/org/apache/daffodil/dpath/DPath.scala    |  15 ++-
 .../org/apache/daffodil/infoset/InfosetImpl.scala  |  10 +-
 .../section23/dfdl_expressions/expressions.tdml    | 131 +++++++++++++--------
 .../dfdl_expressions/TestDFDLExpressions.scala     |   9 +-
 5 files changed, 108 insertions(+), 59 deletions(-)

diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
index 0746fe6..1480305 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/debugger/InteractiveDebugger.scala
@@ -1094,7 +1094,7 @@ class InteractiveDebugger(runner: 
InteractiveDebuggerRunner, eCompilers: Express
           // display the empty element.
           //
           case r: RuntimeSchemaDefinitionError if r.getCause() ne null => 
r.getCause() match {
-            case nd: InfosetNoDataException => {
+            case nd: InfosetNoDataExceptionBase => {
               //
               // Displays the empty element since it has no value.
               //
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
index b621ae3..9506810 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPath.scala
@@ -36,12 +36,13 @@ import org.apache.daffodil.infoset.DISimple
 import org.apache.daffodil.infoset.InfosetArrayIndexOutOfBoundsException
 import org.apache.daffodil.infoset.InfosetException
 import org.apache.daffodil.infoset.InfosetLengthUnknownException
-import org.apache.daffodil.infoset.InfosetNoDataException
+import org.apache.daffodil.infoset.InfosetNoDataExceptionBase
 import org.apache.daffodil.infoset.InfosetNoInfosetException
 import org.apache.daffodil.infoset.InfosetNoNextSiblingException
 import org.apache.daffodil.infoset.InfosetNoSuchChildElementException
 import org.apache.daffodil.infoset.InfosetNodeNotFinalException
 import org.apache.daffodil.infoset.OutputValueCalcEvaluationException
+import org.apache.daffodil.infoset.InfosetSelfReferencingException
 import org.apache.daffodil.processors.CompileState
 import org.apache.daffodil.processors.Failure
 import org.apache.daffodil.processors.ParseOrUnparseState
@@ -145,7 +146,7 @@ final class RuntimeExpressionDPath[T <: AnyRef](qn: 
NamedQName, tt: NodeInfo.Kin
 
             case ni: InfosetNoInfosetException => doPE(e, ps)
 
-            case nd: InfosetNoDataException => doPE(e, ps)
+            case nd: InfosetNoDataExceptionBase => doPE(e, ps)
 
             case ai: InfosetArrayIndexOutOfBoundsException => doPE(e, ps)
 
@@ -160,6 +161,14 @@ final class RuntimeExpressionDPath[T <: AnyRef](qn: 
NamedQName, tt: NodeInfo.Kin
             case _ => doSDE(e, ps)
           }
         }
+        case ParserNonBlocking => {
+          e match {
+            case nd: InfosetNoDataExceptionBase => doSDE(
+              new 
InfosetSelfReferencingException(state.dState.currentNode.asElement,
+              state.dState.currentNode.erd), ps)
+            case _ => doSDE(e, ps)
+          }
+        }
         case _ => doSDE(e, ps)
       }
       case us: UState => throw e
@@ -196,7 +205,7 @@ final class RuntimeExpressionDPath[T <: AnyRef](qn: 
NamedQName, tt: NodeInfo.Kin
         whereBlockedInfo.block(noSibling.diSimple, noSibling.info, 0, 
noSibling)
       case noArrayIndex: InfosetArrayIndexOutOfBoundsException =>
         whereBlockedInfo.block(noArrayIndex.diArray, 
noArrayIndex.diArray.erd.dpathElementCompileInfo, noArrayIndex.index, 
noArrayIndex)
-      case nd: InfosetNoDataException if nd.erd.outputValueCalcExpr.isDefined 
=> {
+      case nd: InfosetNoDataExceptionBase if 
nd.erd.outputValueCalcExpr.isDefined => {
         // we got a no-data exception from an element with outputValueCalc
         // that is, some OVC element requested the value of another OVC element
         val ovc = new OutputValueCalcEvaluationException(nd)
diff --git 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
index 70ad1ca..51b31cb 100644
--- 
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
+++ 
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/infoset/InfosetImpl.scala
@@ -233,10 +233,16 @@ case class InfosetNoInfosetException(val rd: 
Maybe[DPathCompileInfo])
  *
  * For complex types indicates has not been setNilled.
  */
-case class InfosetNoDataException(val diElement: DIElement, val erd: 
ElementRuntimeData)
-  extends ProcessingError("Expression Evaluation", 
One(erd.schemaFileLocation), Nope, "Element %s does not have a value.", 
erd.namedQName)
+sealed abstract class InfosetNoDataExceptionBase(val diElement: DIElement, val 
erd: ElementRuntimeData, message: String)
+  extends ProcessingError("Expression Evaluation", 
One(erd.schemaFileLocation), Nope, "%s %s", message, erd.namedQName)
   with InfosetException with RetryableException
 
+case class InfosetNoDataException(override val diElement: DIElement, override 
val erd: ElementRuntimeData)
+  extends InfosetNoDataExceptionBase(diElement, erd, "Element does not have a 
value.")
+
+case class InfosetSelfReferencingException(override val diElement: DIElement, 
override val erd: ElementRuntimeData)
+  extends InfosetNoDataExceptionBase(diElement, erd, "Self referencing element 
does not have a value.")
+
 case class InfosetArrayIndexOutOfBoundsException(val diArray: DIArray, val 
index: Long, val length: Long)
   extends ProcessingError("Expression Evaluation", Nope, Nope, "Value %d is 
out of range for the '%s' array with length %d", index, diArray.erd.namedQName, 
length)
   with InfosetException with RetryableException
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
index 11dd8b9..20429ae 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section23/dfdl_expressions/expressions.tdml
@@ -2306,26 +2306,58 @@
     </tdml:infoset>
   </tdml:parserTestCase>
 
+  <tdml:defineSchema name="selfReferencingExpression">
+  <xs:include 
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+  <dfdl:format ref="ex:GeneralFormat" />
+
+  <xs:simpleType name="cnt1">
+    <xs:restriction base="xs:int">
+      <xs:minInclusive value="0"/>
+      <xs:maxInclusive value="2"/>
+    </xs:restriction>
+  </xs:simpleType>
+
+  <xs:element name="sr1">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="cnt" type="xs:int" dfdl:lengthKind="delimited" />
+        <xs:sequence>
+          <xs:element name="v" type="ex:cnt1"
+                  dfdl:inputValueCalc="{ if (dfdl:checkConstraints(.)) then 
xs:int(../ex:cnt) else -1 }" />
+        </xs:sequence>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="sr2">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="cnt" type="xs:int" dfdl:lengthKind="delimited" />
+        <xs:sequence>
+          <xs:element name="v" type="xs:int" dfdl:lengthKind="explicit" 
dfdl:length="{.}" />
+        </xs:sequence>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:element name="sr3">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="cnt" type="xs:int" dfdl:lengthKind="delimited" />
+        <xs:sequence>
+          <xs:element name="v" type="ex:cnt1"
+                dfdl:inputValueCalc="{ dfdl:checkConstraints(if(../ex:cnt eq 
0) then ../ex:cnt else .) }" />
+        </xs:sequence>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  </tdml:defineSchema>
+
   <tdml:defineSchema name="checkConstraints">
     <xs:include 
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
     <dfdl:format ref="ex:GeneralFormat" />
-    <xs:element name="e1">
-      <xs:complexType>
-        <xs:sequence>
-          <xs:element name="cnt" type="xs:int"
-            dfdl:lengthKind="delimited" />
-          <xs:element name="a" minOccurs="0" maxOccurs="unbounded"
-            dfdl:occursCountKind="expression" dfdl:occursCount="{ 
xs:int(../ex:cnt) }">
-            <xs:complexType>
-              <xs:sequence>
-                <xs:element name="v" type="xs:int"
-                  dfdl:inputValueCalc="{ dfdl:checkConstraints(.) }" />
-              </xs:sequence>
-            </xs:complexType>
-          </xs:element>
-        </xs:sequence>
-      </xs:complexType>
-    </xs:element>
+
     <xs:element name="e2" dfdl:lengthKind="delimited">
       <xs:annotation>
         <xs:appinfo source="http://www.ogf.org/dfdl/";>
@@ -2339,6 +2371,7 @@
         </xs:restriction>
       </xs:simpleType>
     </xs:element>
+
     <xs:element name="e3" dfdl:lengthKind="delimited">
       <xs:annotation>
         <xs:appinfo source="http://www.ogf.org/dfdl/";>
@@ -2404,12 +2437,7 @@
         </xs:appinfo>
       </xs:annotation>
     </xs:element>
-    
-    <!--  This test is incorrect. An element of simple type cannot use "." 
-    in any inputValueCalc, as "." means "the value of this element", so 
-    we're chasing our tail here. -->
-    <xs:element name="e8" type="xs:int"
-      dfdl:inputValueCalc="{ dfdl:checkConstraints(.) }" />
+
     <xs:simpleType name="st1">
       <xs:restriction base="ex:st2">
         <xs:pattern value="[0-9]+" />
@@ -2435,41 +2463,50 @@
   </tdml:defineSchema>
 
 <!-- 
-     Test Name: dfdlCheckConstraints
-     Schema: checkConstraints
-     Purpose: This test demonstrates that checkConstraints cannot reference an 
inputValueCalc-ed element because the value is being computed by inputValueCalc
+     Test Name: dfdlCheckConstraintsSelfReference1
+     Schema: selfReferencingExpression
+     Purpose: This tests the error in the case of a self referencing 
checkConstraints without a value
 -->
 
-  <tdml:parserTestCase name="dfdlCheckConstraints"
-    root="e1" model="checkConstraints" description="DFDL-23-135R">
-    <tdml:document>6</tdml:document>
+  <tdml:parserTestCase name="dfdlSelfReferencingExpression1"
+                       root="sr1" model="selfReferencingExpression" 
description="DFDL-23-135R">
+    <tdml:document>1</tdml:document>
     <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Placeholder</tdml:error>
+      <tdml:error>Expression Evaluation Error</tdml:error>
+      <tdml:error>Self referencing</tdml:error>
+      <tdml:error>does not have a value</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
-  <tdml:parserTestCase name="checkConstraintsComplexTypeFails"
-    root="e7" model="checkConstraints" description="DFDL-23-135R">
-    <tdml:document>s1s2</tdml:document>
+<!--
+     Test Name: dfdlCheckConstraintsSelfReference2
+     Schema: selfReferencingExpression
+     Purpose: This tests the error in the case of a self referencing 
dfdl:length without a value
+-->
+
+  <tdml:parserTestCase name="dfdlSelfReferencingExpression2"
+                       root="sr2" model="selfReferencingExpression" 
description="DFDL-23-135R">
+    <tdml:document>1</tdml:document>
     <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>checkConstraints</tdml:error>
-      <tdml:error>AnyAtomic</tdml:error>
+      <tdml:error>Expression Evaluation Error</tdml:error>
+      <tdml:error>Self referencing</tdml:error>
+      <tdml:error>does not have a value</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
-<!-- 
-     Test Name: dfdlCheckConstraints2
-     Schema: checkConstraints
-     Purpose: This test demonstrates that checkConstraints cannot reference an 
inputValueCalc-ed element because the value is being computed by inputValueCalc
--->
-  <tdml:parserTestCase name="dfdlCheckConstraints2" validation="on"
-    root="e8" model="checkConstraints" description="DFDL-23-135R">
-    <tdml:document></tdml:document>
+  <!--
+     Test Name: dfdlCheckConstraintsSelfReference3
+     Schema: selfReferencingExpression
+     Purpose: This tests the error in the case of a self reference without a 
value
+  -->
+
+  <tdml:parserTestCase name="dfdlSelfReferencingExpression3"
+                       root="sr3" model="selfReferencingExpression" 
description="DFDL-23-135R">
+    <tdml:document>1</tdml:document>
     <tdml:errors>
-      <tdml:error>Schema Definition Error</tdml:error>
-      <tdml:error>Placeholder</tdml:error>
+      <tdml:error>Expression Evaluation Error</tdml:error>
+      <tdml:error>Self referencing</tdml:error>
+      <tdml:error>does not have a value</tdml:error>
     </tdml:errors>
   </tdml:parserTestCase>
 
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
index 1ae4501..36aa2df 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section23/dfdl_expressions/TestDFDLExpressions.scala
@@ -247,12 +247,9 @@ class TestDFDLExpressions {
   @Test def test_expresion_bad_path_to_element(): Unit = { 
runner.runOneTest("expresion_bad_path_to_element") }
   @Test def test_ArrayOptElem_02(): Unit = { 
runner.runOneTest("ArrayOptElem_02") }
 
-  //DFDL-1035 - tests need better diagnostic
-  //@Test def test_dfdlCheckConstraints() { 
runner.runOneTest("dfdlCheckConstraints") }
-  //@Test def test_dfdlCheckConstraints2() { 
runner.runOneTest("dfdlCheckConstraints2") }
-
-  // DFDL-1043
-  // @Test def test_checkConstraintsComplexTypeFails() { 
runner.runOneTest("checkConstraintsComplexTypeFails") }
+  @Test def test_dfdlSelfReferencingExpression1(): Unit = { 
runner.runOneTest("dfdlSelfReferencingExpression1") }
+  @Test def test_dfdlSelfReferencingExpression2(): Unit = { 
runner.runOneTest("dfdlSelfReferencingExpression2") }
+  @Test def test_dfdlSelfReferencingExpression3(): Unit = { 
runner.runOneTest("dfdlSelfReferencingExpression3") }
 
   @Test def test_nonFunctionIsDetected() = { 
runnerNV.runOneTest("nonFunctionIsDetected") }
   @Test def test_constantFunction1(): Unit = { 
runnerNV.runOneTest("constantFunction1") }

Reply via email to