コード例 #1
0
ファイル: XPathBuilder.cs プロジェクト: z77ma/runtime
        public virtual QilNode Operator(XPathOperator op, QilNode?left, QilNode?right)
        {
            Debug.Assert(op != XPathOperator.Unknown);
            XPathOperatorGroup opGroup = s_operatorGroup[(int)op];

            Debug.Assert((opGroup != XPathOperatorGroup.Negate && right != null) || (opGroup == XPathOperatorGroup.Negate && right == null));

            switch (opGroup)
            {
            case XPathOperatorGroup.Logical: return(LogicalOperator(op, left !, right !));

            case XPathOperatorGroup.Equality: return(EqualityOperator(op, left !, right !));

            case XPathOperatorGroup.Relational: return(RelationalOperator(op, left !, right !));

            case XPathOperatorGroup.Arithmetic: return(ArithmeticOperator(op, left !, right !));

            case XPathOperatorGroup.Negate: return(NegateOperator(op, left !));

            case XPathOperatorGroup.Union: return(UnionOperator(op, left, right !));

            default:
                Debug.Fail($"{op} is not a valid XPathOperator");
                return(null);
            }
        }
コード例 #2
0
ファイル: XPathBuilder.cs プロジェクト: z77ma/runtime
        public virtual QilNode?EndBuild(QilNode?result)
        {
            if (result == null)
            { // special door to clean builder state in exception handlers
                _inTheBuild = false;
                return(result);
            }
            Debug.Assert(_inTheBuild, "StartBuild() wasn't called");

            if (result.XmlType !.MaybeMany && result.XmlType.IsNode && result.XmlType.IsNotRtf)
            {
                result = _f.DocOrderDistinct(result);
            }
            result            = _fixupVisitor.Fixup(result, /*environment:*/ _environment);
            numFixupCurrent  -= _fixupVisitor.numCurrent;
            numFixupPosition -= _fixupVisitor.numPosition;
            numFixupLast     -= _fixupVisitor.numLast;

            // All these variables will be positive for "false() and (. = position() + last())"
            // since QilPatternFactory eliminates the right operand of 'and'
            Debug.Assert(numFixupCurrent >= 0, "Context fixup error");
            Debug.Assert(numFixupPosition >= 0, "Context fixup error");
            Debug.Assert(numFixupLast >= 0, "Context fixup error");
            _inTheBuild = false;
            return(result);
        }
コード例 #3
0
        QilNode IXPathEnvironment.ResolveVariable(string prefix, string name)
        {
            if (!_allowVariables)
            {
                throw new XslLoadException(SR.Xslt_VariablesNotAllowed);
            }
            string ns = ResolvePrefixThrow(/*ignoreDefaultNs:*/ true, prefix);

            Debug.Assert(ns != null);

            // Look up in params and variables of the current scope and all outer ones
            QilNode?var = _scope.LookupVariable(name, ns);

            if (var == null)
            {
                throw new XslLoadException(SR.Xslt_InvalidVariable, Compiler.ConstructQName(prefix, name));
            }

            // All Node* parameters are guaranteed to be in document order with no duplicates, so TypeAssert
            // this so that optimizer can use this information to avoid redundant sorts and duplicate removal.
            XmlQueryType varType = var.XmlType !;

            if (var.NodeType == QilNodeType.Parameter && varType.IsNode && varType.IsNotRtf && varType.MaybeMany && !varType.IsDod)
            {
                var = _f.TypeAssert(var, XmlQueryTypeFactory.NodeSDod);
            }

            return(var);
        }
コード例 #4
0
ファイル: KeyMatchBuilder.cs プロジェクト: z77ma/runtime
 public QilNode ConvertReletive2Absolute(QilNode node, QilNode fixup)
 {
     QilDepthChecker.Check(node);
     Debug.Assert(node != null);
     Debug.Assert(fixup != null);
     _fixup = fixup;
     return(this.Visit(node));
 }
コード例 #5
0
ファイル: QilFactory.cs プロジェクト: layomia/dotnet_runtime
        public QilParameter Parameter(QilNode?defaultValue, QilNode?name, XmlQueryType xmlType)
        {
            QilParameter n = new QilParameter(QilNodeType.Parameter, defaultValue, name, xmlType);

            n.XmlType = _typeCheck.CheckParameter(n);
            TraceNode(n);
            return(n);
        }
コード例 #6
0
ファイル: Focus.cs プロジェクト: mikem8361/runtime
 public void Sort(QilNode?sortKeys)
 {
     if (sortKeys != null)
     {
         // If sorting is required, cache the input node-set to support last() within sort key expressions
         EnsureCache();
         // The rest of the loop content must be compiled in the context of already sorted node-set
         _current = _f.For(_f.Sort(_current !, sortKeys));
     }
 }
コード例 #7
0
        public QilNode EnsureNodeSet(QilNode n)
        {
            QilNode?result = TryEnsureNodeSet(n);

            if (result == null)
            {
                throw new XPathCompileException(SR.XPath_NodeSetExpected);
            }
            return(result);
        }
コード例 #8
0
        public QilNode?EndBuild(QilNode?result)
        {
            Debug.Assert(_inTheBuild, "StartBuild() wasn't called");

            // All these variables will be positive for "false() and (. = position() + last())"
            // since QilPatternFactory eliminates the right operand of 'and'
            Debug.Assert(_predicateEnvironment.numFixupCurrent >= 0, "Context fixup error");
            Debug.Assert(_predicateEnvironment.numFixupPosition >= 0, "Context fixup error");
            Debug.Assert(_predicateEnvironment.numFixupLast >= 0, "Context fixup error");
            _inTheBuild = false;
            return(result);
        }
コード例 #9
0
        public QilNode GenerateInvoke(QilFunction func, IList <XslNode> actualArgs)
        {
            _iterStack.Clear();
            _formalArgs = func.Arguments;
            _invokeArgs = _fac.ActualParameterList();

            // curArg is an instance variable used in Clone() method
            for (_curArg = 0; _curArg < _formalArgs.Count; _curArg++)
            {
                // Find actual value for a given formal arg
                QilParameter formalArg = (QilParameter)_formalArgs[_curArg];
                QilNode?     invokeArg = FindActualArg(formalArg, actualArgs);

                // If actual value was not specified, use the default value and copy its debug comment
                if (invokeArg == null)
                {
                    if (_debug)
                    {
                        if (formalArg.Name !.NamespaceUri == XmlReservedNs.NsXslDebug)
                        {
                            Debug.Assert(formalArg.Name.LocalName == "namespaces", "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs()");
                            Debug.Assert(formalArg.DefaultValue != null, "PrecompileProtoTemplatesHeaders() set it");
                            invokeArg = Clone(formalArg.DefaultValue);
                        }
                        else
                        {
                            invokeArg = _fac.DefaultValueMarker();
                        }
                    }
                    else
                    {
                        Debug.Assert(formalArg.Name !.NamespaceUri != XmlReservedNs.NsXslDebug, "Cur,Pos,Last don't have default values and should be always added to by caller in AddImplicitArgs(). We don't have $namespaces in !debug.");
                        invokeArg = Clone(formalArg.DefaultValue !);
                    }
                }

                XmlQueryType formalType = formalArg.XmlType !;
                XmlQueryType invokeType = invokeArg.XmlType !;

                // Possible arg types: anyType, node-set, string, boolean, and number
                _fac.CheckXsltType(formalArg);
                _fac.CheckXsltType(invokeArg);

                if (!invokeType.IsSubtypeOf(formalType))
                {
                    // This may occur only if inferred type of invokeArg is XslFlags.None
                    Debug.Assert(invokeType == T.ItemS, "Actual argument type is not a subtype of formal argument type");
                    invokeArg = _fac.TypeAssert(invokeArg, formalType);
                }

                _invokeArgs.Add(invokeArg);
            }
コード例 #10
0
 public override QilNode this[int index]
 {
     get { if (index != 0)
           {
               throw new IndexOutOfRangeException();
           }
           return(_binding !); }
     set { if (index != 0)
           {
               throw new IndexOutOfRangeException();
           }
           _binding = value; }
 }
コード例 #11
0
ファイル: XPathBuilder.cs プロジェクト: zdbobi/runtime
            public QilNode Fixup(QilNode inExpr, QilIterator current, QilNode?last)
            {
                QilDepthChecker.Check(inExpr);
                _current = current;
                _last    = last;
                Debug.Assert(current != null);
                _justCount   = false;
                _environment = null;
                numCurrent   = numPosition = numLast = 0;
                inExpr       = VisitAssumeReference(inExpr);
#if StopMaskOptimisation
                SetStopVisitMark(inExpr, /*stop*/ true);
#endif
                return(inExpr);
            }
コード例 #12
0
        public TemplateMatch(Template template, QilLoop filter)
        {
            _template  = template;
            _priority  = double.IsNaN(template.Priority) ? XPathPatternBuilder.GetPriority(filter) : template.Priority;
            _iterator  = filter.Variable;
            _condition = filter.Body;

            XPathPatternBuilder.CleanAnnotation(filter);
            NipOffTypeNameCheck();

            Debug.Assert(
                _qname == null ||
                _nodeKind == XmlNodeKindFlags.Element || _nodeKind == XmlNodeKindFlags.Attribute || _nodeKind == XmlNodeKindFlags.PI,
                "qname may be not null only for element, attribute, or PI patterns"
                );
        }
コード例 #13
0
        private QilNode MatchPattern(QilIterator it, TemplateMatch match)
        {
            QilNode?cond = match.Condition;

            if (cond == null)
            {
                return(_f.True());
            }
            else
            {
                // We have to clone, because the same pattern may be used
                // in many different xsl:apply-templates/imports functions
                cond = cond.DeepClone(_f.BaseFactory);
                return(_refReplacer.Replace(cond, match.Iterator, it));
            }
        }
コード例 #14
0
 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);
         }
     }
 }
コード例 #15
0
        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
            }

            // All these variables will be positive for "false() and (. = position() + last())"
            // since QilPatternFactory eliminates the right operand of 'and'
            Debug.Assert(_predicateEnvironment.numFixupCurrent >= 0, "Context fixup error");
            Debug.Assert(_predicateEnvironment.numFixupPosition >= 0, "Context fixup error");
            Debug.Assert(_predicateEnvironment.numFixupLast >= 0, "Context fixup error");
            _inTheBuild = false;
            return(result);
        }
コード例 #16
0
ファイル: KeyMatchBuilder.cs プロジェクト: z77ma/runtime
        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);
        }
コード例 #17
0
 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));
     }
 }
コード例 #18
0
        /// <summary>
        /// Analyze the content argument of the ElementCtor.  Try to eliminate as many runtime checks as possible,
        /// both for the ElementCtor and for content constructors.
        /// </summary>
        public override QilNode?Analyze(QilNode?ndElem, QilNode?ndContent)
        {
            Debug.Assert(ndElem !.NodeType == QilNodeType.ElementCtor);
            this.parentInfo = XmlILConstructInfo.Write(ndElem);

            // Start by assuming that these properties are false (they default to true, but analyzer might be able to
            // prove they are really false).
            this.parentInfo.MightHaveNamespacesAfterAttributes = false;
            this.parentInfo.MightHaveAttributes          = false;
            this.parentInfo.MightHaveDuplicateAttributes = false;

            // The element's namespace might need to be declared
            this.parentInfo.MightHaveNamespaces = !this.parentInfo.IsNamespaceInScope;

            // Clear list of duplicate attributes
            _dupAttrs.Clear();

            return(base.Analyze(ndElem, ndContent));
        }
コード例 #19
0
ファイル: XPathBuilder.cs プロジェクト: zdbobi/runtime
 private QilNode UnionOperator(XPathOperator op, QilNode?left, QilNode right)
 {
     Debug.Assert(op == XPathOperator.Union);
     if (left == null)
     {
         return(_f.EnsureNodeSet(right));
     }
     left  = _f.EnsureNodeSet(left);
     right = _f.EnsureNodeSet(right);
     if (left.NodeType == QilNodeType.Sequence)
     {
         ((QilList)left).Add(right);
         return(left);
     }
     else
     {
         return(_f.Union(left, right));
     }
 }
コード例 #20
0
        //-----------------------------------------------
        // QilVisitor overrides
        //-----------------------------------------------

        /// <summary>
        /// Visit all children of "parent", replacing each child with a copy of each child.
        /// </summary>
        protected override QilNode Visit(QilNode oldNode)
        {
            QilNode?newNode = null;

            if (oldNode == null)
            {
                return(null !);
            }

            // ShallowClone any nodes which have not yet been cloned
            if (oldNode is QilReference)
            {
                // Reference nodes may have been cloned previously and put into scope
                newNode = FindClonedReference(oldNode);
            }

            newNode ??= oldNode.ShallowClone(_fac);

            return(base.Visit(newNode));
        }
コード例 #21
0
        public QilNode Parse(XPathScanner scanner, IPatternBuilder ptrnBuilder)
        {
            Debug.Assert(_scanner == null && _ptrnBuilder == null);
            Debug.Assert(scanner != null && ptrnBuilder != null);
            QilNode?result = null;

            ptrnBuilder.StartBuild();
            try
            {
                _scanner     = scanner;
                _ptrnBuilder = ptrnBuilder;
                result       = this.ParsePattern();
                _scanner.CheckToken(LexKind.Eof);
            }
            finally
            {
                result = ptrnBuilder.EndBuild(result);
#if DEBUG
                _ptrnBuilder = null;
                _scanner     = null;
#endif
            }
            return(result !);
        }
コード例 #22
0
        /// <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.Fail($"{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);
        }
コード例 #23
0
 public QilParameter Parameter(QilNode?defaultValue, QilName?name, XmlQueryType t)
 {
     return(_f.Parameter(defaultValue, name, t));
 }
コード例 #24
0
ファイル: QilParameter.cs プロジェクト: z77ma/runtime
        //-----------------------------------------------
        // Constructor
        //-----------------------------------------------

        /// <summary>
        /// Construct a parameter
        /// </summary>
        public QilParameter(QilNodeType nodeType, QilNode?defaultValue, QilNode?name, XmlQueryType xmlType) : base(nodeType, defaultValue)
        {
            _name        = name;
            this.xmlType = xmlType;
        }
コード例 #25
0
        private void NipOffTypeNameCheck()
        {
            QilBinary[] leftPath = new QilBinary[4]; // Circular buffer for last 4 And nodes
            int         idx      = -1;               // Index of last element in leftPath
            QilNode     node     = _condition !;     // Walker through left path of the tree

            _nodeKind = XmlNodeKindFlags.None;
            _qname    = null;

            while (node.NodeType == QilNodeType.And)
            {
                node = (leftPath[++idx & 3] = (QilBinary)node).Left;
            }

            // Recognizing (IsType RefTo LiteralType)
            if (!(node.NodeType == QilNodeType.IsType))
            {
                return;
            }

            QilBinary isType = (QilBinary)node;

            if (!(isType.Left == _iterator && isType.Right.NodeType == QilNodeType.LiteralType))
            {
                return;
            }

            XmlNodeKindFlags nodeKinds = isType.Right.XmlType !.NodeKinds;

            if (!Bits.ExactlyOne((uint)nodeKinds))
            {
                return;
            }

            // Recognized pattern A, check for B
            QilNode x = isType;

            _nodeKind = nodeKinds;
            QilBinary lastAnd = leftPath[idx & 3];

            if (lastAnd != null && lastAnd.Right.NodeType == QilNodeType.Eq)
            {
                QilBinary eq = (QilBinary)lastAnd.Right;

                // Recognizing (Eq (NameOf RefTo) LiteralQName)
                if (eq.Left.NodeType == QilNodeType.NameOf &&
                    ((QilUnary)eq.Left).Child == _iterator && eq.Right.NodeType == QilNodeType.LiteralQName
                    )
                {
                    // Recognized pattern B
                    x      = lastAnd;
                    _qname = (QilName?)((QilLiteral)eq.Right).Value;
                    idx--;
                }
            }

            // Nip $x off the condition
            QilBinary and1 = leftPath[idx & 3];
            QilBinary and2 = leftPath[--idx & 3];

            if (and2 != null)
            {
                and2.Left = and1.Right;
            }
            else if (and1 != null)
            {
                _condition = and1.Right;
            }
            else
            {
                _condition = null;
            }
        }
コード例 #26
0
 public QilIterator(QilNodeType nodeType, QilNode?binding) : base(nodeType)
 {
     Binding = binding;
 }
コード例 #27
0
        /// <summary>
        /// If a cloned reference is in scope, replace "oldNode".  Otherwise, return "oldNode".
        /// </summary>
        protected override QilNode VisitReference(QilNode oldNode)
        {
            QilNode?newNode = FindClonedReference(oldNode);

            return(base.VisitReference(newNode == null ? oldNode : newNode));
        }
コード例 #28
0
 protected virtual QilNode?NoReplace(QilNode?node)
 {
     return(node);
 }