Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Within the DPath processing code, Daffodil will define 2 case classes, a UDFunctionCallExpr and a UDFunctionCall. The dResultType and dArgTypes arguments for UDFArgsListExpr will be inferred from the udFunctionClass the functionClass as shown above. The Expression functionObject will be set to the below.

Code Block
languagescala
UDFunctionCallExpr(functionQNameString, functionQName, args, dResultType, dArgTypes, UDFunctionCall(_, functionClassObject, udFunctionClass))

...

fEvaluate))


UDFunctionCallExpr will extend Daffodil's FunctionCallBase, and implement inherentType, targetTypeForSubexpression and compiledDPath. compiledDPath will call UDFunctionCall. UDFunctionCall will call fEvaluate using its invoke method.

Code Block
languagescala
case class UDFunctionCallExpr(nameAsParsed: String, fnQName: RefQName, args: List[Expression],
resultType: NodeInfo.Kind, argsTypes: List[NodeInfo.Kind], constructor: List[CompiledDPath] => RecipeOp)
	extends FunctionCallBase(nameAsParsed, fnQName, args) {

	lazy val argsToArgType = (args zip argsTypes).toMap
	override lazy val inherentType = resultType

	override def targetTypeForSubexpression(childExpr: Expression): NodeInfo.Kind = {
		argsToArgType.get(childExpr) match {
			case Some(argType) => argType
			case None => {
				Assert.invariantFailed("subexpression %s is not an argument.".format(subexp))
			}
		}
	}
	override lazy val compiledDPath = {
		val recipes = args.map { _.compiledDPath }
		val res = new CompiledDPath(constructor(recipes) +: conversions)
		res
	}
}

case class UDFunctionCall(recipes: List[CompiledDPath], functionClassObject: Object, udfEvaluate: Method)
	extends FNArgsList(recipes) {

	override def computeValues(values: List[Any], dstate: DState) = {
		val res = udfEvaluate.invoke(functionClassObject, values: _*) //might need to explicitly cast values to type Object before hand
		res
	}
}