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

stevedlawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git


The following commit(s) were added to refs/heads/main by this push:
     new edee1e2e1 Convert NodeInfo.Nothing from a lazy val to an object
edee1e2e1 is described below

commit edee1e2e1a609194110f0e6f87e91decd6f0cbab
Author: Steve Lawrence <[email protected]>
AuthorDate: Fri Apr 17 12:34:58 2026 -0400

    Convert NodeInfo.Nothing from a lazy val to an object
    
    The NodeInfo.Nothing instance has a `children` Delay member that never
    actually gets evaluated. This is fine and not unexpected since Nothing
    doesn't really have children and so nothing ever attempts to access or
    need the member.
    
    However, in some cases it is possible for the Nothing val to be
    referenced in a serialized class (e.g. in a DPath expression object that
    stores argument types such as fn:round-half-to-even) when creating a
    saved parser. And because this Nothing has a Delay that is never
    evaluated, it leads to an "object not initialized" exception, preventing
    creating a saved parser.
    
    To fix this issue, this changes NodeInfo.Nothing from a lazy val to an
    object. Whether we use a lazy val or an object here really does not make
    a difference with how we use it, but in Scala lazy vals are serialized
    while objects are not--Scala only serializes object names which are used
    to look up and return the singleton instance during deserialization.
    This allows us to avoid all possible serialization issues, and also
    changes Nothing to match the same pattern as all the other TypeNodes.
    
    DAFFODIL-3079
---
 .../apache/daffodil/runtime1/dpath/NodeInfo.scala  | 49 ++++++++++++----------
 .../calc_value_properties/outputValueCalc.tdml     | 29 +++++++++++++
 .../TestOutputValueCalc.scala                      |  1 +
 3 files changed, 57 insertions(+), 22 deletions(-)

diff --git 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
index fef41e7a6..d49e416cd 100644
--- 
a/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
+++ 
b/daffodil-core/src/main/scala/org/apache/daffodil/runtime1/dpath/NodeInfo.scala
@@ -297,29 +297,32 @@ object NodeInfo extends Enum {
   /**
    * Nothing is the bottom of the type lattice.
    *
-   * It is the return type of the dfdlx:error() function. It's a subtype of
+   * It is the return type of the fn:error() function. It's a subtype of
    * every type (except some special singletons like ArrayType).
    */
-  lazy val Nothing = new TypeNode(
-    Seq(
-      Boolean,
-      Complex,
-      Array,
-      ArrayIndex,
-      Double,
-      Float,
-      Date,
-      Time,
-      DateTime,
-      UnsignedByte,
-      Byte,
-      HexBinary,
-      AnyURI,
-      String,
-      NonEmptyString
-    ),
-    Nil
-  ) with Boolean.Kind
+  protected sealed trait NothingKind extends NodeInfo.Kind
+  case object Nothing
+    extends TypeNode(
+      Seq(
+        Boolean,
+        Complex,
+        Array,
+        ArrayIndex,
+        Double,
+        Float,
+        Date,
+        Time,
+        DateTime,
+        UnsignedByte,
+        Byte,
+        HexBinary,
+        AnyURI,
+        String,
+        NonEmptyString
+      ),
+      Nil
+    )
+    with Boolean.Kind
     with Complex.Kind
     with Array.Kind
     with ArrayIndex.Kind
@@ -332,7 +335,9 @@ object NodeInfo extends Enum {
     with Byte.Kind
     with HexBinary.Kind
     with NonEmptyString.Kind
-    with AnyURI.Kind
+    with AnyURI.Kind {
+    sealed trait Kind extends NothingKind
+  }
 
   /**
    * All complex types are represented by this one type object.
diff --git 
a/daffodil-test/src/test/resources/org/apache/daffodil/section17/calc_value_properties/outputValueCalc.tdml
 
b/daffodil-test/src/test/resources/org/apache/daffodil/section17/calc_value_properties/outputValueCalc.tdml
index a379d3a3c..c15cb3118 100644
--- 
a/daffodil-test/src/test/resources/org/apache/daffodil/section17/calc_value_properties/outputValueCalc.tdml
+++ 
b/daffodil-test/src/test/resources/org/apache/daffodil/section17/calc_value_properties/outputValueCalc.tdml
@@ -315,6 +315,15 @@
                        </xs:complexType>
                </xs:element>
 
+               <xs:element name="err_05">
+                       <xs:complexType>
+                               <xs:sequence>
+                                       <xs:element name="err1" type="xs:string"
+                                               
dfdl:outputValueCalc="{fn:round-half-to-even(fn:error('This is the error 
string'))}" />
+                               </xs:sequence>
+                       </xs:complexType>
+               </xs:element>
+
         <xs:element name="refSimpleElementWithOvc">
           <xs:complexType>
             <xs:sequence>
@@ -766,6 +775,26 @@
 
        </tdml:unparserTestCase>
 
+       <tdml:unparserTestCase name="errorInRoundHalfToEven"
+           root="err_05" model="outputValueCalc-Embedded.dfdl.xsd"
+           description="Calling fn:error() inside fn:round-half-to-even()">
+               <tdml:infoset>
+                       <tdml:dfdlInfoset 
xmlns:xs="http://www.w3.org/2001/XMLSchema";
+                               
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
+                               <ex:err_05>
+                                       <err1>a</err1>
+                               </ex:err_05>
+                       </tdml:dfdlInfoset>
+               </tdml:infoset>
+               <tdml:document />
+
+           <tdml:errors>
+                   <tdml:error>Unparse Error</tdml:error>
+                   <tdml:error>This is the error string</tdml:error>
+           </tdml:errors>
+
+       </tdml:unparserTestCase>
+
     <tdml:unparserTestCase name="refSimpleTypeElemWithOvc"
       root="refSimpleElementWithOvc" model="outputValueCalc-Embedded.dfdl.xsd"
       description="An element referencing a simpleType Elem with an OVC" 
roundTrip="false">
diff --git 
a/daffodil-test/src/test/scala/org/apache/daffodil/section17/calc_value_properties/TestOutputValueCalc.scala
 
b/daffodil-test/src/test/scala/org/apache/daffodil/section17/calc_value_properties/TestOutputValueCalc.scala
index d6387d96b..a0ec423f7 100644
--- 
a/daffodil-test/src/test/scala/org/apache/daffodil/section17/calc_value_properties/TestOutputValueCalc.scala
+++ 
b/daffodil-test/src/test/scala/org/apache/daffodil/section17/calc_value_properties/TestOutputValueCalc.scala
@@ -58,6 +58,7 @@ class TestOutputValueCalc1 extends TdmlTests {
   @Test def errorOneArg = test
   @Test def errorTwoArg = test
   @Test def errorThreeArg = test
+  @Test def errorInRoundHalfToEven = test
 
   // DAFFODIL-1701
   @Test def refSimpleTypeElemWithOvc = test

Reply via email to