public QilInvokeEarlyBound XsltInvokeEarlyBound(QilNode name, QilNode clrMethod, QilNode arguments, XmlQueryType xmlType) { QilInvokeEarlyBound n = new QilInvokeEarlyBound(QilNodeType.XsltInvokeEarlyBound, name, clrMethod, arguments, xmlType); n.XmlType = this.typeCheck.CheckXsltInvokeEarlyBound(n); TraceNode(n); return(n); }
public XmlQueryType CheckXsltInvokeEarlyBound(QilInvokeEarlyBound node) { #if DEBUG CheckLiteralValue(node[0], typeof(QilName)); CheckLiteralValue(node[1], typeof(MethodInfo)); CheckClassAndNodeType(node[2], typeof(QilList), QilNodeType.ActualParameterList); XmlExtensionFunction extFunc = new XmlExtensionFunction(node.Name.LocalName, node.Name.NamespaceUri, node.ClrMethod); QilList actualArgs = node.Arguments; Check(actualArgs.Count == extFunc.Method.GetParameters().Length, actualArgs, "InvokeEarlyBound argument count must match function's argument count"); for (int i = 0; i < actualArgs.Count; i++) { Check(actualArgs[i].XmlType.IsSubtypeOf(extFunc.GetXmlArgumentType(i)), actualArgs[i], "InvokeEarlyBound argument must be a subtype of the invoked function's argument type"); } #endif return(node.XmlType); }
protected virtual QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound n) { return(VisitChildren(n)); }
public XmlQueryType CheckXsltInvokeEarlyBound(QilInvokeEarlyBound node) { #if DEBUG CheckLiteralValue(node[0], typeof(QilName)); CheckLiteralValue(node[1], typeof(MethodInfo)); CheckClassAndNodeType(node[2], typeof(QilList), QilNodeType.ActualParameterList); XmlExtensionFunction extFunc = new XmlExtensionFunction(node.Name.LocalName, node.Name.NamespaceUri, node.ClrMethod); QilList actualArgs = node.Arguments; Check(actualArgs.Count == extFunc.Method.GetParameters().Length, actualArgs, "InvokeEarlyBound argument count must match function's argument count"); for (int i = 0; i < actualArgs.Count; i++) { Check(actualArgs[i].XmlType.IsSubtypeOf(extFunc.GetXmlArgumentType(i)), actualArgs[i], "InvokeEarlyBound argument must be a subtype of the invoked function's argument type"); } #endif return node.XmlType; }
protected virtual QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound n) { return VisitChildren(n); }
protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound n) { return NoReplace(n); }
protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound n) { return(NoReplace(n)); }
public QilInvokeEarlyBound XsltInvokeEarlyBound(QilNode name, QilNode clrMethod, QilNode arguments, XmlQueryType xmlType) { QilInvokeEarlyBound n = new QilInvokeEarlyBound(QilNodeType.XsltInvokeEarlyBound, name, clrMethod, arguments, xmlType); n.XmlType = this.typeCheck.CheckXsltInvokeEarlyBound(n); TraceNode(n); return n; }
/// <summary> /// Generate code for for QilNodeType.XsltInvokeEarlyBound. /// </summary> protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvoke) { QilName ndName = ndInvoke.Name; XmlExtensionFunction extFunc; Type clrTypeRetSrc, clrTypeRetDst; // Retrieve metadata from the extension function extFunc = new XmlExtensionFunction(ndName.LocalName, ndName.NamespaceUri, ndInvoke.ClrMethod); clrTypeRetSrc = extFunc.ClrReturnType; clrTypeRetDst = GetStorageType(ndInvoke); // Prepare to call runtime.ChangeTypeXsltResult if (clrTypeRetSrc != clrTypeRetDst && !ndInvoke.XmlType.IsEmpty) { _helper.LoadQueryRuntime(); _helper.LoadInteger(_helper.StaticData.DeclareXmlType(ndInvoke.XmlType)); } // If this is not a static method, then get the instance object if (!extFunc.Method.IsStatic) { // Special-case the XsltLibrary object if (ndName.NamespaceUri.Length == 0) _helper.LoadXsltLibrary(); else _helper.CallGetEarlyBoundObject(_helper.StaticData.DeclareEarlyBound(ndName.NamespaceUri, extFunc.Method.DeclaringType), extFunc.Method.DeclaringType); } // Generate code to push each Invoke argument onto the stack for (int iArg = 0; iArg < ndInvoke.Arguments.Count; iArg++) { QilNode ndActualArg; XmlQueryType xmlTypeFormalArg; Type clrTypeActualArg, clrTypeFormalArg; ndActualArg = ndInvoke.Arguments[iArg]; // Infer Xml type and Clr type of formal argument xmlTypeFormalArg = extFunc.GetXmlArgumentType(iArg); clrTypeFormalArg = extFunc.GetClrArgumentType(iArg); Debug.Assert(ndActualArg.XmlType.IsSubtypeOf(xmlTypeFormalArg), "Xml type of actual arg must be a subtype of the Xml type of the formal arg"); // Use different conversion rules for internal Xslt libraries. If the actual argument is // stored using Clr type T, then library must use type T, XPathItem, IList<T>, or IList<XPathItem>. // If the actual argument is stored using Clr type IList<T>, then library must use type // IList<T> or IList<XPathItem>. This is to ensure that there will not be unnecessary // conversions that take place when calling into an internal library. if (ndName.NamespaceUri.Length == 0) { Type itemType = GetItemStorageType(ndActualArg); if (clrTypeFormalArg == XmlILMethods.StorageMethods[itemType].IListType) { // Formal type is IList<T> NestedVisitEnsureStack(ndActualArg, itemType, true); } else if (clrTypeFormalArg == XmlILMethods.StorageMethods[typeof(XPathItem)].IListType) { // Formal type is IList<XPathItem> NestedVisitEnsureStack(ndActualArg, typeof(XPathItem), true); } else if ((ndActualArg.XmlType.IsSingleton && clrTypeFormalArg == itemType) || ndActualArg.XmlType.TypeCode == XmlTypeCode.None) { // Formal type is T NestedVisitEnsureStack(ndActualArg, clrTypeFormalArg, false); } else if (ndActualArg.XmlType.IsSingleton && clrTypeFormalArg == typeof(XPathItem)) { // Formal type is XPathItem NestedVisitEnsureStack(ndActualArg, typeof(XPathItem), false); } else Debug.Fail("Internal Xslt library may not use parameters of type " + clrTypeFormalArg); } else { // There is an implicit upcast to the Xml type of the formal argument. This can change the Clr storage type. clrTypeActualArg = GetStorageType(xmlTypeFormalArg); // If the formal Clr type is typeof(object) or if it is not a supertype of the actual Clr type, then call ChangeTypeXsltArgument if (xmlTypeFormalArg.TypeCode == XmlTypeCode.Item || !clrTypeFormalArg.IsAssignableFrom(clrTypeActualArg)) { // (clrTypeFormalArg) runtime.ChangeTypeXsltArgument(xmlTypeFormalArg, (object) value, clrTypeFormalArg); _helper.LoadQueryRuntime(); _helper.LoadInteger(_helper.StaticData.DeclareXmlType(xmlTypeFormalArg)); NestedVisitEnsureStack(ndActualArg, GetItemStorageType(xmlTypeFormalArg), !xmlTypeFormalArg.IsSingleton); _helper.TreatAs(clrTypeActualArg, typeof(object)); _helper.LoadType(clrTypeFormalArg); _helper.Call(XmlILMethods.ChangeTypeXsltArg); _helper.TreatAs(typeof(object), clrTypeFormalArg); } else { NestedVisitEnsureStack(ndActualArg, GetItemStorageType(xmlTypeFormalArg), !xmlTypeFormalArg.IsSingleton); } } } // Invoke the target method _helper.Call(extFunc.Method); // Return value is on the stack; convert it to canonical ILGen storage type if (ndInvoke.XmlType.IsEmpty) { _helper.Emit(OpCodes.Ldsfld, XmlILMethods.StorageMethods[typeof(XPathItem)].SeqEmpty); } else if (clrTypeRetSrc != clrTypeRetDst) { // (T) runtime.ChangeTypeXsltResult(idxType, (object) value); _helper.TreatAs(clrTypeRetSrc, typeof(object)); _helper.Call(XmlILMethods.ChangeTypeXsltResult); _helper.TreatAs(typeof(object), clrTypeRetDst); } else if (ndName.NamespaceUri.Length != 0 && !clrTypeRetSrc.GetTypeInfo().IsValueType) { // Check for null if a user-defined extension function returns a reference type Label lblSkip = _helper.DefineLabel(); _helper.Emit(OpCodes.Dup); _helper.Emit(OpCodes.Brtrue, lblSkip); _helper.LoadQueryRuntime(); _helper.Emit(OpCodes.Ldstr, SR.Xslt_ItemNull); _helper.Call(XmlILMethods.ThrowException); _helper.MarkLabel(lblSkip); } _iterCurr.Storage = StorageDescriptor.Stack(GetItemStorageType(ndInvoke), !ndInvoke.XmlType.IsSingleton); return ndInvoke; }