/// <summary> /// Serialize literal QName as three separate attributes. /// </summary> protected override QilNode VisitLiteralQName(QilName value) { this.writer.WriteAttributeString("name", value.ToString()); return(value); }
private QilNode AddDebugVariable(QilName name, QilNode value, QilNode content) { QilIterator var = _f.Let(value); var.DebugName = name.ToString(); return _f.Loop(var, content); }
private QilParameter CreateXslParam(QilName name, XmlQueryType xt) { QilParameter arg = _f.Parameter(xt); arg.DebugName = name.ToString(); arg.Name = name; return arg; }
private void EndElement() { MethodInfo facMethod = null; object[] facArgs; QilList list; QilNode nd; ReaderAnnotation ann; list = this.stk.Pop(); ann = (ReaderAnnotation)list.Annotation; // Special case certain element names string s = r.LocalName; switch (r.LocalName) { case "QilExpression": { Debug.Assert(list.Count > 0, "QilExpression node requires a Root expression"); QilExpression qil = f.QilExpression(list[list.Count - 1]); // Be flexible on order and presence of QilExpression children for (int i = 0; i < list.Count - 1; i++) { switch (list[i].NodeType) { case QilNodeType.True: case QilNodeType.False: qil.IsDebug = list[i].NodeType == QilNodeType.True; break; case QilNodeType.FunctionList: qil.FunctionList = (QilList)list[i]; break; case QilNodeType.GlobalVariableList: qil.GlobalVariableList = (QilList)list[i]; break; case QilNodeType.GlobalParameterList: qil.GlobalParameterList = (QilList)list[i]; break; } } nd = qil; break; } case "ForwardDecls": this.inFwdDecls = false; return; case "Parameter": case "Let": case "For": case "Function": { string id = ann.Id; QilName name = ann.Name; Debug.Assert(id != null, r.LocalName + " must have an id attribute"); Debug.Assert(!this.inFwdDecls || ann.XmlType != null, "Forward decl for " + r.LocalName + " '" + id + "' must have an xmlType attribute"); // Create node (may be discarded later if it was already declared in forward declarations section) switch (r.LocalName) { case "Parameter": Debug.Assert(list.Count <= (this.inFwdDecls ? 0 : 1), "Parameter '" + id + "' must have 0 or 1 arguments"); Debug.Assert(ann.XmlType != null, "Parameter '" + id + "' must have an xmlType attribute"); if (this.inFwdDecls || list.Count == 0) { nd = f.Parameter(null, name, ann.XmlType); } else { nd = f.Parameter(list[0], name, ann.XmlType); } break; case "Let": Debug.Assert(list.Count == (this.inFwdDecls ? 0 : 1), "Let '" + id + "' must have 0 or 1 arguments"); if (this.inFwdDecls) { nd = f.Let(f.Unknown(ann.XmlType)); } else { nd = f.Let(list[0]); } break; case "For": Debug.Assert(list.Count == 1, "For '" + id + "' must have 1 argument"); nd = f.For(list[0]); break; default: Debug.Assert(list.Count == (this.inFwdDecls ? 2 : 3), "Function '" + id + "' must have 2 or 3 arguments"); if (this.inFwdDecls) { nd = f.Function(list[0], list[1], ann.XmlType); } else { nd = f.Function(list[0], list[1], list[2], ann.XmlType != null ? ann.XmlType : list[1].XmlType); } break; } // Set DebugName if (name != null) { ((QilReference)nd).DebugName = name.ToString(); } if (this.inFwdDecls) { Debug.Assert(!this.scope.ContainsKey(id), "Multiple nodes have id '" + id + "'"); this.fwdDecls[id] = nd; this.scope[id] = nd; } else { if (this.fwdDecls.ContainsKey(id)) { // Replace forward declaration Debug.Assert(r.LocalName == Enum.GetName(typeof(QilNodeType), nd.NodeType), "Id '" + id + "' is not not bound to a " + r.LocalName + " forward decl"); nd = this.fwdDecls[id]; this.fwdDecls.Remove(id); if (list.Count > 0) { nd[0] = list[0]; } if (list.Count > 1) { nd[1] = list[1]; } } else { // Put reference in scope Debug.Assert(!this.scope.ContainsKey(id), "Id '" + id + "' is already in scope"); this.scope[id] = nd; } } nd.Annotation = ann; break; } case "RefTo": { // Lookup reference string id = ann.Id; Debug.Assert(id != null, r.LocalName + " must have an id attribute"); Debug.Assert(this.scope.ContainsKey(id), "Id '" + id + "' is not in scope"); this.stk.Peek().Add(this.scope[id]); return; } case "Sequence": nd = f.Sequence(list); break; case "FunctionList": nd = f.FunctionList(list); break; case "GlobalVariableList": nd = f.GlobalVariableList(list); break; case "GlobalParameterList": nd = f.GlobalParameterList(list); break; case "ActualParameterList": nd = f.ActualParameterList(list); break; case "FormalParameterList": nd = f.FormalParameterList(list); break; case "SortKeyList": nd = f.SortKeyList(list); break; case "BranchList": nd = f.BranchList(list); break; case "XsltInvokeEarlyBound": { Debug.Assert(ann.ClrNamespace != null, "XsltInvokeEarlyBound must have a clrNamespace attribute"); Debug.Assert(list.Count == 2, "XsltInvokeEarlyBound must have exactly 2 arguments"); Debug.Assert(list.XmlType != null, "XsltInvokeEarlyBound must have an xmlType attribute"); MethodInfo mi = null; QilName name = (QilName)list[0]; foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { Type t = asm.GetType(ann.ClrNamespace); if (t != null) { mi = t.GetMethod(name.LocalName); break; } } Debug.Assert(mi != null, "Cannot find method " + ann.ClrNamespace + "." + name.ToString()); nd = f.XsltInvokeEarlyBound(name, f.LiteralObject(mi), list[1], ann.XmlType); break; } default: { // Find factory method which will be used to construct the Qil node Debug.Assert(nameToFactoryMethod.ContainsKey(r.LocalName), "Method " + r.LocalName + " could not be found on QilFactory"); facMethod = nameToFactoryMethod[r.LocalName]; Debug.Assert(facMethod.GetParameters().Length == list.Count, "NodeType " + r.LocalName + " does not allow " + list.Count + " parameters"); // Create factory method arguments facArgs = new object[list.Count]; for (int i = 0; i < facArgs.Length; i++) { facArgs[i] = list[i]; } // Create node and set its properties nd = (QilNode)facMethod.Invoke(f, facArgs); break; } } nd.SourceLine = list.SourceLine; // Add node to its parent's list this.stk.Peek().Add(nd); }