System.Xml.Xsl.Xslt.QilGenerator.PrecompileProtoTemplatesHeaders C# (CSharp) Méthode

PrecompileProtoTemplatesHeaders() private méthode

private PrecompileProtoTemplatesHeaders ( ) : void
Résultat void
        private void PrecompileProtoTemplatesHeaders()
        {
            // All global variables should be in scoupe here.
            List<VarPar> paramWithCalls = null;
            Dictionary<VarPar, Template> paramToTemplate = null;
            Dictionary<VarPar, QilFunction> paramToFunction = null;

            foreach (ProtoTemplate tmpl in _compiler.AllTemplates)
            {
                Debug.Assert(tmpl != null && tmpl.Function == null);
                Debug.Assert(tmpl.NodeType == XslNodeType.AttributeSet || tmpl.NodeType == XslNodeType.Template);
                QilList args = _f.FormalParameterList();
                XslFlags flags = !IsDebug ? tmpl.Flags : XslFlags.FullFocus;

                QilList nsList = EnterScope(tmpl);
                if ((flags & XslFlags.Current) != 0)
                {
                    args.Add(CreateXslParam(CloneName(_nameCurrent), T.NodeNotRtf));
                }
                if ((flags & XslFlags.Position) != 0)
                {
                    args.Add(CreateXslParam(CloneName(_namePosition), T.DoubleX));
                }
                if ((flags & XslFlags.Last) != 0)
                {
                    args.Add(CreateXslParam(CloneName(_nameLast), T.DoubleX));
                }
                if (IsDebug && nsList != null)
                {
                    // AttributeSet doesn't need this logic because: 1) it doesn't have args; 2) we merge them.
                    // SimplifiedStylesheet has nsList == null as well.
                    QilParameter ns = CreateXslParam(CloneName(_nameNamespaces), T.NamespaceS);
                    ns.DefaultValue = GetNsVar(nsList);
                    args.Add(ns);
                }

                Template template = tmpl as Template;
                if (template != null)
                {
                    Debug.Assert(tmpl.NodeType == XslNodeType.Template);

                    CheckSingletonFocus();
                    _funcFocus.StartFocus(args, flags);
                    for (int i = 0; i < tmpl.Content.Count; i++)
                    {
                        XslNode node = tmpl.Content[i];
                        if (node.NodeType == XslNodeType.Text)
                        {
                            // NOTE: We should take care of a bizarre case when xsl:param comes after TextCtor:
                            // <xsl:template match="/" xml:space="preserve">  <xsl:param name="par"/>
                            continue;
                        }
                        if (node.NodeType == XslNodeType.Param)
                        {
                            VarPar xslPar = (VarPar)node;
                            EnterScope(xslPar);
                            if (_scope.IsLocalVariable(xslPar.Name.LocalName, xslPar.Name.NamespaceUri))
                            {
                                ReportError(/*[XT0580]*/SR.Xslt_DupLocalVariable, xslPar.Name.QualifiedName);
                            }
                            QilParameter param = CreateXslParam(xslPar.Name, ChooseBestType(xslPar));
                            if (IsDebug)
                            {
                                param.Annotation = xslPar;
                                // Actual compilation will happen in CompileProtoTemplate()
                            }
                            else
                            {
                                if ((xslPar.DefValueFlags & XslFlags.HasCalls) == 0)
                                {
                                    param.DefaultValue = CompileVarParValue(xslPar);
                                }
                                else
                                {
                                    // We can't compile param default value here because it contains xsl:call-template and
                                    // we will not be able to compile any calls befor we finish with all headers
                                    // So we compile this default value as a call to helper function. Now we create header for this function
                                    // and preserve this param in paramWithCall list. Later in this function we finaly compile all preserved
                                    // parameters and set resulted default values as helper function definition.
                                    QilList paramFormal = _f.FormalParameterList();
                                    QilList paramActual = _f.ActualParameterList();
                                    for (int j = 0; j < args.Count; j++)
                                    {
                                        QilParameter formal = _f.Parameter(args[j].XmlType);
                                        {
                                            formal.DebugName = ((QilParameter)args[j]).DebugName;
                                            formal.Name = CloneName(((QilParameter)args[j]).Name);
                                            SetLineInfo(formal, args[j].SourceLine);
                                        }
                                        paramFormal.Add(formal);
                                        paramActual.Add(args[j]);
                                    }
                                    // Param doesn't know what implicit args it needs, so we pass all implicit args that was passed to its template.
                                    // let's reflect this fact in parans FocusFlags:
                                    xslPar.Flags |= (template.Flags & XslFlags.FocusFilter);
                                    QilFunction paramFunc = _f.Function(paramFormal,
                                        _f.Boolean((xslPar.DefValueFlags & XslFlags.SideEffects) != 0),
                                        ChooseBestType(xslPar)
                                    );
                                    paramFunc.SourceLine = SourceLineInfo.NoSource;
                                    paramFunc.DebugName = "<xsl:param name=\"" + xslPar.Name.QualifiedName + "\">";
                                    param.DefaultValue = _f.Invoke(paramFunc, paramActual);
                                    // store VarPar here to compile it on next pass:
                                    if (paramWithCalls == null)
                                    {
                                        paramWithCalls = new List<VarPar>();
                                        paramToTemplate = new Dictionary<VarPar, Template>();
                                        paramToFunction = new Dictionary<VarPar, QilFunction>();
                                    }
                                    paramWithCalls.Add(xslPar);
                                    paramToTemplate.Add(xslPar, template);
                                    paramToFunction.Add(xslPar, paramFunc);
                                }
                            }
                            SetLineInfo(param, xslPar.SourceLine);
                            ExitScope();
                            _scope.AddVariable(xslPar.Name, param);
                            args.Add(param);
                        }
                        else
                        {
                            break;
                        }
                    }
                    _funcFocus.StopFocus();
                }
                ExitScope();

                tmpl.Function = _f.Function(args,
                    _f.Boolean((tmpl.Flags & XslFlags.SideEffects) != 0),
                    tmpl is AttributeSet ? T.AttributeS : T.NodeNotRtfS
                );
                tmpl.Function.DebugName = tmpl.GetDebugName();
                Debug.Assert((template != null) == (tmpl.SourceLine != null), "Templates must have line information, and attribute sets must not");
                SetLineInfo(tmpl.Function, tmpl.SourceLine ?? SourceLineInfo.NoSource);
                _functions.Add(tmpl.Function);
            } // foreach (ProtoTemplate tmpl in compiler.AllTemplates)

            // Finish compiling postponed parameters (those having calls in their default values)
            if (paramWithCalls != null)
            {
                Debug.Assert(!IsDebug, "In debug mode we don't generate parumWithCalls functions. Otherwise focus flags should be adjusted");
                foreach (VarPar par in paramWithCalls)
                {
                    Template tmpl = paramToTemplate[par];
                    QilFunction func = paramToFunction[par];
                    CheckSingletonFocus();
                    _funcFocus.StartFocus(func.Arguments, par.Flags);
                    EnterScope(tmpl);
                    EnterScope(par);
                    foreach (QilParameter arg in func.Arguments)
                    {
                        _scope.AddVariable(arg.Name, arg);
                    }
                    func.Definition = CompileVarParValue(par);
                    SetLineInfo(func.Definition, par.SourceLine);
                    ExitScope();
                    ExitScope();
                    _funcFocus.StopFocus();
                    _functions.Add(func);
                }
            }
        }
QilGenerator