The CQR implementation of QilExpression.

QilExpression is the XML Query Intermediate Language invented by Michael Brundage and Chris Suver. QilExpression is an intermediate representation (IR) for all XML query and view languages. QilExpression is designed for optimization, composition with virtual XML views, translation into other forms, and direct execution. See also the QIL specification.

Inheritance: QilNode
コード例 #1
0
 /// <summary>
 /// This function is called on every recompilation to discard all previous results
 /// </summary>
 private void Reset()
 {
     _compilerErrorColl = null;
     _outputSettings = null;
     _qil = null;
     _command = null;
 }
コード例 #2
0
ファイル: XmlIlVisitor.cs プロジェクト: Corillian/corefx
        //-----------------------------------------------
        // Entry
        //-----------------------------------------------

        /// <summary>
        /// Visits the specified QilExpression graph and generates MSIL code.
        /// </summary>
        public void Visit(QilExpression qil, GenerateHelper helper, MethodInfo methRoot)
        {
            _qil = qil;
            _helper = helper;
            _iterNested = null;
            _indexId = 0;

            // Prepare each global parameter and global variable to be visited
            PrepareGlobalValues(qil.GlobalParameterList);
            PrepareGlobalValues(qil.GlobalVariableList);

            // Visit each global parameter and global variable
            VisitGlobalValues(qil.GlobalParameterList);
            VisitGlobalValues(qil.GlobalVariableList);

            // Build each function
            foreach (QilFunction ndFunc in qil.FunctionList)
            {
                // Visit each parameter and the function body
                Function(ndFunc);
            }

            // Build the root expression
            _helper.MethodBegin(methRoot, null, true);
            StartNestedIterator(qil.Root);
            Visit(qil.Root);
            Debug.Assert(_iterCurr.Storage.Location == ItemLocation.None, "Root expression should have been pushed to the writer.");
            EndNestedIterator(qil.Root);
            _helper.MethodEnd();
        }
コード例 #3
0
ファイル: XslCompiledTransform.cs プロジェクト: shmao/corefx
 /// <summary>
 /// This function is called on every recompilation to discard all previous results
 /// </summary>
 private void Reset()
 {
     _compilerResults = null;
     _outputSettings = null;
     _qil = null;
     _command = null;
 }
コード例 #4
0
 public XmlILOptimizerVisitor(QilExpression qil, bool optimize) : base(optimize ? s_patternsOpt : s_patternsNoOpt, qil.Factory)
 {
     _qil = qil;
     _elemAnalyzer = new XmlILElementAnalyzer(qil.Factory);
     _contentAnalyzer = new XmlILStateAnalyzer(qil.Factory);
     _nmspAnalyzer = new XmlILNamespaceAnalyzer();
 }
コード例 #5
0
ファイル: QilFactory.cs プロジェクト: geoffkizer/corefx
        //-----------------------------------------------
        // 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;
        }
コード例 #6
0
        /// <summary>
        /// Scan through the external parameters, global variables, and function list for forward references.
        /// </summary>
        protected override QilNode VisitQilExpression(QilExpression qil)
        {
            IList <QilNode> fdecls = new ForwardRefFinder().Find(qil);

            if (fdecls != null && fdecls.Count > 0)
            {
                this.writer.WriteStartElement("ForwardDecls");
                foreach (QilNode n in fdecls)
                {
                    // i.e. <Function id="$a"/>
                    this.writer.WriteStartElement(Enum.GetName(typeof(QilNodeType), n.NodeType));
                    this.writer.WriteAttributeString("id", _ngen.NameOf(n));
                    WriteXmlType(n);

                    if (n.NodeType == QilNodeType.Function)
                    {
                        // Visit Arguments and SideEffects operands
                        Visit(n[0]);
                        Visit(n[2]);
                    }

                    this.writer.WriteEndElement();
                }
                this.writer.WriteEndElement();
            }

            return(VisitChildren(qil));
        }
コード例 #7
0
        //-----------------------------------------------
        // meta
        //-----------------------------------------------
        public QilExpression QilExpression(QilNode root)
        {
            QilExpression n = new QilExpression(QilNodeType.QilExpression, root);

            n.XmlType = _typeCheck.CheckQilExpression(n);
            TraceNode(n);
            return(n);
        }
コード例 #8
0
 /// <summary>
 /// Perform tail-call analysis on the functions in the specified QilExpression.
 /// </summary>
 public static void Analyze(QilExpression qil) {
     foreach (QilFunction ndFunc in qil.FunctionList) {
         // Only analyze functions which are pushed to the writer, since otherwise code
         // is generated after the call instruction in order to process cached results
         if (XmlILConstructInfo.Read(ndFunc).ConstructMethod == XmlILConstructMethod.Writer)
             AnalyzeDefinition(ndFunc.Definition);
     }
 }
コード例 #9
0
        //-----------------------------------------------
        // Convenience methods
        //-----------------------------------------------

        public QilExpression QilExpression(QilNode root, QilFactory factory)
        {
            QilExpression n = new QilExpression(QilNodeType.QilExpression, root, factory);

            n.XmlType = this.typeCheck.CheckQilExpression(n);
            TraceNode(n);
            return(n);
        }
コード例 #10
0
 //-----------------------------------------------
 // meta
 //-----------------------------------------------
 public XmlQueryType CheckQilExpression(QilExpression node)
 {
     Check(node[0].NodeType == QilNodeType.False || node[0].NodeType == QilNodeType.True, node, "IsDebug must either be True or False");
     CheckLiteralValue(node[1], typeof(XmlWriterSettings));
     CheckLiteralValue(node[2], typeof(IList <WhitespaceRule>));
     CheckClassAndNodeType(node[3], typeof(QilList), QilNodeType.GlobalParameterList);
     CheckClassAndNodeType(node[4], typeof(QilList), QilNodeType.GlobalVariableList);
     CheckClassAndNodeType(node[5], typeof(QilList), QilNodeType.FunctionList);
     return(XmlQueryTypeFactory.ItemS);
 }
コード例 #11
0
ファイル: XmlIlGenerator.cs プロジェクト: Corillian/corefx
        /// <summary>
        /// Given the logical query plan (QilExpression) generate a physical query plan (MSIL) that can be executed.
        /// </summary>
        // SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are
        // created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail 
        // builds. As a result it is fine to suppress the FxCop SxS warning.
        public XmlILCommand Generate(QilExpression query, TypeBuilder typeBldr)
        {
            _qil = query;

            bool useLRE = (
                !_qil.IsDebug &&
                (typeBldr == null)
#if DEBUG
                && !XmlILTrace.IsEnabled // Dump assembly to disk; can't do this when using LRE
#endif
            );
            bool emitSymbols = _qil.IsDebug;

            // In debug code, ensure that input QIL is correct
            QilValidationVisitor.Validate(_qil);

#if DEBUG
            // Trace Qil before optimization
            XmlILTrace.WriteQil(this.qil, "qilbefore.xml");

            // Trace optimizations
            XmlILTrace.TraceOptimizations(this.qil, "qilopt.xml");
#endif

            // Optimize and annotate the Qil graph
            _optVisitor = new XmlILOptimizerVisitor(_qil, !_qil.IsDebug);
            _qil = _optVisitor.Optimize();

            // In debug code, ensure that output QIL is correct
            QilValidationVisitor.Validate(_qil);

#if DEBUG
            // Trace Qil after optimization
            XmlILTrace.WriteQil(this.qil, "qilafter.xml");
#endif

            // Create module in which methods will be generated
            if (typeBldr != null)
            {
                _module = new XmlILModule(typeBldr);
            }
            else
            {
                _module = new XmlILModule(useLRE, emitSymbols);
            }

            // Create a code generation helper for the module; enable optimizations if IsDebug is false
            _helper = new GenerateHelper(_module, _qil.IsDebug);

            // Create helper methods
            CreateHelperFunctions();

            // Create metadata for the Execute function, which is the entry point to the query
            // public static void Execute(XmlQueryRuntime);
            MethodInfo methExec = _module.DefineMethod("Execute", typeof(void), new Type[] { }, new string[] { }, XmlILMethodAttributes.NonUser);

            // Create metadata for the root expression
            // public void Root()
            Debug.Assert(_qil.Root != null);
            XmlILMethodAttributes methAttrs = (_qil.Root.SourceLine == null) ? XmlILMethodAttributes.NonUser : XmlILMethodAttributes.None;
            MethodInfo methRoot = _module.DefineMethod("Root", typeof(void), new Type[] { }, new string[] { }, methAttrs);

            // Declare all early bound function objects
            foreach (EarlyBoundInfo info in _qil.EarlyBoundTypes)
            {
                _helper.StaticData.DeclareEarlyBound(info.NamespaceUri, info.EarlyBoundType);
            }

            // Create metadata for each QilExpression function that has at least one caller
            CreateFunctionMetadata(_qil.FunctionList);

            // Create metadata for each QilExpression global variable and parameter
            CreateGlobalValueMetadata(_qil.GlobalVariableList);
            CreateGlobalValueMetadata(_qil.GlobalParameterList);

            // Generate Execute method
            GenerateExecuteFunction(methExec, methRoot);

            // Visit the QilExpression graph
            _xmlIlVisitor = new XmlILVisitor();
            _xmlIlVisitor.Visit(_qil, _helper, methRoot);

            // Collect all static information required by the runtime
            XmlQueryStaticData staticData = new XmlQueryStaticData(
                _qil.DefaultWriterSettings,
                _qil.WhitespaceRules,
                _helper.StaticData
            );

            // Create static constructor that initializes XmlQueryStaticData instance at runtime
            if (typeBldr != null)
            {
                CreateTypeInitializer(staticData);

                // Finish up creation of the type
                _module.BakeMethods();

                return null;
            }
            else
            {
                // Finish up creation of the type
                _module.BakeMethods();

                // Create delegate over "Execute" method
                ExecuteDelegate delExec = (ExecuteDelegate)_module.CreateDelegate("Execute", typeof(ExecuteDelegate));
                return new XmlILCommand(delExec, staticData);
            }
        }
コード例 #12
0
 // Do not edit this region
 #region AUTOGENERATED
 #region meta
 protected override QilNode VisitQilExpression(QilExpression n) { return NoReplace(n); }
コード例 #13
0
 //-----------------------------------------------
 // meta
 //-----------------------------------------------
 public QilExpression QilExpression(QilNode root) {
     QilExpression n = new QilExpression(QilNodeType.QilExpression, root);
     n.XmlType = this.typeCheck.CheckQilExpression(n);
     TraceNode(n);
     return n;
 }
コード例 #14
0
 protected virtual QilNode VisitQilExpression(QilExpression n) { return VisitChildren(n); }
コード例 #15
0
 /// <summary>
 /// Serialize rewritten Qil tree to writer "w".
 /// </summary>
 private static void WriteQilRewrite(QilExpression qil, XmlWriter w, string rewriteName) {
     w.WriteStartElement("Diff");
     if (rewriteName != null)
         w.WriteAttributeString("rewrite", rewriteName);
     WriteQil(qil, w);
     w.WriteEndElement();
 }
コード例 #16
0
 public XmlILOptimizerVisitor(QilExpression qil, bool optimize) : base(optimize ? PatternsOpt : PatternsNoOpt, qil.Factory) {
     this.qil = qil;
     this.elemAnalyzer = new XmlILElementAnalyzer(qil.Factory);
     this.contentAnalyzer = new XmlILStateAnalyzer(qil.Factory);
     this.nmspAnalyzer = new XmlILNamespaceAnalyzer();
 }
コード例 #17
0
        // Do not edit this region
        // It is auto-generated
        #region AUTOGENERATED

        #region meta
        protected override QilNode VisitQilExpression(QilExpression local0) {
            QilNode local1 = local0[0];
            if (this[XmlILOptimization.EliminateUnusedFunctions]) {
                if (AllowReplace(XmlILOptimization.EliminateUnusedFunctions, local0)) {
                    
    IList<QilNode> funcList = local0.FunctionList;
    for (int i = funcList.Count - 1; i >= 0; i--) {
        if (XmlILConstructInfo.Write(funcList[i]).CallersInfo.Count == 0)
            funcList.RemoveAt(i);
    }
}
            }
            if (this[XmlILOptimization.AnnotateConstruction]) {
                if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0)) {
                    
    foreach (QilFunction ndFunc in local0.FunctionList) {
        // Functions that construct Xml trees should stream output to writer; otherwise, results should
        // be cached and returned.
        if (IsConstructedExpression(ndFunc.Definition)) {
            // Perform state analysis on function's content
            ndFunc.Definition = this.contentAnalyzer.Analyze(ndFunc, ndFunc.Definition);
        }
    }

    // Perform state analysis on the root expression
    local0.Root = this.contentAnalyzer.Analyze(null, local0.Root);

    // Make sure that root expression is pushed to writer
    XmlILConstructInfo.Write(local0.Root).PushToWriterLast = true;
}
            }
            return NoReplace(local0);
        }
コード例 #18
0
        /// <summary>
        /// Given the logical query plan (QilExpression) generate a physical query plan (MSIL) that can be executed.
        /// </summary>
        public XmlCommand Generate(QilExpression query, AssemblyName asmName) {
            MethodInfo methRoot, methExec;
            bool useLRE, emitSymbols;
            ExecuteDelegate delExec;
            XmlILMethodAttributes methAttrs;

            this.qil = query;

            useLRE = !this.qil.IsDebug && (asmName == null);
            emitSymbols = this.qil.IsDebug;

            // In debug code, ensure that input QIL is correct
            QilValidationVisitor.Validate(this.qil);

            // Trace Qil before optimization
            XmlILTrace.WriteQil(this.qil, "qilbefore.xml");

            // Trace optimizations
            XmlILTrace.TraceOptimizations(this.qil, "qilopt.xml");

            if (XmlILTrace.IsEnabled) {
                // Dump assembly to disk; can't do this when using LRE
                useLRE = false;
            }

            // Optimize and annotate the Qil graph
            this.optVisitor = new XmlILOptimizerVisitor(this.qil, !this.qil.IsDebug);
            this.qil = this.optVisitor.Optimize();

            // In debug code, ensure that output QIL is correct
            QilValidationVisitor.Validate(this.qil);

            // Trace Qil after optimization
            XmlILTrace.WriteQil(this.qil, "qilafter.xml");

            // Create module in which methods will be generated
            this.module = new XmlILModule(useLRE, emitSymbols, asmName);

            // Create a code generation helper for the module; enable optimizations if IsDebug is false
            this.helper = new GenerateHelper(this.module, this.qil.IsDebug);

            // Create helper methods
            CreateHelperFunctions();

            // Create metadata for the root expression
            // public void Root()
            Debug.Assert(this.qil.Root != null);
            methAttrs = (this.qil.Root.SourceLine == null) ? XmlILMethodAttributes.NonUser : XmlILMethodAttributes.None;
            methRoot = this.module.DefineMethod("Root", typeof(void), new Type[] {}, new string[] {}, methAttrs);

            // Create metadata for each QilExpression function that has at least one caller
            CreateFunctionMetadata(this.qil.FunctionList);

            // Create metadata for each QilExpression global variable and parameter
            CreateGlobalValueMetadata(this.qil.GlobalVariableList);
            CreateGlobalValueMetadata(this.qil.GlobalParameterList);

            // Create Execute method
            methExec = CreateExecuteFunction(methRoot);

            // Visit the QilExpression graph
            this.xmlIlVisitor = new XmlILVisitor();
            this.xmlIlVisitor.Visit(this.qil, this.helper, methRoot);

            this.module.BakeMethods();

            // Create delegate over "Execute" method
            delExec = (ExecuteDelegate) this.module.CreateDelegate("Execute", typeof(ExecuteDelegate));

            return new XmlILCommand(delExec, this.qil, this.helper.StaticData);
        }
コード例 #19
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public XmlILCommand(ExecuteDelegate delExec, QilExpression qil, StaticDataManager staticData) {
     Debug.Assert(qil != null);
     this.delExec = delExec;
     this.defaultWriterSettings = qil.DefaultWriterSettings;
     this.wsRules = qil.WhitespaceRules;
     this.names = staticData.Names;
     this.prefixMappingsList = staticData.PrefixMappingsList;
     this.filters = staticData.NameFilters;
     this.types = staticData.XmlTypes;
     this.collations = staticData.Collations;
     this.globalNames = staticData.GlobalNames;
     this.earlyInfo = staticData.EarlyBound;
 }
コード例 #20
0
 private void CompileIlFromQil(XsltSettings settings) {
     command = new XmlILGenerator().Generate(qil, settings.AssemblyName);
     // Set outputSettings only if compilation was successful
     outputSettings = qil.DefaultWriterSettings;
     qil = null;
 }
コード例 #21
0
        public static void TraceOptimizations(QilExpression qil, string fileName) {
            if (!IsEnabled)
                return;

            XmlWriter w = XmlWriter.Create(dirName + "\\" + fileName);

            w.WriteStartDocument();
            w.WriteProcessingInstruction("xml-stylesheet", "href='qilo.xslt' type='text/xsl'");
            w.WriteStartElement("QilOptimizer");
            w.WriteAttributeString("timestamp", DateTime.Now.ToString(CultureInfo.InvariantCulture));
            WriteQilRewrite(qil, w, null);

            try {
                // Then, rewrite the graph until "done" or some max value is reached.
                for (int i = 1; i < MAX_REWRITES; i++) {
                    QilExpression qilTemp = (QilExpression) (new QilCloneVisitor(qil.Factory).Clone(qil));

                    XmlILOptimizerVisitor visitor = new XmlILOptimizerVisitor(qilTemp, !qilTemp.IsDebug);
                    visitor.Threshold = i;
                    qilTemp = visitor.Optimize();

                    // In debug code, ensure that QIL after N steps is correct
                    QilValidationVisitor.Validate(qilTemp);

                    // Trace the rewrite
                    WriteQilRewrite(qilTemp, w, OptimizationToString(visitor.LastReplacement));

                    if (visitor.ReplacementCount < i)
                        break;
                }
            }
            catch (Exception e) {
                if (!XmlException.IsCatchableException(e)) {
                    throw;
                }
                w.WriteElementString("Exception", null, e.ToString());
                throw;
            }
            finally {
                w.WriteEndElement();
                w.WriteEndDocument();
                w.Flush();
                w.Close();
            }
        }
コード例 #22
0
 public IList <QilNode> Find(QilExpression qil)
 {
     Visit(qil);
     return(_fwdrefs);
 }
コード例 #23
0
 /// <summary>
 /// Serialize Qil tree to writer "w".
 /// </summary>
 private static void WriteQil(QilExpression qil, XmlWriter w) {
     QilXmlWriter qw = new QilXmlWriter(w);
     qw.ToXml(qil);
 }
コード例 #24
0
        // Do not edit this region
        // It is auto-generated
        #region AUTOGENERATED

        #region meta
        protected override QilNode VisitQilExpression(QilExpression local0)
        {
            QilNode local1 = local0[0];
            if (this[XmlILOptimization.EliminateUnusedGlobals])
            {
                // PATTERN: [EliminateUnusedGlobals] $qil:(QilExpression *) => { ... }
                if (AllowReplace(XmlILOptimization.EliminateUnusedGlobals, local0))
                {
                    EliminateUnusedGlobals(local0.GlobalVariableList);
                    EliminateUnusedGlobals(local0.GlobalParameterList);
                    EliminateUnusedGlobals(local0.FunctionList);
                }
            }
            if (this[XmlILOptimization.AnnotateConstruction])
            {
                // PATTERN: [AnnotateConstruction] $qil:(QilExpression *) => { ... }
                if (AllowReplace(XmlILOptimization.AnnotateConstruction, local0))
                {
                    foreach (QilFunction ndFunc in local0.FunctionList)
                    {
                        // Functions that construct Xml trees should stream output to writer; otherwise, results should
                        // be cached and returned.
                        if (IsConstructedExpression(ndFunc.Definition))
                        {
                            // Perform state analysis on function's content
                            ndFunc.Definition = _contentAnalyzer.Analyze(ndFunc, ndFunc.Definition);
                        }
                    }

                    // Perform state analysis on the root expression
                    local0.Root = _contentAnalyzer.Analyze(null, local0.Root);

                    // Make sure that root expression is pushed to writer
                    XmlILConstructInfo.Write(local0.Root).PushToWriterLast = true;
                }
            }
            return NoReplace(local0);
        }
コード例 #25
0
        public static void WriteQil(QilExpression qil, string fileName) {
            if (!IsEnabled)
                return;

            XmlWriter w = XmlWriter.Create(dirName + "\\" + fileName);
            try {
                WriteQil(qil, w);
            }
            finally {
                w.Close();
            }
        }
コード例 #26
0
 /// <summary>
 /// This function is called on every recompilation to discard all previous results
 /// </summary>
 private void Reset() {
     this.compilerResults = null;
     this.outputSettings  = null;
     this.qil             = null;
     this.command         = null;
 }
コード例 #27
0
 //-----------------------------------------------
 // meta
 //-----------------------------------------------
 public XmlQueryType CheckQilExpression(QilExpression node) {
     Check(node[0].NodeType == QilNodeType.False || node[0].NodeType == QilNodeType.True, node, "IsDebug must either be True or False");
     CheckLiteralValue(node[1], typeof(XmlWriterSettings));
     CheckLiteralValue(node[2], typeof(IList<WhitespaceRule>));
     CheckClassAndNodeType(node[3], typeof(QilList), QilNodeType.GlobalParameterList);
     CheckClassAndNodeType(node[4], typeof(QilList), QilNodeType.GlobalVariableList);
     CheckLiteralValue(node[5], typeof(IList<EarlyBoundInfo>));
     CheckClassAndNodeType(node[6], typeof(QilList), QilNodeType.FunctionList);
     return XmlQueryTypeFactory.ItemS;
 }
コード例 #28
0
 protected override QilNode VisitQilExpression(QilExpression n)
 {
     return(NoReplace(n));
 }
コード例 #29
0
        private void EndElement()
        {
            MethodInfo facMethod = null;

            object[]         facArgs;
            QilList          list;
            QilNode          nd;
            ReaderAnnotation ann;

            list = this.stk.Pop();
            ann  = (ReaderAnnotation)list.Annotation;

            // Special case certain element names
            string s = r.LocalName;

            switch (r.LocalName)
            {
            case "QilExpression": {
                Debug.Assert(list.Count > 0, "QilExpression node requires a Root expression");
                QilExpression qil = f.QilExpression(list[list.Count - 1]);

                // Be flexible on order and presence of QilExpression children
                for (int i = 0; i < list.Count - 1; i++)
                {
                    switch (list[i].NodeType)
                    {
                    case QilNodeType.True:
                    case QilNodeType.False:
                        qil.IsDebug = list[i].NodeType == QilNodeType.True;
                        break;

                    case QilNodeType.FunctionList:
                        qil.FunctionList = (QilList)list[i];
                        break;

                    case QilNodeType.GlobalVariableList:
                        qil.GlobalVariableList = (QilList)list[i];
                        break;

                    case QilNodeType.GlobalParameterList:
                        qil.GlobalParameterList = (QilList)list[i];
                        break;
                    }
                }
                nd = qil;
                break;
            }

            case "ForwardDecls":
                this.inFwdDecls = false;
                return;

            case "Parameter":
            case "Let":
            case "For":
            case "Function": {
                string  id   = ann.Id;
                QilName name = ann.Name;
                Debug.Assert(id != null, r.LocalName + " must have an id attribute");
                Debug.Assert(!this.inFwdDecls || ann.XmlType != null, "Forward decl for " + r.LocalName + " '" + id + "' must have an xmlType attribute");

                // Create node (may be discarded later if it was already declared in forward declarations section)
                switch (r.LocalName)
                {
                case "Parameter":
                    Debug.Assert(list.Count <= (this.inFwdDecls ? 0 : 1), "Parameter '" + id + "' must have 0 or 1 arguments");
                    Debug.Assert(ann.XmlType != null, "Parameter '" + id + "' must have an xmlType attribute");
                    if (this.inFwdDecls || list.Count == 0)
                    {
                        nd = f.Parameter(null, name, ann.XmlType);
                    }
                    else
                    {
                        nd = f.Parameter(list[0], name, ann.XmlType);
                    }
                    break;

                case "Let":
                    Debug.Assert(list.Count == (this.inFwdDecls ? 0 : 1), "Let '" + id + "' must have 0 or 1 arguments");
                    if (this.inFwdDecls)
                    {
                        nd = f.Let(f.Unknown(ann.XmlType));
                    }
                    else
                    {
                        nd = f.Let(list[0]);
                    }
                    break;

                case "For":
                    Debug.Assert(list.Count == 1, "For '" + id + "' must have 1 argument");
                    nd = f.For(list[0]);
                    break;

                default:
                    Debug.Assert(list.Count == (this.inFwdDecls ? 2 : 3), "Function '" + id + "' must have 2 or 3 arguments");
                    if (this.inFwdDecls)
                    {
                        nd = f.Function(list[0], list[1], ann.XmlType);
                    }
                    else
                    {
                        nd = f.Function(list[0], list[1], list[2], ann.XmlType != null ? ann.XmlType : list[1].XmlType);
                    }
                    break;
                }

                // Set DebugName
                if (name != null)
                {
                    ((QilReference)nd).DebugName = name.ToString();
                }

                if (this.inFwdDecls)
                {
                    Debug.Assert(!this.scope.ContainsKey(id), "Multiple nodes have id '" + id + "'");
                    this.fwdDecls[id] = nd;
                    this.scope[id]    = nd;
                }
                else
                {
                    if (this.fwdDecls.ContainsKey(id))
                    {
                        // Replace forward declaration
                        Debug.Assert(r.LocalName == Enum.GetName(typeof(QilNodeType), nd.NodeType), "Id '" + id + "' is not not bound to a " + r.LocalName + " forward decl");
                        nd = this.fwdDecls[id];
                        this.fwdDecls.Remove(id);

                        if (list.Count > 0)
                        {
                            nd[0] = list[0];
                        }
                        if (list.Count > 1)
                        {
                            nd[1] = list[1];
                        }
                    }
                    else
                    {
                        // Put reference in scope
                        Debug.Assert(!this.scope.ContainsKey(id), "Id '" + id + "' is already in scope");
                        this.scope[id] = nd;
                    }
                }
                nd.Annotation = ann;
                break;
            }

            case "RefTo": {
                // Lookup reference
                string id = ann.Id;
                Debug.Assert(id != null, r.LocalName + " must have an id attribute");

                Debug.Assert(this.scope.ContainsKey(id), "Id '" + id + "' is not in scope");
                this.stk.Peek().Add(this.scope[id]);
                return;
            }

            case "Sequence":
                nd = f.Sequence(list);
                break;

            case "FunctionList":
                nd = f.FunctionList(list);
                break;

            case "GlobalVariableList":
                nd = f.GlobalVariableList(list);
                break;

            case "GlobalParameterList":
                nd = f.GlobalParameterList(list);
                break;

            case "ActualParameterList":
                nd = f.ActualParameterList(list);
                break;

            case "FormalParameterList":
                nd = f.FormalParameterList(list);
                break;

            case "SortKeyList":
                nd = f.SortKeyList(list);
                break;

            case "BranchList":
                nd = f.BranchList(list);
                break;

            case "XsltInvokeEarlyBound": {
                Debug.Assert(ann.ClrNamespace != null, "XsltInvokeEarlyBound must have a clrNamespace attribute");
                Debug.Assert(list.Count == 2, "XsltInvokeEarlyBound must have exactly 2 arguments");
                Debug.Assert(list.XmlType != null, "XsltInvokeEarlyBound must have an xmlType attribute");
                MethodInfo mi   = null;
                QilName    name = (QilName)list[0];

                foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
                {
                    Type t = asm.GetType(ann.ClrNamespace);
                    if (t != null)
                    {
                        mi = t.GetMethod(name.LocalName);
                        break;
                    }
                }

                Debug.Assert(mi != null, "Cannot find method " + ann.ClrNamespace + "." + name.ToString());

                nd = f.XsltInvokeEarlyBound(name, f.LiteralObject(mi), list[1], ann.XmlType);
                break;
            }

            default: {
                // Find factory method which will be used to construct the Qil node
                Debug.Assert(nameToFactoryMethod.ContainsKey(r.LocalName), "Method " + r.LocalName + " could not be found on QilFactory");
                facMethod = nameToFactoryMethod[r.LocalName];
                Debug.Assert(facMethod.GetParameters().Length == list.Count, "NodeType " + r.LocalName + " does not allow " + list.Count + " parameters");

                // Create factory method arguments
                facArgs = new object[list.Count];
                for (int i = 0; i < facArgs.Length; i++)
                {
                    facArgs[i] = list[i];
                }

                // Create node and set its properties
                nd = (QilNode)facMethod.Invoke(f, facArgs);
                break;
            }
            }

            nd.SourceLine = list.SourceLine;

            // Add node to its parent's list
            this.stk.Peek().Add(nd);
        }
コード例 #30
0
 /// <summary>
 /// This function is called on every recompilation to discard all previous results
 /// </summary>
 private void Reset() {
     compilerResults = null;
     outputSettings  = null;
     qil             = null;
     command         = null;
 }
コード例 #31
0
 protected virtual QilNode VisitQilExpression(QilExpression n)
 {
     return(VisitChildren(n));
 }
コード例 #32
0
 private void CompileQilToMsil(XsltSettings settings) {
     this.command = new XmlILGenerator().Generate(this.qil, /*typeBuilder:*/null);
     this.outputSettings = this.command.StaticData.DefaultWriterSettings;
     this.qil = null;
 }