示例#1
0
 private void CompileBoolean(XPathExpr expr, bool testValue)
 {
     if (this.compiler.nestingLevel == 1)
     {
         this.CompileBasicBoolean(expr, testValue);
     }
     else
     {
         OpcodeBlock block = new OpcodeBlock();
         Opcode      jump  = new BlockEndOpcode();
         block.Append(new PushBooleanOpcode(testValue));
         XPathExprList subExpr = expr.SubExpr;
         XPathExpr     expr2   = subExpr[0];
         block.Append(this.CompileBlock(expr2));
         if (expr2.ReturnType != ValueDataType.Boolean)
         {
             block.Append(new TypecastOpcode(ValueDataType.Boolean));
         }
         block.Append(new ApplyBooleanOpcode(jump, testValue));
         for (int i = 1; i < subExpr.Count; i++)
         {
             expr2 = subExpr[i];
             block.Append(new StartBooleanOpcode(testValue));
             block.Append(this.CompileBlock(expr2));
             if (expr2.ReturnType != ValueDataType.Boolean)
             {
                 block.Append(new TypecastOpcode(ValueDataType.Boolean));
             }
             block.Append(new EndBooleanOpcode(jump, testValue));
         }
         block.Append(jump);
         this.codeBlock.Append(block);
     }
 }
示例#2
0
        public QueryFunction Bind(string functionName, string functionNamespace, XPathExprList args)
        {
            Fx.Assert(null != functionName && null != args, "");

            // Variable length argument list requires a special case here
            if (functionName == "concat" && args.Count > 4)
            {
                ConcatFunction f = new ConcatFunction(args.Count);
                if (f.Bind(functionName, args))
                {
                    return(f);
                }
            }
            else
            {
                for (int i = 0; i < XPathFunctionLibrary.functionTable.Length; ++i)
                {
                    // XPath functions are typeless, so don't check types
                    if (XPathFunctionLibrary.functionTable[i].Bind(functionName, args))
                    {
                        return(XPathFunctionLibrary.functionTable[i]);
                    }
                }
            }

            return(null);
        }
示例#3
0
            // Compiles expressions at nesting level == 1 -> boolean expressions that can be processed
            // with less complex opcodes because they will never track multiple sequences simultaneously
            void CompileBasicBoolean(XPathExpr expr, bool testValue)
            {
                // Boolean expressions must always have at least 2 sub expressions
                Fx.Assert(expr.SubExprCount > 1, "");
                Fx.Assert(this.compiler.nestingLevel == 1, "");

                OpcodeBlock   boolBlock   = new OpcodeBlock(); // struct
                Opcode        blockEnd    = new BlockEndOpcode();
                XPathExprList subExprList = expr.SubExpr;

                // Compile sub-expressions
                for (int i = 0; i < subExprList.Count; ++i)
                {
                    XPathExpr subExpr = subExprList[i];
                    boolBlock.Append(this.CompileBlock(subExpr));
                    // Make sure each sub-expression can produce a boolean result
                    if (subExpr.ReturnType != ValueDataType.Boolean)
                    {
                        boolBlock.Append(new TypecastOpcode(ValueDataType.Boolean));
                    }
                    if (i < (subExprList.Count - 1))
                    {
                        // No point jumping if this is the last expression
                        boolBlock.Append(new JumpIfOpcode(blockEnd, testValue));
                    }
                }
                boolBlock.Append(blockEnd);
                this.codeBlock.Append(boolBlock);
            }
示例#4
0
        XPathExprList ParseAbsolutePath()
        {
            XPathExprList path  = null;
            XPathToken    token = this.NextToken();

            if (null != token)
            {
                switch (token.TokenID)
                {
                default:
                    this.PushToken(token);
                    break;

                case XPathTokenID.Slash:
                    path = new XPathExprList();
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                    break;

                case XPathTokenID.DblSlash:
                    // '//' is special. If found at the start of an absolute path, it implies that the descendant-or-self axis
                    // is applied to the ROOT
                    path = new XPathExprList();
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
                    break;
                }
            }

            if (null != path)
            {
                this.ParseRelativePath(path);
            }

            return(path);
        }
示例#5
0
            void CompileFunction(XPathFunctionExpr expr)
            {
                // In some scenarios, some functions are handled in a special way
                if (this.CompileFunctionSpecial(expr))
                {
                    return;
                }

                // Generic function compilation
                QueryFunction function = expr.Function;

                // Compile each argument expression first, introducing a typecast where appropriate
                // Arguments are pushed C style - right to left
                if (expr.SubExprCount > 0)
                {
                    XPathExprList paramList = expr.SubExpr;
                    for (int i = paramList.Count - 1; i >= 0; --i)
                    {
                        this.CompileFunctionParam(function, expr.SubExpr, i);
                    }
                }
                this.codeBlock.Append(new FunctionCallOpcode(function));
                if (1 == this.compiler.nestingLevel && function.TestFlag(QueryFunctionFlag.UsesContextNode))
                {
                    this.compiler.SetPushInitialContext(true);
                }
            }
        private bool ParseRelativePath(XPathExprList path)
        {
            XPathStepExpr expr = this.ParseStep();

            if (expr == null)
            {
                return(false);
            }
            path.Add(expr);
            while (true)
            {
                if (this.NextToken(XPathTokenID.Slash) != null)
                {
                    expr = this.ParseStep();
                }
                else
                {
                    if (this.NextToken(XPathTokenID.DblSlash) == null)
                    {
                        return(true);
                    }
                    expr = new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All));
                    path.Add(expr);
                    expr = this.ParseStep();
                }
                if (expr == null)
                {
                    this.ThrowError(QueryCompileError.InvalidLocationPath);
                }
                path.Add(expr);
            }
        }
示例#7
0
            void CompileXsltFunction(XPathXsltFunctionExpr expr)
            {
                // Compile each argument expression first, introducing a typecast where appropriate
                // Arguments are pushed C style - right to left
                if (expr.SubExprCount > 0)
                {
                    XPathExprList paramList = expr.SubExpr;
                    for (int i = paramList.Count - 1; i >= 0; --i)
                    {
                        XPathExpr param = paramList[i];
                        this.CompileExpression(param);
                        ValueDataType paramType = XPathXsltFunctionExpr.ConvertTypeFromXslt(expr.Function.ArgTypes[i]);
                        if (ValueDataType.None != paramType)
                        {
                            if (param.ReturnType != paramType)
                            {
                                this.CompileTypecast(paramType);
                            }
                        }
                    }
                }

                if (expr.Function is XPathMessageFunction)
                {
                    this.codeBlock.Append(new XPathMessageFunctionCallOpcode((XPathMessageFunction)expr.Function, expr.SubExprCount));
                    if (IsSpecialInternalFunction(expr))
                    {
                        this.codeBlock.Append(new PopSequenceToValueStackOpcode());
                    }
                }
                else
                {
                    this.codeBlock.Append(new XsltFunctionCallOpcode(expr.Context, expr.Function, expr.SubExprCount));
                }
            }
示例#8
0
            private void CompileFilter(XPathExpr expr)
            {
                XPathExprList subExpr = expr.SubExpr;
                XPathExpr     expr2   = subExpr[0];

                if ((subExpr.Count > 1) && (ValueDataType.Sequence != expr2.ReturnType))
                {
                    this.ThrowError(QueryCompileError.InvalidExpression);
                }
                this.CompileExpression(expr2);
                if (expr2.ReturnType == ValueDataType.Sequence)
                {
                    if (!this.IsSpecialInternalFunction(expr2) && (expr.SubExprCount > 1))
                    {
                        this.codeBlock.Append(new MergeOpcode());
                        this.codeBlock.Append(new PopSequenceToSequenceStackOpcode());
                    }
                    else if (this.IsSpecialInternalFunction(expr2) && (expr.SubExprCount > 1))
                    {
                        this.codeBlock.DetachLast();
                    }
                    this.compiler.nestingLevel++;
                    if (this.compiler.nestingLevel > 3)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.PredicateNestingTooDeep));
                    }
                    for (int i = 1; i < expr.SubExprCount; i++)
                    {
                        this.CompilePredicate(subExpr[i]);
                    }
                    this.compiler.nestingLevel--;
                }
            }
        private XPathExprList ParseAbsolutePath()
        {
            XPathExprList path  = null;
            XPathToken    token = this.NextToken();

            if (token != null)
            {
                XPathTokenID tokenID = token.TokenID;
                if (tokenID == XPathTokenID.Slash)
                {
                    path = new XPathExprList();
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                }
                else if (tokenID == XPathTokenID.DblSlash)
                {
                    path = new XPathExprList();
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                    path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
                }
                else
                {
                    this.PushToken(token);
                }
            }
            if (path != null)
            {
                this.ParseRelativePath(path);
            }
            return(path);
        }
示例#10
0
 private void CompilePredicates(XPathExprList exprList)
 {
     for (int i = 0; i < exprList.Count; i++)
     {
         this.CompilePredicate(exprList[i]);
     }
 }
示例#11
0
 private void CompileXsltFunction(XPathXsltFunctionExpr expr)
 {
     if (expr.SubExprCount > 0)
     {
         XPathExprList subExpr = expr.SubExpr;
         for (int i = subExpr.Count - 1; i >= 0; i--)
         {
             XPathExpr expr2 = subExpr[i];
             this.CompileExpression(expr2);
             ValueDataType destType = XPathXsltFunctionExpr.ConvertTypeFromXslt(expr.Function.ArgTypes[i]);
             if ((destType != ValueDataType.None) && (expr2.ReturnType != destType))
             {
                 this.CompileTypecast(destType);
             }
         }
     }
     if (expr.Function is XPathMessageFunction)
     {
         this.codeBlock.Append(new XPathMessageFunctionCallOpcode((XPathMessageFunction)expr.Function, expr.SubExprCount));
         if (this.IsSpecialInternalFunction(expr))
         {
             this.codeBlock.Append(new PopSequenceToValueStackOpcode());
         }
     }
     else
     {
         this.codeBlock.Append(new XsltFunctionCallOpcode(expr.Context, expr.Function, expr.SubExprCount));
     }
 }
示例#12
0
 void CompilePredicates(XPathExprList exprList)
 {
     // Compile each predicate expression first
     for (int i = 0; i < exprList.Count; ++i)
     {
         this.CompilePredicate(exprList[i]);
     }
 }
        private XPathExpr ParseFunctionExpression()
        {
            XPathExpr  expr;
            XPathToken token = this.NextToken(XPathTokenID.Function);

            if (token == null)
            {
                return(null);
            }
            NodeQName name = this.QualifyName(token.Prefix, token.Name);

            this.NextToken(XPathTokenID.LParen, QueryCompileError.InvalidFunction);
            XPathExprList args = new XPathExprList();

            while ((expr = this.ParseExpression()) != null)
            {
                args.Add(expr);
                if (this.NextToken(XPathTokenID.Comma) == null)
                {
                    break;
                }
            }
            XPathExpr expr2 = null;

            if (this.functionLibraries != null)
            {
                QueryFunction function = null;
                for (int i = 0; i < this.functionLibraries.Length; i++)
                {
                    function = this.functionLibraries[i].Bind(name.Name, name.Namespace, args);
                    if (function != null)
                    {
                        expr2 = new XPathFunctionExpr(function, args);
                        break;
                    }
                }
            }
            if ((expr2 == null) && (this.context != null))
            {
                XPathResultType[] argTypes = new XPathResultType[args.Count];
                for (int j = 0; j < args.Count; j++)
                {
                    argTypes[j] = XPathXsltFunctionExpr.ConvertTypeToXslt(args[j].ReturnType);
                }
                string prefix = this.context.LookupPrefix(name.Namespace);
                IXsltContextFunction function2 = this.context.ResolveFunction(prefix, name.Name, argTypes);
                if (function2 != null)
                {
                    expr2 = new XPathXsltFunctionExpr(this.context, function2, args);
                }
            }
            if (expr2 == null)
            {
                this.ThrowError(QueryCompileError.UnsupportedFunction);
            }
            this.NextToken(XPathTokenID.RParen, QueryCompileError.InvalidFunction);
            return(expr2);
        }
        private XPathExprList ParseRelativePath()
        {
            XPathExprList path = new XPathExprList();

            if (this.ParseRelativePath(path))
            {
                return(path);
            }
            return(null);
        }
示例#15
0
        XPathExpr ParsePathExpression()
        {
            XPathExpr pathExpr = this.ParseLocationPath();

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

            // Perhaps we have a filter expression
            XPathExpr filterExpr = this.ParseFilterExpression();

            if (null != filterExpr)
            {
                if (null != this.NextToken(XPathTokenID.Slash))
                {
                    EnsureReturnsNodeSet(filterExpr);

                    // Is this a complex filter expression.. i.e. followed by further selections..
                    XPathExprList relPath = this.ParseRelativePath();
                    if (null == relPath)
                    {
                        this.ThrowError(QueryCompileError.InvalidLocationPath);
                    }

                    XPathExpr relPathExpr = new XPathExpr(XPathExprType.RelativePath, ValueDataType.Sequence, relPath);

                    pathExpr = new XPathExpr(XPathExprType.Path, ValueDataType.Sequence);
                    pathExpr.Add(filterExpr);
                    pathExpr.Add(relPathExpr);
                }
                else if (null != this.NextToken(XPathTokenID.DblSlash))
                {
                    EnsureReturnsNodeSet(filterExpr);

                    XPathExprList relPath = this.ParseRelativePath();
                    if (null == relPath)
                    {
                        this.ThrowError(QueryCompileError.InvalidLocationPath);
                    }

                    XPathExpr relPathExpr = new XPathExpr(XPathExprType.RelativePath, ValueDataType.Sequence, relPath);
                    pathExpr = new XPathExpr(XPathExprType.Path, ValueDataType.Sequence);
                    pathExpr.Add(filterExpr);
                    pathExpr.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
                    pathExpr.Add(relPathExpr);
                }
                else
                {
                    pathExpr = filterExpr;
                }
            }

            return(pathExpr);
        }
示例#16
0
        XPathStepExpr ParseStep()
        {
            QueryAxisType      axis       = this.ParseAxisSpecifier();
            NodeSelectCriteria selectDesc = null;
            bool abbreviatedStep          = false;

            if (QueryAxisType.None != axis)
            {
                // Valid axis specifier - must be followed by a nodeTest
                selectDesc = this.ParseNodeTest(axis);
            }
            else
            {
                // No axis specifier. This could be an abbreviated step - shortcuts for 'self' or 'parent'
                if (null != this.NextToken(XPathTokenID.Period))
                {
                    selectDesc      = new NodeSelectCriteria(QueryAxisType.Self, NodeQName.Empty, QueryNodeType.All);
                    abbreviatedStep = true;
                }
                else if (null != this.NextToken(XPathTokenID.DblPeriod))
                {
                    // A shortcut for parent
                    selectDesc      = new NodeSelectCriteria(QueryAxisType.Parent, NodeQName.Empty, QueryNodeType.Ancestor);
                    abbreviatedStep = true;
                }
                else
                {
                    // No axis specifier provided. Assume child
                    if (null == (selectDesc = this.ParseNodeTest(QueryAxisType.Child)))
                    {
                        // No nodeTest either.. clearly not a Step
                        return(null);
                    }
                }
            }

            if (null == selectDesc)
            {
                this.ThrowError(QueryCompileError.InvalidLocationStep);
            }

            XPathExprList predicates = null;

            if (!abbreviatedStep)
            {
                // Abbreviated steps are not permitted predicates
                predicates = this.ParsePredicates();
            }

            return(new XPathStepExpr(selectDesc, predicates));
        }
        internal XPathExpr ParseLocationPath()
        {
            XPathExprList subExpr = this.ParseAbsolutePath();

            if (subExpr == null)
            {
                subExpr = this.ParseRelativePath();
            }
            if (subExpr != null)
            {
                return(new XPathExpr(XPathExprType.LocationPath, ValueDataType.Sequence, subExpr));
            }
            return(null);
        }
示例#18
0
            private void CompileFunctionParam(QueryFunction function, XPathExprList paramList, int index)
            {
                XPathExpr expr = paramList[index];

                this.CompileExpression(expr);
                if ((function.ParamTypes[index] != ValueDataType.None) && (expr.ReturnType != function.ParamTypes[index]))
                {
                    if (function.ParamTypes[index] == ValueDataType.Sequence)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.InvalidTypeConversion));
                    }
                    this.CompileTypecast(function.ParamTypes[index]);
                }
            }
示例#19
0
        internal bool Bind(string name, XPathExprList args)
        {
            Fx.Assert(null != name && null != args, "");

            if (
                0 != string.CompareOrdinal(this.name, name) ||
                this.paramTypes.Length != args.Count
                )
            {
                return(false);
            }

            return(this.paramTypes.Length == args.Count);
        }
 internal void AddBooleanExpression(XPathExprType boolExprType, XPathExpr expr)
 {
     if (boolExprType == expr.Type)
     {
         XPathExprList subExpr = expr.SubExpr;
         for (int i = 0; i < subExpr.Count; i++)
         {
             this.AddBooleanExpression(boolExprType, subExpr[i]);
         }
     }
     else
     {
         this.Add(expr);
     }
 }
        private XPathExprList ParsePredicates()
        {
            XPathExprList list = null;
            XPathExpr     expr = this.ParsePredicateExpression();

            if (expr != null)
            {
                list = new XPathExprList();
                list.Add(expr);
                while ((expr = this.ParsePredicateExpression()) != null)
                {
                    list.Add(expr);
                }
            }
            return(list);
        }
示例#22
0
        internal XPathExpr ParseLocationPath()
        {
            XPathExprList path = this.ParseAbsolutePath();

            if (null == path)
            {
                path = this.ParseRelativePath();
            }

            if (null != path)
            {
                return(new XPathExpr(XPathExprType.LocationPath, ValueDataType.Sequence, path));
            }

            return(null);
        }
示例#23
0
        XPathExprList ParsePredicates()
        {
            XPathExprList predicates = null;
            XPathExpr     predicate  = this.ParsePredicateExpression();

            if (null != predicate)
            {
                predicates = new XPathExprList();
                predicates.Add(predicate);
                while (null != (predicate = this.ParsePredicateExpression()))
                {
                    predicates.Add(predicate);
                }
            }

            return(predicates);
        }
        private XPathExpr ParsePathExpression()
        {
            XPathExpr expr = this.ParseLocationPath();

            if (expr != null)
            {
                return(expr);
            }
            XPathExpr expr2 = this.ParseFilterExpression();

            if (expr2 == null)
            {
                return(expr);
            }
            if (this.NextToken(XPathTokenID.Slash) != null)
            {
                this.EnsureReturnsNodeSet(expr2);
                XPathExprList subExpr = this.ParseRelativePath();
                if (subExpr == null)
                {
                    this.ThrowError(QueryCompileError.InvalidLocationPath);
                }
                XPathExpr expr3 = new XPathExpr(XPathExprType.RelativePath, ValueDataType.Sequence, subExpr);
                expr = new XPathExpr(XPathExprType.Path, ValueDataType.Sequence);
                expr.Add(expr2);
                expr.Add(expr3);
                return(expr);
            }
            if (this.NextToken(XPathTokenID.DblSlash) != null)
            {
                this.EnsureReturnsNodeSet(expr2);
                XPathExprList list2 = this.ParseRelativePath();
                if (list2 == null)
                {
                    this.ThrowError(QueryCompileError.InvalidLocationPath);
                }
                XPathExpr expr4 = new XPathExpr(XPathExprType.RelativePath, ValueDataType.Sequence, list2);
                expr = new XPathExpr(XPathExprType.Path, ValueDataType.Sequence);
                expr.Add(expr2);
                expr.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
                expr.Add(expr4);
                return(expr);
            }
            return(expr2);
        }
示例#25
0
            void CompileBoolean(XPathExpr expr, bool testValue)
            {
                // Boolean expressions must always have at least 2 sub expressions
                Fx.Assert(expr.SubExprCount > 1, "");

                if (this.compiler.nestingLevel == 1)
                {
                    this.CompileBasicBoolean(expr, testValue);
                    return;
                }

                OpcodeBlock boolBlock = new OpcodeBlock(); // struct
                Opcode      blockEnd  = new BlockEndOpcode();

                // Set up the result mask
                boolBlock.Append(new PushBooleanOpcode(testValue));
                XPathExprList subExprList = expr.SubExpr;
                XPathExpr     subExpr;

                // the first expression needs the least work..
                subExpr = subExprList[0];
                boolBlock.Append(this.CompileBlock(subExpr));
                if (subExpr.ReturnType != ValueDataType.Boolean)
                {
                    boolBlock.Append(new TypecastOpcode(ValueDataType.Boolean));
                }
                boolBlock.Append(new ApplyBooleanOpcode(blockEnd, testValue));

                // Compile remaining sub-expressions
                for (int i = 1; i < subExprList.Count; ++i)
                {
                    subExpr = subExprList[i];
                    boolBlock.Append(new StartBooleanOpcode(testValue));
                    boolBlock.Append(this.CompileBlock(subExpr));
                    // Make sure each sub-expression can produce a boolean result
                    if (subExpr.ReturnType != ValueDataType.Boolean)
                    {
                        boolBlock.Append(new TypecastOpcode(ValueDataType.Boolean));
                    }
                    boolBlock.Append(new EndBooleanOpcode(blockEnd, testValue));
                }
                boolBlock.Append(blockEnd);
                this.codeBlock.Append(boolBlock);
            }
示例#26
0
 void CompileSteps(XPathExprList steps, bool start)
 {
     for (int i = 0; i < steps.Count; ++i)
     {
         Fx.Assert(XPathExprType.PathStep == steps[i].Type, "");
         XPathStepExpr step = (XPathStepExpr)steps[i];
         if (!step.SelectDesc.Axis.IsSupported())
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.UnsupportedAxis));
         }
         Opcode stepOpcode = null;
         if (start && 0 == i)
         {
             // First steps
             // Is this an absolute path? We have an absolute path if the first step selects the root
             if (QueryNodeType.Root == step.SelectDesc.Type)
             {
                 stepOpcode = new SelectRootOpcode();
             }
             else
             {
                 stepOpcode = new InitialSelectOpcode(step.SelectDesc);
             }
         }
         else
         {
             Fx.Assert(QueryNodeType.Root != step.SelectDesc.Type, "");
             stepOpcode = new SelectOpcode(step.SelectDesc);
         }
         this.codeBlock.Append(stepOpcode);
         // The step may have predicates..
         if (step.SubExprCount > 0)
         {
             this.compiler.nestingLevel++;
             if (this.compiler.nestingLevel > 3) // throw if we find something deepter than [ [ ] ]
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.PredicateNestingTooDeep));
             }
             this.CompilePredicates(step.SubExpr);
             this.compiler.nestingLevel--;
         }
     }
 }
示例#27
0
            void CompileFilter(XPathExpr expr)
            {
                Fx.Assert(XPathExprType.Filter == expr.Type, "");
                // The filter expression has two components - the expression and its predicate
                // It may have an optional relative path following it
                //Debug.Assert(expr.SubExprCount <= 3);
                XPathExprList subExpr = expr.SubExpr;

                XPathExpr filterExpr = subExpr[0];

                if (subExpr.Count > 1 && ValueDataType.Sequence != filterExpr.ReturnType)
                {
                    this.ThrowError(QueryCompileError.InvalidExpression);
                }
                // The filter expression will return a sequence and push it onto the value stack
                // Transfer it back to the sequence stack, so we can keep working on it
                this.CompileExpression(filterExpr);
                if (filterExpr.ReturnType == ValueDataType.Sequence)
                {
                    if (!IsSpecialInternalFunction(filterExpr) && expr.SubExprCount > 1)
                    {
                        // Flatten the sequence and move it to the sequence stack
                        this.codeBlock.Append(new MergeOpcode());
                        this.codeBlock.Append(new PopSequenceToSequenceStackOpcode());
                    }
                    else if (IsSpecialInternalFunction(filterExpr) && expr.SubExprCount > 1)
                    {
                        this.codeBlock.DetachLast();
                    }

                    // Now, apply the predicates
                    this.compiler.nestingLevel++;
                    if (this.compiler.nestingLevel > 3) // throw if we find something deepter than [ [ ] ]
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.PredicateNestingTooDeep));
                    }
                    for (int i = 1; i < expr.SubExprCount; ++i)
                    {
                        this.CompilePredicate(subExpr[i]);
                    }
                    this.compiler.nestingLevel--;
                }
            }
示例#28
0
        internal void AddBooleanExpression(XPathExprType boolExprType, XPathExpr expr)
        {
            Fx.Assert(boolExprType == this.type, "");

            // An boolean sub0expression that is of the same type as its container should be merged and flattened
            // into its parent
            if (boolExprType == expr.Type)
            {
                XPathExprList subExprList = expr.SubExpr;
                for (int i = 0; i < subExprList.Count; ++i)
                {
                    this.AddBooleanExpression(boolExprType, subExprList[i]);
                }
            }
            else
            {
                this.Add(expr);
            }
        }
        private XPathStepExpr ParseStep()
        {
            QueryAxisType      axisType = this.ParseAxisSpecifier();
            NodeSelectCriteria desc     = null;
            bool flag = false;

            if (axisType != QueryAxisType.None)
            {
                desc = this.ParseNodeTest(axisType);
            }
            else if (this.NextToken(XPathTokenID.Period) != null)
            {
                desc = new NodeSelectCriteria(QueryAxisType.Self, NodeQName.Empty, QueryNodeType.All);
                flag = true;
            }
            else if (this.NextToken(XPathTokenID.DblPeriod) != null)
            {
                desc = new NodeSelectCriteria(QueryAxisType.Parent, NodeQName.Empty, QueryNodeType.Ancestor);
                flag = true;
            }
            else
            {
                desc = this.ParseNodeTest(QueryAxisType.Child);
                if (desc == null)
                {
                    return(null);
                }
            }
            if (desc == null)
            {
                this.ThrowError(QueryCompileError.InvalidLocationStep);
            }
            XPathExprList predicates = null;

            if (!flag)
            {
                predicates = this.ParsePredicates();
            }
            return(new XPathStepExpr(desc, predicates));
        }
示例#30
0
        bool ParseRelativePath(XPathExprList path)
        {
            Fx.Assert(null != path, "");

            XPathStepExpr step = this.ParseStep();

            if (null == step)
            {
                return(false);
            }

            path.Add(step);
            while (true)
            {
                if (null != this.NextToken(XPathTokenID.Slash))
                {
                    step = this.ParseStep();
                }
                else if (null != this.NextToken(XPathTokenID.DblSlash))
                {
                    step = new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All));
                    path.Add(step);
                    step = this.ParseStep();
                }
                else
                {
                    break;
                }

                if (null == step)
                {
                    this.ThrowError(QueryCompileError.InvalidLocationPath);
                }

                path.Add(step);
            }

            return(true);
        }
 public QueryFunction Bind(string functionName, string functionNamespace, XPathExprList args)
 {
     if ((functionName == "concat") && (args.Count > 4))
     {
         ConcatFunction function = new ConcatFunction(args.Count);
         if (function.Bind(functionName, args))
         {
             return function;
         }
     }
     else
     {
         for (int i = 0; i < functionTable.Length; i++)
         {
             if (functionTable[i].Bind(functionName, args))
             {
                 return functionTable[i];
             }
         }
     }
     return null;
 }
            void CompileFunctionParam(QueryFunction function, XPathExprList paramList, int index)
            {
                XPathExpr param = paramList[index];
                this.CompileExpression(param);
                if (ValueDataType.None != function.ParamTypes[index])
                {
                    if (param.ReturnType != function.ParamTypes[index])
                    {
                        if (function.ParamTypes[index] == ValueDataType.Sequence)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.InvalidTypeConversion));
                        }

                        this.CompileTypecast(function.ParamTypes[index]);
                    }
                }
            }
示例#33
0
        XPathExpr ParseFunctionExpression()
        {
            XPathToken functionToken = this.NextToken(XPathTokenID.Function);

            if (null == functionToken)
            {
                return null;
            }

            NodeQName functionName = this.QualifyName(functionToken.Prefix, functionToken.Name);
            this.NextToken(XPathTokenID.LParen, QueryCompileError.InvalidFunction);

            XPathExprList args = new XPathExprList();

            // Read in arguments
            XPathExpr arg;

            while (null != (arg = this.ParseExpression()))
            {
                args.Add(arg);
                if (null == this.NextToken(XPathTokenID.Comma))
                {
                    break;
                }
            }

            // Bind to the function
            // Try each library until we can bind the function
            XPathExpr functionImpl = null;
            if (null != this.functionLibraries)
            {
                QueryFunction fun = null;
                for (int i = 0; i < this.functionLibraries.Length; ++i)
                {
                    if (null != (fun = this.functionLibraries[i].Bind(functionName.Name, functionName.Namespace, args)))
                    {
                        functionImpl = new XPathFunctionExpr(fun, args);
                        break;
                    }
                }
            }

            // Try to bind using the XsltContext
            if (null == functionImpl && this.context != null)
            {
                XPathResultType[] argTypes = new XPathResultType[args.Count];
                for (int i = 0; i < args.Count; ++i)
                {
                    argTypes[i] = XPathXsltFunctionExpr.ConvertTypeToXslt(args[i].ReturnType);
                }
                string prefix = this.context.LookupPrefix(functionName.Namespace);
                IXsltContextFunction xsltFun = this.context.ResolveFunction(prefix, functionName.Name, argTypes);
                if (xsltFun != null)
                {
                    functionImpl = new XPathXsltFunctionExpr(this.context, xsltFun, args);
                }
            }

            if (null == functionImpl)
            {
                this.ThrowError(QueryCompileError.UnsupportedFunction);
            }

            this.NextToken(XPathTokenID.RParen, QueryCompileError.InvalidFunction);
            return functionImpl;
        }
 internal XPathExpr(XPathExprType type, ValueDataType returnType, XPathExprList subExpr) : this(type, returnType)
 {
     this.subExpr = subExpr;
 }
示例#35
0
        bool ParseRelativePath(XPathExprList path)
        {
            Fx.Assert(null != path, "");

            XPathStepExpr step = this.ParseStep();

            if (null == step)
            {
                return false;
            }

            path.Add(step);
            while (true)
            {
                if (null != this.NextToken(XPathTokenID.Slash))
                {
                    step = this.ParseStep();
                }
                else if (null != this.NextToken(XPathTokenID.DblSlash))
                {
                    step = new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All));
                    path.Add(step);
                    step = this.ParseStep();
                }
                else
                {
                    break;
                }

                if (null == step)
                {
                    this.ThrowError(QueryCompileError.InvalidLocationPath);
                }

                path.Add(step);
            }

            return true;
        }
 private XPathExpr ParseFunctionExpression()
 {
     XPathExpr expr;
     XPathToken token = this.NextToken(XPathTokenID.Function);
     if (token == null)
     {
         return null;
     }
     NodeQName name = this.QualifyName(token.Prefix, token.Name);
     this.NextToken(XPathTokenID.LParen, QueryCompileError.InvalidFunction);
     XPathExprList args = new XPathExprList();
     while ((expr = this.ParseExpression()) != null)
     {
         args.Add(expr);
         if (this.NextToken(XPathTokenID.Comma) == null)
         {
             break;
         }
     }
     XPathExpr expr2 = null;
     if (this.functionLibraries != null)
     {
         QueryFunction function = null;
         for (int i = 0; i < this.functionLibraries.Length; i++)
         {
             function = this.functionLibraries[i].Bind(name.Name, name.Namespace, args);
             if (function != null)
             {
                 expr2 = new XPathFunctionExpr(function, args);
                 break;
             }
         }
     }
     if ((expr2 == null) && (this.context != null))
     {
         XPathResultType[] argTypes = new XPathResultType[args.Count];
         for (int j = 0; j < args.Count; j++)
         {
             argTypes[j] = XPathXsltFunctionExpr.ConvertTypeToXslt(args[j].ReturnType);
         }
         string prefix = this.context.LookupPrefix(name.Namespace);
         IXsltContextFunction function2 = this.context.ResolveFunction(prefix, name.Name, argTypes);
         if (function2 != null)
         {
             expr2 = new XPathXsltFunctionExpr(this.context, function2, args);
         }
     }
     if (expr2 == null)
     {
         this.ThrowError(QueryCompileError.UnsupportedFunction);
     }
     this.NextToken(XPathTokenID.RParen, QueryCompileError.InvalidFunction);
     return expr2;
 }
示例#37
0
        XPathExprList ParseAbsolutePath()
        {
            XPathExprList path = null;
            XPathToken token = this.NextToken();

            if (null != token)
            {
                switch (token.TokenID)
                {
                    default:
                        this.PushToken(token);
                        break;

                    case XPathTokenID.Slash:
                        path = new XPathExprList();
                        path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                        break;

                    case XPathTokenID.DblSlash:
                        // '//' is special. If found at the start of an absolute path, it implies that the descendant-or-self axis
                        // is applied to the ROOT
                        path = new XPathExprList();
                        path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
                        path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
                        break;
                }
            }

            if (null != path)
            {
                this.ParseRelativePath(path);
            }

            return path;
        }
示例#38
0
 internal XPathFunctionExpr(QueryFunction function, XPathExprList subExpr)
     : base(XPathExprType.Function, function.ReturnType, subExpr)
 {
     Fx.Assert(null != function, "");
     this.function = function;
 }
示例#39
0
 internal XPathXsltFunctionExpr(XsltContext context, IXsltContextFunction function, XPathExprList subExpr)
     : base(XPathExprType.XsltFunction, ConvertTypeFromXslt(function.ReturnType), subExpr)
 {
     this.function = function;
     this.context = context;
 }
 private XPathExprList ParsePredicates()
 {
     XPathExprList list = null;
     XPathExpr expr = this.ParsePredicateExpression();
     if (expr != null)
     {
         list = new XPathExprList();
         list.Add(expr);
         while ((expr = this.ParsePredicateExpression()) != null)
         {
             list.Add(expr);
         }
     }
     return list;
 }
 void CompileSteps(XPathExprList steps, bool start)
 {
     for (int i = 0; i < steps.Count; ++i)
     {
         Fx.Assert(XPathExprType.PathStep == steps[i].Type, "");
         XPathStepExpr step = (XPathStepExpr)steps[i];
         if (!step.SelectDesc.Axis.IsSupported())
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.UnsupportedAxis));
         }
         Opcode stepOpcode = null;
         if (start && 0 == i)
         {
             // First steps
             // Is this an absolute path? We have an absolute path if the first step selects the root
             if (QueryNodeType.Root == step.SelectDesc.Type)
             {
                 stepOpcode = new SelectRootOpcode();
             }
             else
             {
                 stepOpcode = new InitialSelectOpcode(step.SelectDesc);
             }
         }
         else
         {
             Fx.Assert(QueryNodeType.Root != step.SelectDesc.Type, "");
             stepOpcode = new SelectOpcode(step.SelectDesc);
         }
         this.codeBlock.Append(stepOpcode);
         // The step may have predicates..
         if (step.SubExprCount > 0)
         {
             this.compiler.nestingLevel++;
             if (this.compiler.nestingLevel > 3) // throw if we find something deepter than [ [ ] ]
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.PredicateNestingTooDeep));
             }
             this.CompilePredicates(step.SubExpr);
             this.compiler.nestingLevel--;
         }
     }
 }
 void CompilePredicates(XPathExprList exprList)
 {
     // Compile each predicate expression first
     for (int i = 0; i < exprList.Count; ++i)
     {
         this.CompilePredicate(exprList[i]);
     }
 }
 private void CompilePredicates(XPathExprList exprList)
 {
     for (int i = 0; i < exprList.Count; i++)
     {
         this.CompilePredicate(exprList[i]);
     }
 }
 private void CompileSteps(XPathExprList steps)
 {
     this.CompileSteps(steps, true);
 }
 private void CompileSteps(XPathExprList steps, bool start)
 {
     for (int i = 0; i < steps.Count; i++)
     {
         XPathStepExpr expr = (XPathStepExpr) steps[i];
         if (!expr.SelectDesc.Axis.IsSupported())
         {
             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.UnsupportedAxis));
         }
         Opcode opcode = null;
         if (start && (i == 0))
         {
             if (QueryNodeType.Root == expr.SelectDesc.Type)
             {
                 opcode = new SelectRootOpcode();
             }
             else
             {
                 opcode = new InitialSelectOpcode(expr.SelectDesc);
             }
         }
         else
         {
             opcode = new SelectOpcode(expr.SelectDesc);
         }
         this.codeBlock.Append(opcode);
         if (expr.SubExprCount > 0)
         {
             this.compiler.nestingLevel++;
             if (this.compiler.nestingLevel > 3)
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new QueryCompileException(QueryCompileError.PredicateNestingTooDeep));
             }
             this.CompilePredicates(expr.SubExpr);
             this.compiler.nestingLevel--;
         }
     }
 }
 void CompileSteps(XPathExprList steps)
 {
     CompileSteps(steps, true);
 }
 internal XPathStepExpr(NodeSelectCriteria desc, XPathExprList predicates) : base(XPathExprType.PathStep, ValueDataType.Sequence, predicates)
 {
     this.selectDesc = desc;
 }
 internal XPathFunctionExpr(QueryFunction function, XPathExprList subExpr) : base(XPathExprType.Function, function.ReturnType, subExpr)
 {
     this.function = function;
 }
        internal bool Bind(string name, XPathExprList args)
        {
            Fx.Assert(null != name && null != args, "");

            if (
                0 != string.CompareOrdinal(this.name, name)
                || this.paramTypes.Length != args.Count
                )
            {
                return false;
            }

            return (this.paramTypes.Length == args.Count);
        }
 private bool ParseRelativePath(XPathExprList path)
 {
     XPathStepExpr expr = this.ParseStep();
     if (expr == null)
     {
         return false;
     }
     path.Add(expr);
     while (true)
     {
         if (this.NextToken(XPathTokenID.Slash) != null)
         {
             expr = this.ParseStep();
         }
         else
         {
             if (this.NextToken(XPathTokenID.DblSlash) == null)
             {
                 return true;
             }
             expr = new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All));
             path.Add(expr);
             expr = this.ParseStep();
         }
         if (expr == null)
         {
             this.ThrowError(QueryCompileError.InvalidLocationPath);
         }
         path.Add(expr);
     }
 }
        public QueryFunction Bind(string functionName, string functionNamespace, XPathExprList args)
        {
            Fx.Assert(null != functionName && null != args, "");

            // Variable length argument list requires a special case here
            if (functionName == "concat" && args.Count > 4)
            {
                ConcatFunction f = new ConcatFunction(args.Count);
                if (f.Bind(functionName, args))
                {
                    return f;
                }
            }
            else
            {
                for (int i = 0; i < XPathFunctionLibrary.functionTable.Length; ++i)
                {
                    // XPath functions are typeless, so don't check types
                    if (XPathFunctionLibrary.functionTable[i].Bind(functionName, args))
                    {
                        return XPathFunctionLibrary.functionTable[i];
                    }
                }
            }

            return null;
        }
示例#52
0
        XPathExprList ParsePredicates()
        {
            XPathExprList predicates = null;
            XPathExpr predicate = this.ParsePredicateExpression();

            if (null != predicate)
            {
                predicates = new XPathExprList();
                predicates.Add(predicate);
                while (null != (predicate = this.ParsePredicateExpression()))
                {
                    predicates.Add(predicate);
                }
            }

            return predicates;
        }
 internal bool Bind(string name, XPathExprList args)
 {
     return (((string.CompareOrdinal(this.name, name) == 0) && (this.paramTypes.Length == args.Count)) && (this.paramTypes.Length == args.Count));
 }
示例#54
0
        XPathExprList ParseRelativePath()
        {
            XPathExprList path = new XPathExprList();

            if (this.ParseRelativePath(path))
            {
                return path;
            }

            return null;
        }
 private XPathExprList ParseAbsolutePath()
 {
     XPathExprList path = null;
     XPathToken token = this.NextToken();
     if (token != null)
     {
         XPathTokenID tokenID = token.TokenID;
         if (tokenID == XPathTokenID.Slash)
         {
             path = new XPathExprList();
             path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
         }
         else if (tokenID == XPathTokenID.DblSlash)
         {
             path = new XPathExprList();
             path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root)));
             path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All)));
         }
         else
         {
             this.PushToken(token);
         }
     }
     if (path != null)
     {
         this.ParseRelativePath(path);
     }
     return path;
 }