/** * Compile: this registers the template with the rule manager, and ensures space is available for * local variables */ public Expression compile(Executable exec) throws XPathException { Expression block = compileSequenceConstructor(exec, iterateAxis(Axis.CHILD), true); if (block == null) { block = Literal.makeEmptySequence(); } compiledTemplate.setMatchPattern(match); compiledTemplate.setBody(block); compiledTemplate.setStackFrameMap(stackFrameMap); compiledTemplate.setExecutable(getExecutable()); compiledTemplate.setSystemId(getSystemId()); compiledTemplate.setLineNumber(getLineNumber()); compiledTemplate.setHasRequiredParams(hasRequiredParams); compiledTemplate.setRequiredType(requiredType); Expression exp = null; try { exp = makeExpressionVisitor().simplify(block); } catch (XPathException e) { compileError(e); } try { if (requiredType != null) { RoleLocator role = new RoleLocator(RoleLocator.TEMPLATE_RESULT, diagnosticId, 0); // role.setSourceLocator(new ExpressionLocation(this)); role.setErrorCode("XTTE0505"); exp = TypeChecker.staticTypeCheck(exp, requiredType, false, role, makeExpressionVisitor()); } } catch (XPathException err) { compileError(err); } compiledTemplate.setBody(exp); compiledTemplate.init(getObjectName(), getPrecedence(), getMinImportPrecedence()); if (getConfiguration().isCompileWithTracing()) { TraceWrapper trace = new TraceInstruction(exp, this); trace.setLocationId(allocateLocationId(getSystemId(), getLineNumber())); trace.setContainer(compiledTemplate); exp = trace; compiledTemplate.setBody(exp); } ItemType contextItemType = Type.ITEM_TYPE; if (getObjectName() == null) { // the template can't be called by name, so the context item must match the match pattern contextItemType = match.getNodeTest(); } ExpressionVisitor visitor = makeExpressionVisitor(); try { // We've already done the typecheck of each XPath expression, but it's worth doing again at // this // level because we have more information now. Expression exp2 = visitor.typeCheck(exp, contextItemType); exp2 = visitor.optimize(exp2, contextItemType); if (exp != exp2) { compiledTemplate.setBody(exp2); exp = exp2; } } catch (XPathException e) { compileError(e); } // Try to extract new global variables from the body of the function // ExpressionPresenter presenter = ExpressionPresenter.make(getConfiguration()); // exp.explain(presenter); // presenter.close(); if (!getConfiguration().isCompileWithTracing()) { Expression exp2 = getConfiguration().getOptimizer().promoteExpressionsToGlobal(exp, visitor); if (exp != exp2) { compiledTemplate.setBody(exp2); exp = exp2; } } allocateSlots(exp); if (match != null) { RuleManager mgr = getPrincipalStylesheet().getRuleManager(); for (int i = 0; i < modeNames.length; i++) { StructuredQName nc = modeNames[i]; Mode mode = mgr.getMode(nc, true); if (prioritySpecified) { mgr.setHandler(match, compiledTemplate, mode, getPrecedence(), priority); } else { mgr.setHandler(match, compiledTemplate, mode, getPrecedence()); } } allocatePatternSlots(match, getSlotManager()); } if (isExplaining()) { System.err.println( "Optimized expression tree for template at line " + getLineNumber() + " in " + getSystemId() + ':'); exp.explain(System.err); } return null; }