Numberpublic final class Number extends Instruction implements Closure
Fields Summary |
---|
private static final int | LEVEL_SINGLE | private static final int | LEVEL_MULTIPLE | private static final int | LEVEL_ANY | private static final String[] | ClassNames | private static final String[] | FieldNames | private Pattern | _from | private Pattern | _count | private Expression | _value | private AttributeValueTemplate | _lang | private AttributeValueTemplate | _format | private AttributeValueTemplate | _letterValue | private AttributeValueTemplate | _groupingSeparator | private AttributeValueTemplate | _groupingSize | private int | _level | private boolean | _formatNeeded | private String | _className | private ArrayList | _closureVars |
Methods Summary |
---|
public void | addVariable(com.sun.org.apache.xalan.internal.xsltc.compiler.VariableRefBase variableRef)Add new variable to the closure.
if (_closureVars == null) {
_closureVars = new ArrayList();
}
// Only one reference per variable
if (!_closureVars.contains(variableRef)) {
_closureVars.add(variableRef);
}
| private void | compileConstructor(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen)Compiles a constructor for the class _className that
inherits from {Any,Single,Multiple}NodeCounter. This constructor
simply calls the same constructor in the super class.
MethodGenerator cons;
final InstructionList il = new InstructionList();
final ConstantPoolGen cpg = classGen.getConstantPool();
cons = new MethodGenerator(ACC_PUBLIC,
com.sun.org.apache.bcel.internal.generic.Type.VOID,
new com.sun.org.apache.bcel.internal.generic.Type[] {
Util.getJCRefType(TRANSLET_INTF_SIG),
Util.getJCRefType(DOM_INTF_SIG),
Util.getJCRefType(NODE_ITERATOR_SIG)
},
new String[] {
"dom",
"translet",
"iterator"
},
"<init>", _className, il, cpg);
il.append(ALOAD_0); // this
il.append(ALOAD_1); // translet
il.append(ALOAD_2); // DOM
il.append(new ALOAD(3));// iterator
int index = cpg.addMethodref(ClassNames[_level],
"<init>",
"(" + TRANSLET_INTF_SIG
+ DOM_INTF_SIG
+ NODE_ITERATOR_SIG
+ ")V");
il.append(new INVOKESPECIAL(index));
il.append(RETURN);
cons.stripAttributes(true);
cons.setMaxLocals();
cons.setMaxStack();
classGen.addMethod(cons.getMethod());
| private void | compileDefault(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)
int index;
ConstantPoolGen cpg = classGen.getConstantPool();
InstructionList il = methodGen.getInstructionList();
int[] fieldIndexes = getXSLTC().getNumberFieldIndexes();
if (fieldIndexes[_level] == -1) {
Field defaultNode = new Field(ACC_PRIVATE,
cpg.addUtf8(FieldNames[_level]),
cpg.addUtf8(NODE_COUNTER_SIG),
null,
cpg.getConstantPool());
// Add a new private field to this class
classGen.addField(defaultNode);
// Get a reference to the newly added field
fieldIndexes[_level] = cpg.addFieldref(classGen.getClassName(),
FieldNames[_level],
NODE_COUNTER_SIG);
}
// Check if field is initialized (runtime)
il.append(classGen.loadTranslet());
il.append(new GETFIELD(fieldIndexes[_level]));
final BranchHandle ifBlock1 = il.append(new IFNONNULL(null));
// Create an instance of DefaultNodeCounter
index = cpg.addMethodref(ClassNames[_level],
"getDefaultNodeCounter",
"(" + TRANSLET_INTF_SIG
+ DOM_INTF_SIG
+ NODE_ITERATOR_SIG
+ ")" + NODE_COUNTER_SIG);
il.append(classGen.loadTranslet());
il.append(methodGen.loadDOM());
il.append(methodGen.loadIterator());
il.append(new INVOKESTATIC(index));
il.append(DUP);
// Store the node counter in the field
il.append(classGen.loadTranslet());
il.append(SWAP);
il.append(new PUTFIELD(fieldIndexes[_level]));
final BranchHandle ifBlock2 = il.append(new GOTO(null));
// Backpatch conditionals
ifBlock1.setTarget(il.append(classGen.loadTranslet()));
il.append(new GETFIELD(fieldIndexes[_level]));
ifBlock2.setTarget(il.append(NOP));
| private void | compileLocals(com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeCounterGenerator nodeCounterGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MatchGenerator matchGen, com.sun.org.apache.bcel.internal.generic.InstructionList il)This method compiles code that is common to matchesFrom() and
matchesCount() in the auxillary class.
int field;
LocalVariableGen local;
ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
// Get NodeCounter._iterator and store locally
local = matchGen.addLocalVariable("iterator",
Util.getJCRefType(NODE_ITERATOR_SIG),
null, null);
field = cpg.addFieldref(NODE_COUNTER, "_iterator",
ITERATOR_FIELD_SIG);
il.append(ALOAD_0); // 'this' pointer on stack
il.append(new GETFIELD(field));
il.append(new ASTORE(local.getIndex()));
matchGen.setIteratorIndex(local.getIndex());
// Get NodeCounter._translet and store locally
local = matchGen.addLocalVariable("translet",
Util.getJCRefType(TRANSLET_SIG),
null, null);
field = cpg.addFieldref(NODE_COUNTER, "_translet",
"Lcom/sun/org/apache/xalan/internal/xsltc/Translet;");
il.append(ALOAD_0); // 'this' pointer on stack
il.append(new GETFIELD(field));
il.append(new CHECKCAST(cpg.addClass(TRANSLET_CLASS)));
il.append(new ASTORE(local.getIndex()));
nodeCounterGen.setTransletIndex(local.getIndex());
// Get NodeCounter._document and store locally
local = matchGen.addLocalVariable("document",
Util.getJCRefType(DOM_INTF_SIG),
null, null);
field = cpg.addFieldref(_className, "_document", DOM_INTF_SIG);
il.append(ALOAD_0); // 'this' pointer on stack
il.append(new GETFIELD(field));
// Make sure we have the correct DOM type on the stack!!!
il.append(new ASTORE(local.getIndex()));
matchGen.setDomIndex(local.getIndex());
| private void | compilePatterns(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)
int current;
int field;
LocalVariableGen local;
MatchGenerator matchGen;
NodeCounterGenerator nodeCounterGen;
_className = getXSLTC().getHelperClassName();
nodeCounterGen = new NodeCounterGenerator(_className,
ClassNames[_level],
toString(),
ACC_PUBLIC | ACC_SUPER,
null,
classGen.getStylesheet());
InstructionList il = null;
ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
// Add a new instance variable for each var in closure
final int closureLen = (_closureVars == null) ? 0 :
_closureVars.size();
for (int i = 0; i < closureLen; i++) {
VariableBase var =
((VariableRefBase) _closureVars.get(i)).getVariable();
nodeCounterGen.addField(new Field(ACC_PUBLIC,
cpg.addUtf8(var.getEscapedName()),
cpg.addUtf8(var.getType().toSignature()),
null, cpg.getConstantPool()));
}
// Add a single constructor to the class
compileConstructor(nodeCounterGen);
/*
* Compile method matchesFrom()
*/
if (_from != null) {
il = new InstructionList();
matchGen =
new MatchGenerator(ACC_PUBLIC | ACC_FINAL,
com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN,
new com.sun.org.apache.bcel.internal.generic.Type[] {
com.sun.org.apache.bcel.internal.generic.Type.INT,
},
new String[] {
"node",
},
"matchesFrom", _className, il, cpg);
compileLocals(nodeCounterGen,matchGen,il);
// Translate Pattern
il.append(matchGen.loadContextNode());
_from.translate(nodeCounterGen, matchGen);
_from.synthesize(nodeCounterGen, matchGen);
il.append(IRETURN);
matchGen.stripAttributes(true);
matchGen.setMaxLocals();
matchGen.setMaxStack();
matchGen.removeNOPs();
nodeCounterGen.addMethod(matchGen.getMethod());
}
/*
* Compile method matchesCount()
*/
if (_count != null) {
il = new InstructionList();
matchGen = new MatchGenerator(ACC_PUBLIC | ACC_FINAL,
com.sun.org.apache.bcel.internal.generic.Type.BOOLEAN,
new com.sun.org.apache.bcel.internal.generic.Type[] {
com.sun.org.apache.bcel.internal.generic.Type.INT,
},
new String[] {
"node",
},
"matchesCount", _className, il, cpg);
compileLocals(nodeCounterGen,matchGen,il);
// Translate Pattern
il.append(matchGen.loadContextNode());
_count.translate(nodeCounterGen, matchGen);
_count.synthesize(nodeCounterGen, matchGen);
il.append(IRETURN);
matchGen.stripAttributes(true);
matchGen.setMaxLocals();
matchGen.setMaxStack();
matchGen.removeNOPs();
nodeCounterGen.addMethod(matchGen.getMethod());
}
getXSLTC().dumpClass(nodeCounterGen.getJavaClass());
// Push an instance of the newly created class
cpg = classGen.getConstantPool();
il = methodGen.getInstructionList();
final int index = cpg.addMethodref(_className, "<init>",
"(" + TRANSLET_INTF_SIG
+ DOM_INTF_SIG
+ NODE_ITERATOR_SIG
+ ")V");
il.append(new NEW(cpg.addClass(_className)));
il.append(DUP);
il.append(classGen.loadTranslet());
il.append(methodGen.loadDOM());
il.append(methodGen.loadIterator());
il.append(new INVOKESPECIAL(index));
// Initialize closure variables
for (int i = 0; i < closureLen; i++) {
final VariableRefBase varRef = (VariableRefBase) _closureVars.get(i);
final VariableBase var = varRef.getVariable();
final Type varType = var.getType();
// Store variable in new closure
il.append(DUP);
il.append(var.loadInstruction());
il.append(new PUTFIELD(
cpg.addFieldref(_className, var.getEscapedName(),
varType.toSignature())));
}
| public java.lang.String | getInnerClassName()Returns the name of the auxiliary class or null if this predicate
is compiled inside the Translet.
return _className;
| public com.sun.org.apache.xalan.internal.xsltc.compiler.Closure | getParentClosure()Returns a reference to its parent closure or null if outermost.
return null;
| public boolean | hasValue()True if the has specified a value for this instance of number.
return _value != null;
| public boolean | inInnerClass()Returns true if this closure is compiled in an inner class (i.e.
if this is a real closure).
// -- Begin Closure interface --------------------
return (_className != null);
| public boolean | isDefault()Returns true if this instance of number has neither
a from nor a count pattern.
return _from == null && _count == null;
| public void | parseContents(com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)
final int count = _attributes.getLength();
for (int i = 0; i < count; i++) {
final String name = _attributes.getQName(i);
final String value = _attributes.getValue(i);
if (name.equals("value")) {
_value = parser.parseExpression(this, name, null);
}
else if (name.equals("count")) {
_count = parser.parsePattern(this, name, null);
}
else if (name.equals("from")) {
_from = parser.parsePattern(this, name, null);
}
else if (name.equals("level")) {
if (value.equals("single")) {
_level = LEVEL_SINGLE;
}
else if (value.equals("multiple")) {
_level = LEVEL_MULTIPLE;
}
else if (value.equals("any")) {
_level = LEVEL_ANY;
}
}
else if (name.equals("format")) {
_format = new AttributeValueTemplate(value, parser, this);
_formatNeeded = true;
}
else if (name.equals("lang")) {
_lang = new AttributeValueTemplate(value, parser, this);
_formatNeeded = true;
}
else if (name.equals("letter-value")) {
_letterValue = new AttributeValueTemplate(value, parser, this);
_formatNeeded = true;
}
else if (name.equals("grouping-separator")) {
_groupingSeparator = new AttributeValueTemplate(value, parser, this);
_formatNeeded = true;
}
else if (name.equals("grouping-size")) {
_groupingSize = new AttributeValueTemplate(value, parser, this);
_formatNeeded = true;
}
}
| public void | translate(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)
int index;
final ConstantPoolGen cpg = classGen.getConstantPool();
final InstructionList il = methodGen.getInstructionList();
// Push "this" for the call to characters()
il.append(classGen.loadTranslet());
if (hasValue()) {
compileDefault(classGen, methodGen);
_value.translate(classGen, methodGen);
// Round the number to the nearest integer
index = cpg.addMethodref(MATH_CLASS, "round", "(D)J");
il.append(new INVOKESTATIC(index));
il.append(new L2I());
// Call setValue on the node counter
index = cpg.addMethodref(NODE_COUNTER,
"setValue",
"(I)" + NODE_COUNTER_SIG);
il.append(new INVOKEVIRTUAL(index));
}
else if (isDefault()) {
compileDefault(classGen, methodGen);
}
else {
compilePatterns(classGen, methodGen);
}
// Call setStartNode()
if (!hasValue()) {
il.append(methodGen.loadContextNode());
index = cpg.addMethodref(NODE_COUNTER,
SET_START_NODE,
"(I)" + NODE_COUNTER_SIG);
il.append(new INVOKEVIRTUAL(index));
}
// Call getCounter() with or without args
if (_formatNeeded) {
if (_format != null) {
_format.translate(classGen, methodGen);
}
else {
il.append(new PUSH(cpg, "1"));
}
if (_lang != null) {
_lang.translate(classGen, methodGen);
}
else {
il.append(new PUSH(cpg, "en")); // TODO ??
}
if (_letterValue != null) {
_letterValue.translate(classGen, methodGen);
}
else {
il.append(new PUSH(cpg, Constants.EMPTYSTRING));
}
if (_groupingSeparator != null) {
_groupingSeparator.translate(classGen, methodGen);
}
else {
il.append(new PUSH(cpg, Constants.EMPTYSTRING));
}
if (_groupingSize != null) {
_groupingSize.translate(classGen, methodGen);
}
else {
il.append(new PUSH(cpg, "0"));
}
index = cpg.addMethodref(NODE_COUNTER, "getCounter",
"(" + STRING_SIG + STRING_SIG
+ STRING_SIG + STRING_SIG
+ STRING_SIG + ")" + STRING_SIG);
il.append(new INVOKEVIRTUAL(index));
}
else {
index = cpg.addMethodref(NODE_COUNTER, "setDefaultFormatting",
"()" + NODE_COUNTER_SIG);
il.append(new INVOKEVIRTUAL(index));
index = cpg.addMethodref(NODE_COUNTER, "getCounter",
"()" + STRING_SIG);
il.append(new INVOKEVIRTUAL(index));
}
// Output the resulting string to the handler
il.append(methodGen.loadHandler());
index = cpg.addMethodref(TRANSLET_CLASS,
CHARACTERSW,
CHARACTERSW_SIG);
il.append(new INVOKEVIRTUAL(index));
| public com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type | typeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)
if (_value != null) {
Type tvalue = _value.typeCheck(stable);
if (tvalue instanceof RealType == false) {
_value = new CastExpr(_value, Type.Real);
}
}
if (_count != null) {
_count.typeCheck(stable);
}
if (_from != null) {
_from.typeCheck(stable);
}
if (_format != null) {
_format.typeCheck(stable);
}
if (_lang != null) {
_lang.typeCheck(stable);
}
if (_letterValue != null) {
_letterValue.typeCheck(stable);
}
if (_groupingSeparator != null) {
_groupingSeparator.typeCheck(stable);
}
if (_groupingSize != null) {
_groupingSize.typeCheck(stable);
}
return Type.Void;
|
|