/// <summary> /// Override the Visit method in order to scan for redundant namespaces and compute side-effect bit. /// </summary> protected override QilNode Visit(QilNode nd) { if (nd != null) { if (this[XmlILOptimization.EliminateNamespaceDecl]) { // Eliminate redundant namespaces in the tree. Don't perform the scan on an ElementCtor which // has already been marked as having a redundant namespace. switch (nd.NodeType) { case QilNodeType.QilExpression: // Perform namespace analysis on root expression (xmlns="" is in-scope for this expression) this.nmspAnalyzer.Analyze(((QilExpression) nd).Root, true); break; case QilNodeType.ElementCtor: if (!XmlILConstructInfo.Read(nd).IsNamespaceInScope) this.nmspAnalyzer.Analyze(nd, false); break; case QilNodeType.DocumentCtor: this.nmspAnalyzer.Analyze(nd, true); break; } } } // Continue visitation return base.Visit(nd); }
//----------------------------------------------- // Convenience methods //----------------------------------------------- public QilExpression QilExpression(QilNode root, QilFactory factory) { QilExpression n = new QilExpression(QilNodeType.QilExpression, root, factory); n.XmlType = _typeCheck.CheckQilExpression(n); TraceNode(n); return n; }
public QilNode InvokeElementAvailable(QilNode n) { CheckQName(n); return XsltInvokeEarlyBound(QName("element-available"), XsltMethods.ElementAvailable, T.BooleanX, new QilNode[] { n } ); }
public bool IsAnyType(QilNode n) { XmlQueryType xt = n.XmlType; bool result = !(xt.IsStrict || xt.IsNode); Debug.Assert(result == (xt.TypeCode == XmlTypeCode.Item || xt.TypeCode == XmlTypeCode.AnyAtomicType), "What else can it be?"); return result; }
/// <summary> /// Visit all children of "parent", replacing each child with a copy of each child. /// </summary> protected override QilNode VisitChildren(QilNode parent) { // Visit children for (int i = 0; i < parent.Count; i++) { QilNode child = parent[i]; // If child is a reference, if (IsReference(parent, i)) { // Visit the reference and substitute its copy parent[i] = VisitReference(child); // If no substutition found, then use original child if (parent[i] == null) parent[i] = child; } else { // Otherwise, visit the node and substitute its copy parent[i] = Visit(child); } } return parent; }
/// <summary> /// Visit all children of "parent". Take care to avoid circular visits. /// </summary> protected virtual bool IsReference(QilNode parent, int childNum) { QilNode child = parent[childNum]; if (child != null) { switch (child.NodeType) { case QilNodeType.For: case QilNodeType.Let: case QilNodeType.Parameter: // Is this a reference or a definition? switch (parent.NodeType) { case QilNodeType.Loop: case QilNodeType.Filter: case QilNodeType.Sort: // Second child of these node types is a reference; first child is a definition return childNum == 1; case QilNodeType.GlobalVariableList: case QilNodeType.GlobalParameterList: case QilNodeType.FormalParameterList: // All children of definition lists are definitions return false; } // All other cases are references return true; case QilNodeType.Function: // If parent is an Invoke node, then visit a reference to the function return parent.NodeType == QilNodeType.Invoke; } } return false; }
//----------------------------------------------- // QilVisitor methods (manually generated) //----------------------------------------------- /// <summary> /// If a reference is passed to the Visit() method, it is assumed to be the definition. /// This method assumes it is a reference to a definition. /// For example, if a Let node is visited, is it the Let definition or a reference to the /// the Let definition? Without context, it is ambiguous. This method allows a caller /// to disambiguate. /// </summary> protected virtual QilNode VisitAssumeReference(QilNode expr) { if (expr is QilReference) return VisitReference(expr); return Visit(expr); }
//----------------------------------------------- // QilVisitor overrides //----------------------------------------------- /// <summary> /// Visit all children of "parent", replacing each child with a copy of each child. /// </summary> protected override QilNode VisitChildren(QilNode parent) { XmlQueryType oldParentType = parent.XmlType; bool recalcType = false; // Visit children for (int i = 0; i < parent.Count; i++) { QilNode oldChild = parent[i], newChild; XmlQueryType oldChildType = oldChild != null ? oldChild.XmlType : null; // Visit child if (IsReference(parent, i)) newChild = VisitReference(oldChild); else newChild = Visit(oldChild); // Only replace child and recalculate type if oldChild != newChild or oldChild.XmlType != newChild.XmlType if ((object) oldChild != (object) newChild || (newChild != null && (object) oldChildType != (object) newChild.XmlType)) { recalcType = true; parent[i] = newChild; } } if (recalcType) RecalculateType(parent, oldParentType); return parent; }
//----------------------------------------------- // Constructor //----------------------------------------------- /// <summary> /// Construct a node /// </summary> public QilFunction(QilNodeType nodeType, QilNode arguments, QilNode definition, QilNode sideEffects, XmlQueryType resultType) : base(nodeType) { this.arguments = arguments; this.definition = definition; this.sideEffects = sideEffects; this.xmlType = resultType; }
/// <summary> /// Find the replacement for a node /// </summary> /// <param name="n">the node to replace</param> /// <returns>null if no replacement is found</returns> public QilNode FindReplacement(QilNode n) { Debug.Assert(s.Count % 2 == 0); for (int i = s.Count-2; i >= 0; i-=2) if (s[i] == n) return (QilNode)s[i+1]; return null; }
public QilNode InvokeIsSameNodeSort(QilNode n1, QilNode n2) { CheckNodeNotRtf(n1); CheckNodeNotRtf(n2); return XsltInvokeEarlyBound(QName("is-same-node-sort"), XsltMethods.IsSameNodeSort, T.BooleanX, new QilNode[] { n1, n2 } ); }
public QilNode InvokeSystemProperty(QilNode n) { CheckQName(n); return XsltInvokeEarlyBound(QName("system-property"), XsltMethods.SystemProperty, T.Choice(T.DoubleX, T.StringX), new QilNode[] { n } ); }
public QilNode ConvertReletive2Absolute(QilNode node, QilNode fixup) { QilDepthChecker.Check(node); Debug.Assert(node != null); Debug.Assert(fixup != null); this.fixup = fixup; return this.Visit(node); }
/// <summary> /// Called at the end of Visit(). /// </summary> protected virtual void AfterVisit(QilNode node) { QilExpression qil; switch (node.NodeType) { case QilNodeType.QilExpression: // Remove all global functions, variables, and parameters from scope qil = (QilExpression) node; foreach (QilNode func in qil.FunctionList) EndScope(func); foreach (QilNode var in qil.GlobalVariableList) EndScope(var); foreach (QilNode param in qil.GlobalParameterList) EndScope(param); break; case QilNodeType.Function: // Remove all formal arguments from scope foreach (QilNode arg in ((QilFunction) node).Arguments) EndScope(arg); break; case QilNodeType.Loop: case QilNodeType.Filter: case QilNodeType.Sort: // Remove loop iterator in scope EndScope(((QilLoop) node).Variable); break; } }
public QilNode Replace(QilNode expr, QilReference lookFor, QilReference replaceBy) { QilDepthChecker.Check(expr); _lookFor = lookFor; _replaceBy = replaceBy; return VisitAssumeReference(expr); }
public virtual QilNode EndBuild(QilNode result) { Debug.Assert(inTheBuild, "StartBuild() wasn't called"); if (result == null) { // Special door to clean builder state in exception handlers } inTheBuild = false; return result; }
public XPathPatternBuilder(IXPathEnvironment environment) { Debug.Assert(environment != null); this.environment = environment; this.f = environment.Factory; this.predicateEnvironment = new XPathPredicateEnvironment(environment); this.predicateBuilder = new XPathBuilder(predicateEnvironment); this.fixupNode = f.Unknown(T.NodeNotRtfS); }
/// <summary> /// Get OptimizerPatterns annotation for the specified node. Lazily create if necessary. /// </summary> public static OptimizerPatterns Read(QilNode nd) { XmlILAnnotation ann = nd.Annotation as XmlILAnnotation; OptimizerPatterns optPatt = (ann != null) ? ann.Patterns : null; if (optPatt == null) { if (!nd.XmlType.MaybeMany) { // Expressions with ZeroOrOne cardinality should always report IsDocOrderDistinct and NoContainedNodes if (s_zeroOrOneDefault == null) { optPatt = new OptimizerPatterns(); optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct); optPatt.AddPattern(OptimizerPatternName.SameDepth); optPatt._isReadOnly = true; s_zeroOrOneDefault = optPatt; } else { optPatt = s_zeroOrOneDefault; } } else if (nd.XmlType.IsDod) { if (s_dodDefault == null) { optPatt = new OptimizerPatterns(); optPatt.AddPattern(OptimizerPatternName.IsDocOrderDistinct); optPatt._isReadOnly = true; s_dodDefault = optPatt; } else { optPatt = s_dodDefault; } } else { if (s_maybeManyDefault == null) { optPatt = new OptimizerPatterns(); optPatt._isReadOnly = true; s_maybeManyDefault = optPatt; } else { optPatt = s_maybeManyDefault; } } } return optPatt; }
/// <summary> /// Recursively analyze the definition of a function. /// </summary> private static void AnalyzeDefinition(QilNode nd) { Debug.Assert(XmlILConstructInfo.Read(nd).PushToWriterLast, "Only need to analyze expressions which will be compiled in push mode."); switch (nd.NodeType) { case QilNodeType.Invoke: // Invoke node can either be compiled as IteratorThenWriter, or Writer. // Since IteratorThenWriter involves caching the results of the function call // and iterating over them, .tailcall cannot be used if (XmlILConstructInfo.Read(nd).ConstructMethod == XmlILConstructMethod.Writer) OptimizerPatterns.Write(nd).AddPattern(OptimizerPatternName.TailCall); break; case QilNodeType.Loop: { // Recursively analyze Loop return value QilLoop ndLoop = (QilLoop)nd; if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding.XmlType.MaybeMany) AnalyzeDefinition(ndLoop.Body); break; } case QilNodeType.Sequence: { // Recursively analyze last expression in Sequence QilList ndSeq = (QilList)nd; if (ndSeq.Count > 0) AnalyzeDefinition(ndSeq[ndSeq.Count - 1]); break; } case QilNodeType.Choice: { // Recursively analyze Choice branches QilChoice ndChoice = (QilChoice)nd; for (int i = 0; i < ndChoice.Branches.Count; i++) AnalyzeDefinition(ndChoice.Branches[i]); break; } case QilNodeType.Conditional: { // Recursively analyze Conditional branches QilTernary ndCond = (QilTernary)nd; AnalyzeDefinition(ndCond.Center); AnalyzeDefinition(ndCond.Right); break; } case QilNodeType.Nop: AnalyzeDefinition(((QilUnary)nd).Child); break; } }
// transparantly passing through Union and DocOrder protected override QilNode Visit(QilNode n) { if ( n.NodeType == QilNodeType.Union || n.NodeType == QilNodeType.DocOrderDistinct || n.NodeType == QilNodeType.Filter || n.NodeType == QilNodeType.Loop ) { return base.Visit(n); } return n; }
/// <summary> /// Visit all children of "parent". By default, take care to avoid circular visits. /// </summary> protected virtual QilNode VisitChildren(QilNode parent) { for (int i = 0; i < parent.Count; i++) { // If child is a reference, then call VisitReference instead of Visit in order to avoid circular visits. if (IsReference(parent, i)) VisitReference(parent[i]); else Visit(parent[i]); } return parent; }
public void Append(QilNode value) { Debug.Assert(inUse, "Reset() wasn't called"); if (value != null) { Debug.Assert(value.XmlType.TypeCode == XmlTypeCode.String); if (value.NodeType == QilNodeType.LiteralString) { builder.Append((string)(QilLiteral)value); } else { FlushBuilder(); concat.Add(value); } } }
//----------------------------------------------- // QilReplaceVisitor methods //----------------------------------------------- /// <summary> /// Once children have been replaced, the Xml type is recalculated. /// </summary> protected virtual void RecalculateType(QilNode node, XmlQueryType oldType) { XmlQueryType newType; newType = f.TypeChecker.Check(node); // Note the use of AtMost to account for cases when folding of Error nodes in the graph cause // cardinality to be recalculated. // For example, (Sequence (TextCtor (Error "error")) (Int32 1)) => (Sequence (Error "error") (Int32 1)) // In this case, cardinality has gone from More to One Debug.Assert(newType.IsSubtypeOf(XmlQueryTypeFactory.AtMost(oldType, oldType.Cardinality)), "Replace shouldn't relax original type"); node.XmlType = newType; }
public QilNode Operator(XPathOperator op, QilNode left, QilNode right) { Debug.Assert(op == XPathOperator.Union); Debug.Assert(left != null); Debug.Assert(right != null); // It is important to not create nested lists here Debug.Assert(right.NodeType == QilNodeType.Filter, "LocationPathPattern must be compiled into a filter"); if (left.NodeType == QilNodeType.Sequence) { ((QilList)left).Add(right); return left; } else { Debug.Assert(left.NodeType == QilNodeType.Filter, "LocationPathPattern must be compiled into a filter"); return f.Sequence(left, right); } }
/// <summary> /// Construct QIL from a rooted graph of QilNodes with a specific factory. /// </summary> public QilExpression(QilNodeType nodeType, QilNode root, QilFactory factory) : base(nodeType) { this.factory = factory; this.isDebug = factory.False(); XmlWriterSettings settings = new XmlWriterSettings(); settings.ConformanceLevel = ConformanceLevel.Auto; this.defWSet = factory.LiteralObject(settings); this.wsRules = factory.LiteralObject(new List<WhitespaceRule>()); this.funList = factory.FunctionList(); this.gloVars = factory.GlobalVariableList(); this.gloParams = factory.GlobalParameterList(); this.rootNod = root; }
/// <summary> /// Called when a pattern has matched, but before the replacement code is executed. If this /// method returns false, then the replacement code is skipped. /// </summary> protected virtual bool AllowReplace(int pattern, QilNode original) { // If still matching patterns, if (Matching) { // Increment the replacement count this.replacementCnt++; // Save the id of this pattern in case it's the last this.lastReplacement = pattern; return true; } return false; }
public override QilNode EndBuild(QilNode result) { depth --; Debug.Assert(0 <= depth && depth <= 1, "this shouldn't happen"); if (result == null) { // special door to clean builder state in exception handlers return base.EndBuild(result); } if (depth == 0) { Debug.Assert(base.numFixupLast == 0); Debug.Assert(base.numFixupPosition == 0); result = convertor.ConvertReletive2Absolute(result, base.fixupCurrent); result = base.EndBuild(result); } return result; }
//----------------------------------------------- // QilVisitor overrides //----------------------------------------------- protected override QilNode VisitChildren(QilNode parent) { if (this.parents.Contains(parent)) { // We have already visited the node that starts the infinite loop, but don't visit its children SetError(parent, "Infinite loop"); } else if (AddNode(parent)) { if (parent.XmlType == null) { SetError(parent, "Type information missing"); } else { XmlQueryType type = this.typeCheck.Check(parent); // if (!type.IsSubtypeOf(parent.XmlType)) SetError(parent, "Type information was not correctly inferred"); } this.parents.Add(parent, parent); for (int i = 0; i < parent.Count; i++) { if (parent[i] == null) { // Allow parameter name and default value to be null if (parent.NodeType == QilNodeType.Parameter) continue; // Do not allow null anywhere else in the graph else SetError(parent, "Child " + i + " must not be null"); } if (parent.NodeType == QilNodeType.GlobalVariableList || parent.NodeType == QilNodeType.GlobalParameterList || parent.NodeType == QilNodeType.FunctionList) { if (((QilReference) parent[i]).DebugName == null) SetError(parent[i], "DebugName must not be null"); } // If child is a reference, then call VisitReference instead of Visit in order to avoid circular visits. if (IsReference(parent, i)) VisitReference(parent[i]); else Visit(parent[i]); } this.parents.Remove(parent); } return parent; }
/// <summary> /// Construct QIL from a rooted graph of QilNodes with a specific factory. /// </summary> public QilExpression(QilNodeType nodeType, QilNode root, QilFactory factory) : base(nodeType) { _factory = factory; _isDebug = factory.False(); XmlWriterSettings settings = new XmlWriterSettings(); settings.ConformanceLevel = ConformanceLevel.Auto; _defWSet = factory.LiteralObject(settings); _wsRules = factory.LiteralObject(new List<WhitespaceRule>()); _gloVars = factory.GlobalVariableList(); _gloParams = factory.GlobalParameterList(); _earlBnd = factory.LiteralObject(new List<EarlyBoundInfo>()); _funList = factory.FunctionList(); _rootNod = root; }
public override QilNode this[int index] { get { switch (index) { case 0: return this.left; case 1: return this.right; default: throw new IndexOutOfRangeException(); } } set { switch (index) { case 0: this.left = value; break; case 1: this.right = value; break; default: throw new IndexOutOfRangeException(); } } }
public void CheckNodeSet(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsNode, "Must be a node-set"); }
private void ExpectAny(QilNode n) { Debug.Assert(IsAnyType(n), "Unexpected expression type: " + n.XmlType !.ToString()); }
public QilNode InvokeNumberFormat(QilNode value, QilNode format, QilNode lang, QilNode letterValue, QilNode groupingSeparator, QilNode groupingSize) { Debug.Assert(value != null && ( value.XmlType !.IsSubtypeOf(T.IntXS) || value.XmlType.IsSubtypeOf(T.DoubleX)), "Value must be either a sequence of ints, or a double singleton" ); CheckString(format); CheckDouble(lang); CheckString(letterValue); CheckString(groupingSeparator); CheckDouble(groupingSize); return(XsltInvokeEarlyBound(QName("number-format"), XsltMethods.NumberFormat, T.StringX, new QilNode[] { value, format, lang, letterValue, groupingSeparator, groupingSize } )); }
public QilNode InvokeMsFormatDateTime(QilNode datetime, QilNode format, QilNode lang, QilNode isDate) { CheckString(datetime); CheckString(format); CheckString(lang); CheckBool(isDate); return(XsltInvokeEarlyBound(QName("ms:format-date-time"), XsltMethods.MSFormatDateTime, T.StringX, new QilNode[] { datetime, format, lang, isDate } )); }
public QilNode InvokeEXslObjectType(QilNode n) { return(XsltInvokeEarlyBound(QName("exsl:object-type"), XsltMethods.EXslObjectType, T.StringX, new QilNode[] { n } )); }
QilNode IXPathBuilder <QilNode> .Predicate(QilNode node, QilNode condition, bool isReverseStep) { Debug.Assert(false, "Should not call to this function."); return(null); }
private static QilLoop GetLastParent(QilNode node) { return(((Annotation)node.Annotation).Parent); }
private QilNode CompileFormatNumber(QilNode value, QilNode formatPicture, QilNode formatName) { _f.CheckDouble(value); _f.CheckString(formatPicture); XmlQualifiedName resolvedName; if (formatName == null) { resolvedName = new XmlQualifiedName(); // formatName must be non-null in the f.InvokeFormatNumberDynamic() call below formatName = _f.String(string.Empty); } else { _f.CheckString(formatName); if (formatName.NodeType == QilNodeType.LiteralString) { resolvedName = ResolveQNameThrow(/*ignoreDefaultNs:*/ true, formatName); } else { resolvedName = null; } } if (resolvedName != null) { DecimalFormatDecl format; if (_compiler.DecimalFormats.Contains(resolvedName)) { format = _compiler.DecimalFormats[resolvedName]; } else { if (resolvedName != DecimalFormatDecl.Default.Name) { throw new XslLoadException(SR.Xslt_NoDecimalFormat, (string)(QilLiteral)formatName); } format = DecimalFormatDecl.Default; } // If both formatPicture and formatName are literal strings, there is no need to reparse // formatPicture on every execution of this format-number(). Instead, we create a DecimalFormatter // object on the first execution, save its index into a global variable, and reuse that object // on all subsequent executions. if (formatPicture.NodeType == QilNodeType.LiteralString) { QilIterator fmtIdx = _f.Let(_f.InvokeRegisterDecimalFormatter(formatPicture, format)); fmtIdx.DebugName = _f.QName("formatter" + _formatterCnt++, XmlReservedNs.NsXslDebug).ToString(); _gloVars.Add(fmtIdx); return(_f.InvokeFormatNumberStatic(value, fmtIdx)); } _formatNumberDynamicUsed = true; QilNode name = _f.QName(resolvedName.Name, resolvedName.Namespace); return(_f.InvokeFormatNumberDynamic(value, formatPicture, name, formatName)); } else { _formatNumberDynamicUsed = true; QilIterator i = _f.Let(formatName); QilNode name = ResolveQNameDynamic(/*ignoreDefaultNs:*/ true, i); return(_f.Loop(i, _f.InvokeFormatNumberDynamic(value, formatPicture, name, i))); } }
/// <summary> /// Recursively analyze content. Return "nd" or a replacement for it. /// </summary> protected virtual QilNode AnalyzeContent(QilNode nd) { XmlILConstructInfo info; QilNode ndChild; // Handle special node-types that are replaced switch (nd.NodeType) { case QilNodeType.For: case QilNodeType.Let: case QilNodeType.Parameter: // Iterator references are shared and cannot be annotated directly with ConstructInfo, // so wrap them with Nop node. nd = this.fac.Nop(nd); break; } // Get node's ConstructInfo annotation info = XmlILConstructInfo.Write(nd); // Set node's guaranteed parent constructor info.ParentInfo = this.parentInfo; // Construct all content using the Writer info.PushToWriterLast = true; // Set states that are possible before expression is constructed info.InitialStates = this.xstates; switch (nd.NodeType) { case QilNodeType.Loop: AnalyzeLoop((nd as QilLoop) !, info); break; case QilNodeType.Sequence: AnalyzeSequence((nd as QilList) !, info); break; case QilNodeType.Conditional: AnalyzeConditional((nd as QilTernary) !, info); break; case QilNodeType.Choice: AnalyzeChoice((nd as QilChoice) !, info); break; case QilNodeType.Error: case QilNodeType.Warning: // Ensure that construct method is Writer info.ConstructMethod = XmlILConstructMethod.Writer; break; case QilNodeType.Nop: ndChild = (nd as QilUnary) !.Child; switch (ndChild.NodeType) { case QilNodeType.For: case QilNodeType.Let: case QilNodeType.Parameter: // Copy iterator items as content AnalyzeCopy(nd, info); break; default: // Ensure that construct method is Writer and recursively analyze content info.ConstructMethod = XmlILConstructMethod.Writer; AnalyzeContent(ndChild); break; } break; default: AnalyzeCopy(nd, info); break; } // Set states that are possible after expression is constructed info.FinalStates = this.xstates; return(nd); }
/// <summary> /// Recursively analyze content. Return "nd" or a replacement for it. /// </summary> private void AnalyzeContent(QilNode nd) { int cntNmspSave; switch (nd.NodeType) { case QilNodeType.Loop: _addInScopeNmsp = false; AnalyzeContent((nd as QilLoop) !.Body); break; case QilNodeType.Sequence: foreach (QilNode ndContent in nd) { AnalyzeContent(ndContent); } break; case QilNodeType.Conditional: _addInScopeNmsp = false; AnalyzeContent((nd as QilTernary) !.Center); AnalyzeContent((nd as QilTernary) !.Right); break; case QilNodeType.Choice: _addInScopeNmsp = false; QilList ndBranches = (nd as QilChoice) !.Branches; for (int idx = 0; idx < ndBranches.Count; idx++) { AnalyzeContent(ndBranches[idx]); } break; case QilNodeType.ElementCtor: // Start a new namespace scope _addInScopeNmsp = true; _nsmgr.PushScope(); cntNmspSave = _cntNmsp; if (CheckNamespaceInScope((nd as QilBinary) !)) { AnalyzeContent((nd as QilBinary) !.Right); } _nsmgr.PopScope(); _addInScopeNmsp = false; _cntNmsp = cntNmspSave; break; case QilNodeType.AttributeCtor: _addInScopeNmsp = false; CheckNamespaceInScope((nd as QilBinary) !); break; case QilNodeType.NamespaceDecl: CheckNamespaceInScope((nd as QilBinary) !); break; case QilNodeType.Nop: AnalyzeContent((nd as QilUnary) !.Child); break; default: _addInScopeNmsp = false; break; } }
public void CheckBool(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSubtypeOf(T.BooleanX), "Must be a singleton Bool"); }
public void CheckDouble(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSubtypeOf(T.DoubleX), "Must be a singleton Double"); }
public void CheckStringS(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSubtypeOf(T.StringXS), "Must be a sequence of strings"); }
public void CheckNode(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSingleton && n.XmlType.IsNode, "Must be a singleton node"); }
public static void CleanAnnotation(QilNode node) { node.Annotation = null; }
private QilNode CompileUnparsedEntityUri(QilNode n) { _f.CheckString(n); return(_f.Error(_lastScope.SourceLine, SR.Xslt_UnsupportedXsltFunction, "unparsed-entity-uri")); }
public static double GetPriority(QilNode node) { return(((Annotation)node.Annotation).Priority); }
// -------------------------------------- GetPredicateBuilder() --------------------------------------- public virtual IXPathBuilder <QilNode> GetPredicateBuilder(QilNode ctx) { return(this); }
public void CheckQName(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSubtypeOf(T.QNameX), "Must be a singleton QName"); }
public QilNode InvokeEnsureNodeSet(QilNode n) { return(XsltInvokeEarlyBound(QName("ensure-node-set"), XsltMethods.EnsureNodeSet, T.NodeSDod, new QilNode[] { n } )); }
public QilNode InvokeMsNumber(QilNode n) { return(XsltInvokeEarlyBound(QName("ms:number"), XsltMethods.MSNumber, T.DoubleX, new QilNode[] { n } )); }
private QilNode MatchPatternsWhosePriorityGreater(QilIterator it, List <Pattern> patternList, QilNode matcher) { if (patternList.Count == 0) { return(matcher); } if (IsNoMatch(matcher)) { return(MatchPatterns(it, patternList)); } QilIterator stopPriority = _f.Let(matcher); QilNode result = _f.Int32(NoMatch); int lastPriority = NoMatch; foreach (Pattern pattern in patternList) { // if (stopPriority > pattern.Priority) then stopPriority else // if ($it =~ pattern.Match) then pattern.Priority else... // First 'if' is generated lazily since it is not needed if priorities are consecutive numbers Debug.Assert(pattern.Priority > lastPriority); if (pattern.Priority > lastPriority + 1) { result = _f.Conditional(_f.Gt(stopPriority, _f.Int32(lastPriority)), stopPriority, result); } result = _f.Conditional(MatchPattern(it, pattern.Match), _f.Int32(pattern.Priority), result); lastPriority = pattern.Priority; } // If the last pattern has the highest priority, the check can be eliminated if (lastPriority != _priority) { result = _f.Conditional(_f.Gt(stopPriority, _f.Int32(lastPriority)), stopPriority, result); } return(_f.Loop(stopPriority, result)); }
public QilNode InvokeFormatNumberDynamic(QilNode value, QilNode formatPicture, QilNode decimalFormatName, QilNode errorMessageName) { CheckDouble(value); CheckString(formatPicture); CheckQName(decimalFormatName); CheckString(errorMessageName); return(XsltInvokeEarlyBound(QName("format-number-dynamic"), XsltMethods.FormatNumberDynamic, T.StringX, new QilNode[] { value, formatPicture, decimalFormatName, errorMessageName } )); }
// Helper methods used in addition to QilPatternFactory's ones public QilNode Error(string res, QilNode args) { return(Error(InvokeFormatMessage(String(res), args))); }
/// <summary> /// Perform analysis on the specified constructor and its content. Return the ndContent that was passed in, /// or a replacement. /// </summary> public virtual QilNode Analyze(QilNode ndConstr, QilNode ndContent) { if (ndConstr == null) { // Root expression is analyzed this.parentInfo = null; this.xstates = PossibleXmlStates.WithinSequence; this.withinElem = false; Debug.Assert(ndContent != null); ndContent = AnalyzeContent(ndContent); } else { this.parentInfo = XmlILConstructInfo.Write(ndConstr); if (ndConstr.NodeType == QilNodeType.Function) { // Results of function should be pushed to writer this.parentInfo.ConstructMethod = XmlILConstructMethod.Writer; // Start with PossibleXmlStates.None and then add additional possible starting states PossibleXmlStates xstates = PossibleXmlStates.None; foreach (XmlILConstructInfo infoCaller in this.parentInfo.CallersInfo) { if (xstates == PossibleXmlStates.None) { xstates = infoCaller.InitialStates; } else if (xstates != infoCaller.InitialStates) { xstates = PossibleXmlStates.Any; } // Function's results are pushed to Writer, so make sure that Invoke nodes' construct methods match infoCaller.PushToWriterFirst = true; } this.parentInfo.InitialStates = xstates; } else { // Build a standalone tree, with this constructor as its root if (ndConstr.NodeType != QilNodeType.Choice) { this.parentInfo.InitialStates = this.parentInfo.FinalStates = PossibleXmlStates.WithinSequence; } // Don't stream Rtf; fully cache the Rtf and copy it into any containing tree in order to simplify XmlILVisitor.VisitRtfCtor if (ndConstr.NodeType != QilNodeType.RtfCtor) { this.parentInfo.ConstructMethod = XmlILConstructMethod.WriterThenIterator; } } // Set withinElem = true if analyzing element content this.withinElem = (ndConstr.NodeType == QilNodeType.ElementCtor); switch (ndConstr.NodeType) { case QilNodeType.DocumentCtor: this.xstates = PossibleXmlStates.WithinContent; break; case QilNodeType.ElementCtor: this.xstates = PossibleXmlStates.EnumAttrs; break; case QilNodeType.AttributeCtor: this.xstates = PossibleXmlStates.WithinAttr; break; case QilNodeType.NamespaceDecl: Debug.Assert(ndContent == null); break; case QilNodeType.TextCtor: Debug.Assert(ndContent == null); break; case QilNodeType.RawTextCtor: Debug.Assert(ndContent == null); break; case QilNodeType.CommentCtor: this.xstates = PossibleXmlStates.WithinComment; break; case QilNodeType.PICtor: this.xstates = PossibleXmlStates.WithinPI; break; case QilNodeType.XsltCopy: this.xstates = PossibleXmlStates.Any; break; case QilNodeType.XsltCopyOf: Debug.Assert(ndContent == null); break; case QilNodeType.Function: this.xstates = this.parentInfo.InitialStates; break; case QilNodeType.RtfCtor: this.xstates = PossibleXmlStates.WithinContent; break; case QilNodeType.Choice: this.xstates = PossibleXmlStates.Any; break; default: Debug.Assert(false, ndConstr.NodeType + " is not handled by XmlILStateAnalyzer."); break; } if (ndContent != null) { ndContent = AnalyzeContent(ndContent); } if (ndConstr.NodeType == QilNodeType.Choice) { AnalyzeChoice(ndConstr as QilChoice, this.parentInfo); } // Since Function will never be another node's content, set its final states here if (ndConstr.NodeType == QilNodeType.Function) { this.parentInfo.FinalStates = this.xstates; } } return(ndContent); }
public void CheckNodeNotRtf(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSingleton && n.XmlType.IsNode && n.XmlType.IsNotRtf, "Must be a singleton node and not an Rtf"); }
private QilNode MatchPatterns(QilIterator it, XmlQueryType xt, PatternBag patternBag, QilNode otherwise) { if (patternBag.FixedNamePatternsNames.Count == 0) { return(MatchPatterns(it, xt, patternBag.NonFixedNamePatterns, otherwise)); } QilNode matcher = _f.Int32(NoMatch); foreach (QilName qname in patternBag.FixedNamePatternsNames) { matcher = _f.Conditional(_f.Eq(_f.NameOf(it), qname.ShallowClone(_f.BaseFactory)), MatchPatterns(it, patternBag.FixedNamePatterns[qname]), matcher ); } matcher = MatchPatternsWhosePriorityGreater(it, patternBag.NonFixedNamePatterns, matcher); return(_f.Conditional(_f.IsType(it, xt), matcher, otherwise)); }
private void FixupFilterBinding(QilLoop filter, QilNode newBinding) { AssertFilter(filter); filter.Variable.Binding = newBinding; }
public void CheckString(QilNode n) { Debug.Assert(n != null && n.XmlType !.IsSubtypeOf(T.StringX), "Must be a singleton string"); }
// XPath spec $4.2, string() public QilNode ConvertToString(QilNode n) { switch (n.XmlType !.TypeCode) {