private QilExpression Compile(Compiler compiler)
{
Debug.Assert(compiler != null);
_compiler = compiler;
_functions = _f.FunctionList();
_extPars = _f.GlobalParameterList();
_gloVars = _f.GlobalVariableList();
_nsVars = _f.GlobalVariableList();
// Refactor huge templates into smaller ones (more JIT friendly)
(new XslAstRewriter()).Rewrite(compiler);
if (!IsDebug)
{
(new XslAstAnalyzer()).Analyze(compiler);
}
// Global variables and external params are visible from everywhere, so we have
// to prepopulate the scope with all of them before starting compilation
CreateGlobalVarPars();
try
{
CompileKeys();
CompileAndSortMatches(compiler.Root.Imports[0]);
PrecompileProtoTemplatesHeaders();
CompileGlobalVariables();
foreach (ProtoTemplate tmpl in compiler.AllTemplates)
{
CompileProtoTemplate(tmpl);
}
_varHelper.CheckEmpty();
}
catch (XslLoadException e)
{
e.SetSourceLineInfo(_lastScope.SourceLine);
throw;
}
catch (Exception e)
{
if (!XmlException.IsCatchableException(e))
{
throw;
}
throw new XslLoadException(e, _lastScope.SourceLine);
}
CompileInitializationCode();
QilNode root = CompileRootExpression(compiler.StartApplyTemplates);
// Clean default values which we calculate in caller context
foreach (ProtoTemplate tmpl in compiler.AllTemplates)
{
foreach (QilParameter par in tmpl.Function.Arguments)
{
if (!IsDebug || par.Name.Equals(_nameNamespaces))
{
par.DefaultValue = null;
}
}
}
// Create list of all early bound objects
Dictionary<string, Type> scriptClasses = compiler.Scripts.ScriptClasses;
List<EarlyBoundInfo> ebTypes = new List<EarlyBoundInfo>(scriptClasses.Count);
foreach (KeyValuePair<string, Type> pair in scriptClasses)
{
if (pair.Value != null)
{
ebTypes.Add(new EarlyBoundInfo(pair.Key, pair.Value));
}
}
QilExpression qil = _f.QilExpression(root, _f.BaseFactory);
{
qil.EarlyBoundTypes = ebTypes;
qil.FunctionList = _functions;
qil.GlobalParameterList = _extPars;
qil.GlobalVariableList = _gloVars;
qil.WhitespaceRules = compiler.WhitespaceRules;
qil.IsDebug = IsDebug;
qil.DefaultWriterSettings = compiler.Output.Settings;
}
QilDepthChecker.Check(qil);
return qil;
}