stevedlawrence closed pull request #153: Add a distinction between how
expressions and literals are compiled
URL: https://github.com/apache/incubator-daffodil/pull/153
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
index 9ca821949..4e541cd2f 100644
---
a/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
+++
b/daffodil-cli/src/it/scala/org/apache/daffodil/debugger/TestCLIDebugger.scala
@@ -253,7 +253,7 @@ class TestCLIdebugger {
shell.sendLine("condition 2 dfdl:occursIndex() mod 2 eq 0")
shell.sendLine("info breakpoints")
- shell.expect(contains("2: cell dfdl:occursIndex() mod 2 eq 0"))
+ shell.expect(contains("2: cell { dfdl:occursIndex() mod 2 eq 0 }"))
shell.sendLine("display info arrayIndex")
@@ -311,10 +311,10 @@ class TestCLIdebugger {
shell.sendLine("break cell")
shell.expect(contains("1: cell"))
shell.sendLine("condition 1 xsd:string(.) eq '3'")
- shell.expect(contains("1: cell xsd:string(.) eq '3'"))
+ shell.expect(contains("1: cell { xsd:string(.) eq '3' }"))
shell.sendLine("info breakpoints")
- shell.expect(allOf(contains("breakpoints:"), contains("1: cell
xsd:string(.) eq '3'")))
+ shell.expect(allOf(contains("breakpoints:"), contains("1: cell {
xsd:string(.) eq '3' }")))
shell.sendLine("continue")
shell.expect(contains("<tns:cell>3</tns:cell>\n </tns:row>\n
</tns:matrix>"))
@@ -424,7 +424,7 @@ class TestCLIdebugger {
shell.sendLine("condition 1 dfdl:occursIndex() eq 3")
shell.sendLine("info breakpoints")
- shell.expect(contains("1: cell dfdl:occursIndex() eq 3"))
+ shell.expect(contains("1: cell { dfdl:occursIndex() eq 3 }"))
shell.sendLine("continue")
shell.expect(contains("</tns:cell>"))
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
index b67fe2659..140d5f77d 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/dpath/DFDLExpressionParser.scala
@@ -191,9 +191,8 @@ class DFDLPathExpressionParser[T <: AnyRef](qn: NamedQName,
def EqualityComp = "eq" | "ne" | "!=" | "="
def NumberComp = "lt" | "le" | "gt" | "ge" | "<=" | ">=" | "<" | ">"
def Comp = EqualityComp | NumberComp
- //
- // we don't care if it has braces around it or not.
- def TopLevel: Parser[WholeExpression] = ("{" ~> Expr <~ "}" | Expr) ^^ { xpr
=>
+
+ def TopLevel: Parser[WholeExpression] = ("{" ~> Expr <~ "}") ^^ { xpr =>
WholeExpression(nodeInfoKind, xpr, namespaces, context, host)
}
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
index 6e1325d0c..5a32a7784 100644
---
a/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
+++
b/daffodil-core/src/main/scala/org/apache/daffodil/dsom/CompiledExpression.scala
@@ -18,6 +18,7 @@
package org.apache.daffodil.dsom
import org.apache.daffodil.dpath._
+import org.apache.daffodil.dpath.NodeInfo.PrimType
import scala.xml.NamespaceBinding
import org.apache.daffodil.xml.NamedQName
import java.lang.{ Long => JLong, Boolean => JBoolean }
@@ -34,20 +35,49 @@ object ExpressionCompilers extends ExpressionCompilerClass {
class ExpressionCompiler[T <: AnyRef] extends ExpressionCompilerBase[T] {
/**
- * Compiles the expression.
+ * Compiles an expression or a literl value. If the passed in string does not
+ * start with an unescaped curly brace it is treated as a literal value.
*
- * This method available at compilation and also at runtime for use by the
debuggger.
+ * An expression could be evaluated as constant as in { 5 } or {
"California" },
+ * and in that case this should return a ConstantExpression object.
+ * Non-constant expressions will return a RuntimeExpressionDPath.
+ *
+ * Literal values (i.e. those that do not start with a unescape curly brace),
+ * will be converted to a privite value as defined by nodeInfoKind and will
+ * return a ConstantExpression with that value.
*
- * Expression may or may not have braces around it. It could still be a
constant as in
- * { 5 } or { "California" }, and in that case this should return a
ConstantExpression
- * object.
+ * This method available at compilation and also at runtime for use by the
debuggger.
*/
- def compileExpression(qn: NamedQName, nodeInfoKind: NodeInfo.Kind,
exprWithBracesMaybe: String, namespaces: NamespaceBinding,
+ def compileExpression(
+ qn: NamedQName,
+ nodeInfoKind: NodeInfo.Kind,
+ exprOrLiteral: String,
+ namespaces: NamespaceBinding,
compileInfoWherePropertyWasLocated: DPathCompileInfo,
- isEvaluatedAbove: Boolean, host: OOLAGHost): CompiledExpression[T] = {
- val (exprForCompiling, isRealExpression) =
exprOrLiteral(exprWithBracesMaybe, nodeInfoKind,
compileInfoWherePropertyWasLocated)
- compileExpression1(qn, nodeInfoKind, exprForCompiling, namespaces,
compileInfoWherePropertyWasLocated, isEvaluatedAbove, host,
- isRealExpression)
+ isEvaluatedAbove: Boolean,
+ host: OOLAGHost): CompiledExpression[T] = {
+
+ val res =
+ if (DPathUtil.isExpression(exprOrLiteral)) {
+ compileRealExpression(
+ qn,
+ nodeInfoKind,
+ exprOrLiteral,
+ namespaces,
+ compileInfoWherePropertyWasLocated,
+ isEvaluatedAbove,
+ host)
+ } else {
+ convertLiteralToConstant(
+ qn,
+ nodeInfoKind,
+ exprOrLiteral,
+ namespaces,
+ compileInfoWherePropertyWasLocated,
+ isEvaluatedAbove,
+ host)
+ }
+ res
}
/**
@@ -64,13 +94,22 @@ class ExpressionCompiler[T <: AnyRef] extends
ExpressionCompilerBase[T] {
* paths. In that case those relative paths will all have to be adjusted
* so they work in the context of one node above.
*/
- def compileProperty(qn: NamedQName, nodeInfoKind: NodeInfo.Kind, property:
Found, host: OOLAGHost, isEvaluatedAbove: Boolean = false):
CompiledExpression[T] =
- compileExpression(qn,
+ def compileProperty(
+ qn: NamedQName,
+ nodeInfoKind: NodeInfo.Kind,
+ property: Found,
+ host: OOLAGHost,
+ isEvaluatedAbove: Boolean = false): CompiledExpression[T] = {
+
+ compileExpression(
+ qn,
nodeInfoKind,
property.value,
property.location.namespaces,
propertyCompileInfo(property),
- isEvaluatedAbove, host)
+ isEvaluatedAbove,
+ host)
+ }
/**
* Compile a potentially runtime-valued delimiter property
@@ -91,26 +130,39 @@ class ExpressionCompiler[T <: AnyRef] extends
ExpressionCompilerBase[T] {
* We don't want to allow turning on/off whether a format is delimited or
* not based on runtime expressions, only what the delimiters are.
*/
- def compileDelimiter(qn: NamedQName, staticNodeInfoKind: NodeInfo.Kind,
runtimeNodeInfoKind: NodeInfo.Kind, property: Found,
+ def compileDelimiter(
+ qn: NamedQName,
+ staticNodeInfoKind: NodeInfo.Kind,
+ runtimeNodeInfoKind: NodeInfo.Kind,
+ property: Found,
host: OOLAGHost): CompiledExpression[T] = {
+
val isEvaluatedAbove = false
- val expr = property.value
+ val exprOrLiteral = property.value
val namespacesForNamespaceResolution = property.location.namespaces
val compileInfoWherePropertyWasLocated = propertyCompileInfo(property)
- val (exprForCompiling, isRealExpression) = exprOrLiteral(expr,
staticNodeInfoKind, compileInfoWherePropertyWasLocated)
- val compiled1 = compileExpression1(qn, staticNodeInfoKind,
exprForCompiling, namespacesForNamespaceResolution,
compileInfoWherePropertyWasLocated, isEvaluatedAbove, host,
- isRealExpression)
- if (compiled1.isConstant) return compiled1
- if (staticNodeInfoKind == runtimeNodeInfoKind) return compiled1
- //
- // TODO: consider passing in a flag or some other way of avoiding this
- // duplicate compile run.
-
- // This is, this nodeInfo.Kind is used as the target type in the DPath
expression compiler, and
- //
- val compiled2 = compileExpression1(qn, runtimeNodeInfoKind,
exprForCompiling, namespacesForNamespaceResolution,
compileInfoWherePropertyWasLocated,
- isEvaluatedAbove, host, isRealExpression)
- compiled2
+ val compiled1 = compileExpression(
+ qn,
+ staticNodeInfoKind,
+ exprOrLiteral,
+ namespacesForNamespaceResolution,
+ compileInfoWherePropertyWasLocated,
+ isEvaluatedAbove,
+ host)
+
+ if (compiled1.isConstant || (staticNodeInfoKind == runtimeNodeInfoKind)) {
+ compiled1
+ } else {
+ val compiled2 = compileExpression(
+ qn,
+ runtimeNodeInfoKind,
+ exprOrLiteral,
+ namespacesForNamespaceResolution,
+ compileInfoWherePropertyWasLocated,
+ isEvaluatedAbove,
+ host)
+ compiled2
+ }
}
/**
@@ -131,86 +183,69 @@ class ExpressionCompiler[T <: AnyRef] extends
ExpressionCompilerBase[T] {
compileInfoWherePropertyWasLocated
}
- /**
- * Returns expression and flag as to whether it must be compiled.
- *
- * If the 2nd return value, 'isRealExpression' is true then we need to
compile
- * the expression, and the expression *will* have curly braces around it.
- * If the 2nd return value is false, then the expression is a string literal
- * being evaluated for a string, so we can directly construct a constant
- * expression object.
- */
- private def exprOrLiteral(exprWithBracesMaybe: String, nodeInfoKind:
NodeInfo.Kind, compileInfoWherePropertyWasLocated: DPathCompileInfo) = {
- var compile: Boolean = true
- val expr = exprWithBracesMaybe
- //
- // we want to standardize that the expression has braces
- //
- val exprForCompiling =
- if (DPathUtil.isExpression(expr)) expr.trim
- else {
- // not an expression. For some properties like delimiters, you can use
a literal string
- // whitespace separated list of literal strings, or an expression in {
.... }
- if (expr.startsWith("{") && !expr.startsWith("{{")) {
- val msg = "'%s' is an unterminated expression. Add missing closing
brace, or escape opening brace with another opening brace."
- compileInfoWherePropertyWasLocated.SDE(msg, expr)
- }
- val expr1 = if (expr.startsWith("{{"))
- expr.tail // everything except the self-escaped leading brace
- else expr
- //
- // Literal String: if the target type is String, do not compile.
- //
- nodeInfoKind match {
- case _: NodeInfo.String.Kind => compile = false // Constant String
- case _ => compile = true
- }
- expr1
- }
+ private def compileRealExpression(
+ qn: NamedQName,
+ nodeInfoKind: NodeInfo.Kind,
+ exprOrLiteral: String,
+ namespaces: NamespaceBinding,
+ compileInfoWherePropertyWasLocated: DPathCompileInfo,
+ isEvaluatedAbove: Boolean,
+ host: OOLAGHost): CompiledExpression[T] = {
+
+ // Treat this as an expression--validate and compile it
- // If we get here then now it's something we can compile. It might be
trivial
- // to compile (e.g, '5' compiles to Literal(5)) but we no longer uniformly
- // compile everything. As a performance optimization (DFDL-1775),
- // we will NOT compile constant strings (constant values whose target type
- // is String).
-
- /* Question: If something starts with {{, e.g.
- * separator="{{ not an expression", then we strip off the first brace,
- * wrap in quotes, and compile it? Why try compiling it? Shouldn't we just
- * return a constant expression or something at this point?
- * <p>
- * Answer: Conversions. E.g., if you have "{{ 6.847 }" as the expression
- * for an inputValueCalc on an element of float type, then the compiler
- * can tell you this isn't going to convert - you get a type check error or
- * maybe a number format exception at constant-folding time, which tells us
- * that the expression - even though it's a constant, isn't right.
- *
- * If we try to do this outside the expression compiler we'd be replicating
- * some of this type-infer/check logic.
- */
- (exprForCompiling, compile)
+ val expr = exprOrLiteral.trim
+ if (!expr.endsWith("}")) {
+ val msg = "'%s' is an unterminated expression. Add missing closing
brace, or escape opening brace with another opening brace."
+ compileInfoWherePropertyWasLocated.SDE(msg, exprOrLiteral)
+ }
+
+ val compiler = new DFDLPathExpressionParser[T](
+ qn,
+ nodeInfoKind,
+ namespaces,
+ compileInfoWherePropertyWasLocated,
+ isEvaluatedAbove,
+ host)
+ val compiledDPath = compiler.compile(expr)
+ compiledDPath
}
- /**
- * Compile the expression or construct a constant expression from it.
- */
- private def compileExpression1(qn: NamedQName, nodeInfoKind: NodeInfo.Kind,
exprForCompiling: String, namespaces: NamespaceBinding,
+ private def convertLiteralToConstant(
+ qn: NamedQName,
+ nodeInfoKind: NodeInfo.Kind,
+ exprOrLiteral: String,
+ namespaces: NamespaceBinding,
compileInfoWherePropertyWasLocated: DPathCompileInfo,
- isEvaluatedAbove: Boolean, host: OOLAGHost, isRealExpression: Boolean):
CompiledExpression[T] = {
- val res = if (isRealExpression) {
- // This is important. The namespace bindings we use must be
- // those from the object where the property carrying the expression
- // was written, not those of the edecl object where the property
- // value is being used/compiled. JIRA DFDL-407
- //
- val compiler = new DFDLPathExpressionParser[T](qn,
- nodeInfoKind, namespaces, compileInfoWherePropertyWasLocated,
isEvaluatedAbove, host)
- val compiledDPath = compiler.compile(exprForCompiling)
- compiledDPath
- } else {
- // Don't compile, meaning this is a constant string
- new ConstantExpression[T](qn, nodeInfoKind,
exprForCompiling.asInstanceOf[T])
+ isEvaluatedAbove: Boolean,
+ host: OOLAGHost): CompiledExpression[T] = {
+
+ // This string is not a real expression, we need to convert it to it's
+ // logical type and set it as a constant expression. Not compilation
+ // required. If something is passed in that does not convert to the
+ // expected type it will result in error.
+
+ // must be able to convert this to a primitive type
+ val maybePrimType = PrimType.fromNodeInfo(nodeInfoKind)
+ if (maybePrimType.isEmpty) {
+ val msg = "No known primitive type to convert logical value to: %s"
+ compileInfoWherePropertyWasLocated.SDE(msg, nodeInfoKind)
}
- res
+
+ // remove the leading escape curly brace if it exists
+ val literal =
+ if (exprOrLiteral.startsWith("{{")) exprOrLiteral.tail
+ else exprOrLiteral
+
+ val logical = try {
+ maybePrimType.get.fromXMLString(literal)
+ } catch {
+ case e: Exception => {
+ val msg = "Unable to convert logical value \"%s\" to %s: %s"
+ compileInfoWherePropertyWasLocated.SDE(msg, exprOrLiteral,
nodeInfoKind, e.getMessage)
+ }
+ }
+
+ new ConstantExpression[T](qn, nodeInfoKind, logical.asInstanceOf[T])
}
}
diff --git
a/daffodil-core/src/test/scala/org/apache/daffodil/dpath/TestDFDLExpressionTree.scala
b/daffodil-core/src/test/scala/org/apache/daffodil/dpath/TestDFDLExpressionTree.scala
index 310b149e2..35089a521 100644
---
a/daffodil-core/src/test/scala/org/apache/daffodil/dpath/TestDFDLExpressionTree.scala
+++
b/daffodil-core/src/test/scala/org/apache/daffodil/dpath/TestDFDLExpressionTree.scala
@@ -255,7 +255,7 @@ class TestDFDLExpressionTree extends Parsers {
}
@Test def test_numbers1() = {
- testExpr(dummySchema, "0.") { actual: Expression =>
+ testExpr(dummySchema, "{ 0. }") { actual: Expression =>
val res = BigDecimal("0.0")
val a @ WholeExpression(_, LiteralExpression(actualRes), _, _, _) =
actual; assertNotNull(a)
val bd = BigDecimal(actualRes.asInstanceOf[JBigDecimal])
@@ -265,32 +265,32 @@ class TestDFDLExpressionTree extends Parsers {
@Test def test_numbers() = {
- testExpr(dummySchema, "5.0E2") { case WholeExpression(_,
LiteralExpression(500.0), _, _, _) => /* ok */ ; }
- testExpr(dummySchema, "5E2") { case WholeExpression(_,
LiteralExpression(500.0), _, _, _) => /* ok */ ; }
- testExpr(dummySchema, ".2E2") { case WholeExpression(_,
LiteralExpression(20.0), _, _, _) => /* ok */ ; }
- testExpr(dummySchema, ".2E-3") { case WholeExpression(_,
LiteralExpression(0.0002), _, _, _) => /* ok */ ; }
- testExpr(dummySchema, ".2E+3") { case WholeExpression(_,
LiteralExpression(200.0), _, _, _) => /* ok */ ; }
+ testExpr(dummySchema, "{ 5.0E2 }") { case WholeExpression(_,
LiteralExpression(500.0), _, _, _) => /* ok */ ; }
+ testExpr(dummySchema, "{ 5E2 }") { case WholeExpression(_,
LiteralExpression(500.0), _, _, _) => /* ok */ ; }
+ testExpr(dummySchema, "{ .2E2 }") { case WholeExpression(_,
LiteralExpression(20.0), _, _, _) => /* ok */ ; }
+ testExpr(dummySchema, "{ .2E-3 }") { case WholeExpression(_,
LiteralExpression(0.0002), _, _, _) => /* ok */ ; }
+ testExpr(dummySchema, "{ .2E+3 }") { case WholeExpression(_,
LiteralExpression(200.0), _, _, _) => /* ok */ ; }
// testExpr(dummySchema, "0.") { actual =>
// val res = new JBigDecimal("0.0")
// val a @ WholeExpression(_, LiteralExpression(`res`), _, _, _) =
actual; assertNotNull(a)
// }
- testExpr(dummySchema, ".1") { actual =>
+ testExpr(dummySchema, "{ .1 }") { actual =>
val res = new JBigDecimal("0.1")
val a @ WholeExpression(_, LiteralExpression(`res`), _, _, _) = actual;
assertNotNull(a)
}
- testExpr(dummySchema,
"982304892038409234982304892038409234.0909808908982304892038409234") { actual =>
+ testExpr(dummySchema, "{
982304892038409234982304892038409234.0909808908982304892038409234 }") { actual
=>
val res = new
JBigDecimal("982304892038409234982304892038409234.0909808908982304892038409234")
val WholeExpression(_, LiteralExpression(r: JBigDecimal), _, _, _) =
actual
assertEquals(res, r)
}
- testExpr(dummySchema, "0") { actual =>
+ testExpr(dummySchema, "{ 0 }") { actual =>
val res = scala.math.BigInt(0)
val a @ WholeExpression(_, LiteralExpression(actualRes: JBigInt), _, _,
_) = actual; assertNotNull(a)
assertEquals(res, BigInt(actualRes))
}
- testExpr(dummySchema,
"9817239872193792873982173948739879128370982398723897921370") { actual =>
+ testExpr(dummySchema, "{
9817239872193792873982173948739879128370982398723897921370 }") { actual =>
val res =
scala.math.BigInt("9817239872193792873982173948739879128370982398723897921370")
val a @ WholeExpression(_, LiteralExpression(actualRes: JBigInt), _, _,
_) = actual; assertNotNull(a)
assertEquals(res, BigInt(actualRes))
@@ -305,8 +305,8 @@ class TestDFDLExpressionTree extends Parsers {
case WholeExpression(_, LiteralExpression(expr), _, _, _) => /* ok */
}
}
- testStringLit("'abc'")
- testStringLit("\"def\"")
+ testStringLit("{ 'abc' }")
+ testStringLit("{ \"def\" }")
}
@Test def test_funCall1() = {
@@ -328,8 +328,8 @@ class TestDFDLExpressionTree extends Parsers {
}
}
- testFn("fn:true()") { actual => assertEquals("true",
actual.functionQName.local) }
- testFn("fn:concat('a', 'b')") { actual => assertEquals("concat",
actual.functionQName.local) }
+ testFn("{ fn:true() }") { actual => assertEquals("true",
actual.functionQName.local) }
+ testFn("{ fn:concat('a', 'b') }") { actual => assertEquals("concat",
actual.functionQName.local) }
}
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 a38a2aaa9..a89eab64c 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
@@ -784,9 +784,12 @@ class InteractiveDebugger(runner:
InteractiveDebuggerRunner, eCompilers: Express
def act(args: Seq[String], prestate: StateForDebugger, state:
ParseOrUnparseState, processor: Processor): DebugState.Type = {
val id = args.head.toInt
val expression = args.tail.mkString(" ")
+ val expressionWithBraces =
+ if (!DPathUtil.isExpression(expression)) "{ " + expression + " }"
+ else expression
val b = DebuggerConfig.breakpoints.find(_.id == id).get
- b.condition = Some(expression)
- debugPrintln("%s: %s %s".format(b.id, b.breakpoint, expression))
+ b.condition = Some(expressionWithBraces)
+ debugPrintln("%s: %s %s".format(b.id, b.breakpoint,
expressionWithBraces))
DebugState.Pause
}
}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathUtil.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathUtil.scala
index 3b007c65a..2cd9028c5 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathUtil.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/DPathUtil.scala
@@ -21,23 +21,14 @@ package org.apache.daffodil.dpath
object DPathUtil {
/**
- * Whether a string is a DFDL expression (an XPath expression surrounded by
brackets).
- *
- * This function does not verify a string conforms to the DFDL subset of
XPath
+ * Whether a string is a DFDL expression. The definition of a DFDL expression
+ * is a string that starts with an unescaped curly brace. If this is true,
+ * then we want to consider this an expression and likely try to compile it
+ * later and check for validity.
*/
def isExpression(expression: String): Boolean = {
val trimmed = expression.trim
- trimmed.startsWith("{") && trimmed.endsWith("}") &&
- (trimmed(1) != '{')
- }
- /**
- * Returns the XPath expression contained in a DFDL expression (an XPath
expression surrounded by brackets).
- *
- * @param expression a valid DFDL expression
- */
- def getExpression(expression: String): String = {
- val v = expression.trim
- v.substring(1, v.length - 1)
+ trimmed.startsWith("{") && !trimmed.startsWith("{{")
}
}
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
index 9eb4c74b6..047f9bae2 100644
--- a/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
+++ b/daffodil-runtime1/src/main/scala/org/apache/daffodil/dpath/NodeInfo.scala
@@ -400,8 +400,11 @@ object NodeInfo extends Enum {
}
def fromNameString(name: String): Option[PrimType] = {
- val m: Option[PrimType] = allPrims.find { _.pname.toLowerCase ==
name.toLowerCase }
- m
+ allPrims.find { _.pname.toLowerCase == name.toLowerCase }
+ }
+
+ def fromNodeInfo(nodeInfo: NodeInfo.Kind): Option[PrimType] = {
+ allPrims.find { nodeInfo.isSubtypeOf(_) }
}
protected sealed trait FloatKind extends SignedNumeric.Kind
diff --git
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
index 71c8e96d3..a7465f2d8 100644
---
a/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
+++
b/daffodil-test/src/test/resources/org/apache/daffodil/section07/variables/variables.tdml
@@ -1061,4 +1061,67 @@
</tdml:errors>
</tdml:parserTestCase>
+
+ <tdml:defineSchema name="logical_default_values">
+
+ <xs:include
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" />
+
+ <dfdl:defineVariable name="float" type="xs:float" defaultValue="-INF" />
+ <dfdl:defineVariable name="double" type="xs:double" defaultValue="1.0e-5"
/>
+ <dfdl:defineVariable name="bool" type="xs:boolean" defaultValue="false" />
+ <dfdl:defineVariable name="string" type="xs:string" defaultValue="str" />
+ <dfdl:defineVariable name="date" type="xs:date" defaultValue="1999-12-31"
/>
+
+ <xs:element name="root">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="float" type="xs:float" dfdl:inputValueCalc="{
$float }" />
+ <xs:element name="double" type="xs:double" dfdl:inputValueCalc="{
$double + 2.0 }" />
+ <xs:element name="bool" type="xs:boolean" dfdl:inputValueCalc="{
$bool }" />
+ <xs:element name="string" type="xs:string" dfdl:inputValueCalc="{
$string }" />
+ <xs:element name="date" type="xs:date" dfdl:inputValueCalc="{ $date
}" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+
+ </tdml:defineSchema>
+
+ <tdml:parserTestCase name="logical_default_values" root="root"
+ model="logical_default_values" description="Section 7 - ">
+ <tdml:document/>
+
+ <tdml:infoset>
+ <tdml:dfdlInfoset>
+ <root xmlns="http://example.com">
+ <float>-INF</float>
+ <double>2.00001</double>
+ <bool>false</bool>
+ <string>str</string>
+ <date>1999-12-31</date>
+ </root>
+ </tdml:dfdlInfoset>
+ </tdml:infoset>
+ </tdml:parserTestCase>
+
+
+ <tdml:defineSchema name="logical_default_values_err">
+ <xs:include
schemaLocation="org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>
+ <dfdl:format ref="ex:GeneralFormat" />
+
+ <dfdl:defineVariable name="float" type="xs:float" defaultValue="float" />
+ <xs:element name="float" type="xs:float" dfdl:inputValueCalc="{ $float }"
/>
+
+ </tdml:defineSchema>
+
+ <tdml:parserTestCase name="logical_default_values_err" root="float"
+ model="logical_default_values_err" description="Section 7 - ">
+ <tdml:document/>
+ <tdml:errors>
+ <tdml:error>Schema Definition Error</tdml:error>
+ <tdml:error>Unable to convert logical value</tdml:error>
+ <tdml:error>float</tdml:error>
+ </tdml:errors>
+ </tdml:parserTestCase>
+
</tdml:testSuite>
diff --git
a/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
b/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
index fe6cabac4..bc3fd0ca3 100644
---
a/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
+++
b/daffodil-test/src/test/scala/org/apache/daffodil/section07/variables/TestVariables.scala
@@ -74,6 +74,9 @@ class TestVariables {
@Test def test_var_end_path() { runner.runOneTest("var_end_path") }
@Test def test_var_in_path() { runner.runOneTest("var_in_path") }
+ @Test def test_logical_default_values() {
runner.runOneTest("logical_default_values") }
+ @Test def test_logical_default_values_err() {
runner.runOneTest("logical_default_values_err") }
+
@Test def test_doubleSetErr_d() { runner_01.runOneTest("doubleSetErr_d") }
@Test def test_setVar1_d() { runner_01.runOneTest("setVar1_d") }
// DFDL-1443 & DFDL-1448
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services