Check() public method

public Check ( QilNode n ) : XmlQueryType
n QilNode
return XmlQueryType
Exemplo n.º 1
0
        //-----------------------------------------------
        // 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 = QilTypeChecker.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;
        }
        //-----------------------------------------------
        // 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 = _typeCheck.Check(parent);

                    // BUGBUG: Hack to account for Xslt compiler type fixups
                    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);
        }