IDEA-77656: XSLT debug: Saxon9: AIOOBE at net.sf.saxon.expr.LocalVariableReference.evaluateVariable() on attempt to evaluate a variable

This commit is contained in:
Sascha Weinreuter
2011-12-05 11:34:17 +01:00
parent 03514e1288
commit fe0d75d1e6
2 changed files with 93 additions and 15 deletions
@@ -16,14 +16,13 @@
package org.intellij.plugins.xsltDebugger.rt.engine.local.saxon9;
import net.sf.saxon.expr.Expression;
import net.sf.saxon.expr.ExpressionVisitor;
import net.sf.saxon.expr.StackFrame;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.expr.*;
import net.sf.saxon.expr.instruct.GeneralVariable;
import net.sf.saxon.expr.instruct.GlobalVariable;
import net.sf.saxon.expr.instruct.LocalVariable;
import net.sf.saxon.expr.instruct.SlotManager;
import net.sf.saxon.om.*;
import net.sf.saxon.style.StyleElement;
import net.sf.saxon.style.*;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.type.ItemType;
import net.sf.saxon.type.Type;
@@ -32,6 +31,7 @@ import org.intellij.plugins.xsltDebugger.rt.engine.Debugger;
import org.intellij.plugins.xsltDebugger.rt.engine.Value;
import org.intellij.plugins.xsltDebugger.rt.engine.local.VariableImpl;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -57,13 +57,20 @@ class Saxon9StyleFrame<N extends StyleElement> extends AbstractSaxon9Frame<Debug
}
public Value eval(String expr) throws Debugger.EvaluationException {
Saxon9TraceListener.MUTED = true;
try {
Expression expression = myElement.makeExpression(expr);
final TypeHierarchy typeHierarchy = myXPathContext.getConfiguration().getTypeHierarchy();
expression = expression.typeCheck(ExpressionVisitor.make(myElement.getStaticContext(), expression.getExecutable()), Type.ITEM_TYPE);
final ItemType itemType = expression.getItemType(typeHierarchy);
final SequenceIterator it = expression.iterate(myXPathContext);
Expression expression =
ExpressionTool.make(expr, new EvalContext(myElement), myElement, 0, Token.EOF, 0, false);
final ExpressionVisitor visitor = ExpressionVisitor.make(myElement.getStaticContext(), expression.getExecutable());
expression = expression.typeCheck(visitor, Type.ITEM_TYPE);
final int variables = myXPathContext.getStackFrame().getStackFrameMap().getNumberOfVariables();
ExpressionTool.allocateSlots(expression, variables, myElement.getContainingSlotManager());
final TypeHierarchy typeHierarchy = myXPathContext.getConfiguration().getTypeHierarchy();
final ItemType itemType = expression.getItemType(typeHierarchy);
final SequenceIterator it = expression.iterate(myXPathContext);
Item value = null;
if (it.next() != null) {
value = it.current();
@@ -72,18 +79,23 @@ class Saxon9StyleFrame<N extends StyleElement> extends AbstractSaxon9Frame<Debug
return new SingleValue(value, itemType);
}
return new SequenceValue(value, it, itemType);
} catch (IllegalArgumentException e) {
throw new Debugger.EvaluationException(e.getMessage() != null ? e.getMessage() : e.toString());
} catch (XPathException e) {
throw new Debugger.EvaluationException(e.getMessage() != null ? e.getMessage() : e.toString());
} catch (AssertionError e) {
assert debug(e);
throw new Debugger.EvaluationException(e.getMessage() != null ? e.getMessage() : e.toString());
} catch (Exception e) {
e.printStackTrace();
assert debug(e);
throw new Debugger.EvaluationException(e.getMessage() != null ? e.getMessage() : e.toString());
} finally {
Saxon9TraceListener.MUTED = false;
}
}
@SuppressWarnings("CallToPrintStackTrace")
private static boolean debug(Throwable e) {
e.printStackTrace();
return true;
}
public List<Debugger.Variable> getVariables() {
final ArrayList<Debugger.Variable> variables = new ArrayList<Debugger.Variable>();
@@ -209,4 +221,64 @@ class Saxon9StyleFrame<N extends StyleElement> extends AbstractSaxon9Frame<Debug
return new ObjectType(myItemType.toString() + "+");
}
}
private static class EvalContext extends ExpressionContext {
private static Field myRedundant;
static {
try {
myRedundant = XSLGeneralVariable.class.getDeclaredField("redundant");
myRedundant.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
myRedundant = null;
}
}
private final StyleElement myElement;
public EvalContext(final StyleElement element) {
super(element);
myElement = element;
}
@Override
public Expression bindVariable(StructuredQName qName) throws XPathException {
final VariableReference expression = (VariableReference)super.bindVariable(qName);
final XSLVariableDeclaration declaration = myElement.bindVariable(qName);
final Declaration decl = new Declaration(declaration.getPrincipalStylesheetModule(), myElement);
final GeneralVariable var;
final Boolean prev = setRedundant(declaration, Boolean.FALSE);
try {
if (declaration instanceof XSLVariable) {
final XSLVariable variable = (XSLVariable)declaration;
if (declaration.isGlobal()) {
var = (GlobalVariable)variable.compile(declaration.getExecutable(), decl);
} else {
var = (LocalVariable)variable.compileLocalVariable(declaration.getExecutable(), decl);
}
} else if (declaration instanceof XSLParam) {
var = (GeneralVariable)declaration.compile(declaration.getExecutable(), decl);
} else {
return expression;
}
} finally {
setRedundant(declaration, prev);
}
expression.fixup(var);
return expression;
}
private static Boolean setRedundant(XSLVariableDeclaration variable, Boolean value) {
if (myRedundant == null) return null;
Object o = Boolean.FALSE;
try {
o = myRedundant.get(variable);
myRedundant.set(variable, value);
} catch (IllegalAccessException e) {
}
return (Boolean)o;
}
}
}
@@ -36,6 +36,8 @@ public class Saxon9TraceListener implements TraceListener {
private LocalDebugger myDebugger;
static boolean MUTED;
public Saxon9TraceListener() {
}
@@ -65,6 +67,7 @@ public class Saxon9TraceListener implements TraceListener {
}
public void enter(InstructionInfo instructionInfo, XPathContext xPathContext) {
if (MUTED) return;
if (TRACE) {
trace("<" + instructionInfo + ">");
}
@@ -76,6 +79,7 @@ public class Saxon9TraceListener implements TraceListener {
}
public void leave(InstructionInfo instructionInfo) {
if (MUTED) return;
if (TRACE) {
trace("</>");
}
@@ -85,6 +89,7 @@ public class Saxon9TraceListener implements TraceListener {
}
public void startCurrentItem(Item item) {
if (MUTED) return;
if (item instanceof NodeInfo) {
if (TRACE) {
trace("<" + ((NodeInfo)item).getDisplayName() + ">");
@@ -94,6 +99,7 @@ public class Saxon9TraceListener implements TraceListener {
}
public void endCurrentItem(Item item) {
if (MUTED) return;
if (item instanceof NodeInfo) {
myDebugger.popSource();
}