mbeckerle commented on a change in pull request #257: Daffodil 2165 type calc
double functions
URL: https://github.com/apache/incubator-daffodil/pull/257#discussion_r299618159
##########
File path:
daffodil-core/src/main/scala/org/apache/daffodil/dpath/Expression.scala
##########
@@ -1553,46 +1556,91 @@ case class FunctionCallExpression(functionQNameString:
String, expressions: List
//Begin DFDLX functions
//Begin TypeValueCalc related functions
- case (RefQName(_, "inputTypeCalcInt", DFDLX), args) =>
+ case (RefQName(_, "inputTypeCalc", DFDLX), args) => {
+ val typeCalc = lookupTypeCalculator(args(0), true, false)
FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
- NodeInfo.Int, NodeInfo.String, args(1).inherentType,
DFDLXInputTypeCalcInt(_))
-
- case (RefQName(_, "inputTypeCalcString", DFDLX), args) => {
- FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
- NodeInfo.String, NodeInfo.String, args(1).inherentType,
DFDLXInputTypeCalcString(_))
+ typeCalc.dstType, NodeInfo.String, typeCalc.srcType,
DFDLXInputTypeCalc(_, typeCalc))
}
- case (RefQName(_, "outputTypeCalcInt", DFDLX), args) =>
- FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
- NodeInfo.Int, NodeInfo.String, args(1).inherentType,
DFDLXOutputTypeCalcInt(_))
-
- case (RefQName(_, "outputTypeCalcString", DFDLX), args) =>
+ case (RefQName(_, "outputTypeCalc", DFDLX), args) => {
+ val typeCalc = lookupTypeCalculator(args(0), false, true)
FNTwoArgsExprInferedArgType(functionQNameString, functionQName, args,
- NodeInfo.String, NodeInfo.String, args(1).inherentType,
DFDLXOutputTypeCalcString(_))
-
- case (RefQName(_, "outputTypeCalcNextSiblingInt", DFDLX), args) =>
- FNZeroArgExpr(functionQNameString, functionQName,
- NodeInfo.Int, NodeInfo.AnyAtomic,
DFDLXOutputTypeCalcNextSiblingInt(_, _))
-
- case (RefQName(_, "outputTypeCalcNextSiblingString", DFDLX), args) =>
- FNZeroArgExpr(functionQNameString, functionQName,
- NodeInfo.String, NodeInfo.AnyAtomic,
DFDLXOutputTypeCalcNextSiblingString(_, _))
+ typeCalc.srcType, NodeInfo.String, typeCalc.dstType,
DFDLXOutputTypeCalc(_, typeCalc))
+ }
- case (RefQName(_, "repTypeValueInt", DFDLX), args) =>
+ case (RefQName(_, "outputTypeCalcNextSibling", DFDLX), args) => {
+ val erd = compileInfo.lexicalContextRuntimeData match{
+ case erd: ElementRuntimeData => erd
+ case _ => SDE("dfdlx:outputTypeCalcNextSibling can only be defined
on an element")
+ }
+ val resolver = erd.nextElementResolver
+ //we keep the ERD to be able to produce better error messages
+ val dstTypes:Seq[(NodeInfo.Kind, ElementRuntimeData)] =
resolver.allPossibleNextElements.map(erd => {
+ val strd = erd.optSimpleTypeRuntimeData match{
+ case Some(x) => x
+ case None => SDE("dfdlx:outputTypeCalcNextSibling: potential next
sibling %s does not have a simple type def. This could be because it has a
primitive type, or a complex type.", erd.namedQName)
+ }
+ val calc = strd.typeCalculator match{
+ case Some(x) => x
+ case None => SDE("dfdlx:outputTypeCalcNextSibling(): potential
next sibling %s does not define a type calculator", erd.namedQName)
+ }
+ if(!calc.supportsUnparse){
+ SDE("dfdlx:outputTypeCalcNextSibling(): potential next sibling %s
does not have an outputTypeCalc", erd.namedQName)
+ }
+ (calc.srcType, erd)
+ })
+ val dstType = dstTypes match{
+ case Seq() => SDE("dfdlx:outputTypeCalcNextSibling() called where no
next sibling exists")
+ case Seq(x) => x._1
+ case x +: xs => {
+ val (ans, headQName) = x
+ /*
+ * Verify that all next siblings have the same dstType
+ * In theory, we could loosen the requirement to having the same
primitive type,
+ * but in the interest of being conservative, we will stick to the
stricter interperatation for now
+ */
+ xs.map(other => {
+ val (otherAns, otherQName) = other
+ if(otherAns != ans){
+ SDE("dfdlx:outputTypeCalcNextSibling() requires that all the
possible next siblings have the same "+
+ "repType. However, the potential next siblings %s and %s
have repTypes %s and %s respectivly",
+ headQName, otherQName, ans, otherAns)
+ }
+ })
+ ans
+ }
+ }
FNZeroArgExpr(functionQNameString, functionQName,
- NodeInfo.Integer, NodeInfo.AnyAtomic, DFDLXRepTypeValueInt(_, _))
+ dstType, NodeInfo.AnyAtomic, DFDLXOutputTypeCalcNextSibling(_, _))
+ }
- case (RefQName(_, "repTypeValueString", DFDLX), args) =>
+ case (RefQName(_, "repTypeValue", DFDLX), args) => {
+ val strd = compileInfo.lexicalContextRuntimeData match {
+ case strd: SimpleTypeRuntimeData => strd
+ case _ => {
+ SDE("dfdlx:repTypeValue() can only be defined on a simple type")
+ }
+ }
+ val repPrimType = strd.optRepPrimType match{
+ case Some(x) => x
+ case None => SDE("dfdlx:repTypeValue() used on type that does not
have a repType")
Review comment:
Missing period at end of sentence.
----------------------------------------------------------------
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.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services