Polishing
This commit is contained in:
@@ -147,6 +147,67 @@ public class CodeFlow implements Opcodes {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the main expression evaluation method has been generated, this
|
||||
* method will callback any registered FieldAdders or ClinitAdders to add any
|
||||
* extra information to the class representing the compiled expression.
|
||||
*/
|
||||
public void finish() {
|
||||
if (this.fieldAdders != null) {
|
||||
for (FieldAdder fieldAdder : this.fieldAdders) {
|
||||
fieldAdder.generateField(cw,this);
|
||||
}
|
||||
}
|
||||
if (this.clinitAdders != null) {
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
this.nextFreeVariableId = 0; // To 0 because there is no 'this' in a clinit
|
||||
for (ClinitAdder clinitAdder : this.clinitAdders) {
|
||||
clinitAdder.generateCode(mv, this);
|
||||
}
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitMaxs(0,0); // not supplied due to COMPUTE_MAXS
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a FieldAdder which will add a new field to the generated
|
||||
* class to support the code produced by an ast nodes primary
|
||||
* generateCode() method.
|
||||
*/
|
||||
public void registerNewField(FieldAdder fieldAdder) {
|
||||
if (this.fieldAdders == null) {
|
||||
this.fieldAdders = new ArrayList<>();
|
||||
}
|
||||
this.fieldAdders.add(fieldAdder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a ClinitAdder which will add code to the static
|
||||
* initializer in the generated class to support the code
|
||||
* produced by an ast nodes primary generateCode() method.
|
||||
*/
|
||||
public void registerNewClinit(ClinitAdder clinitAdder) {
|
||||
if (this.clinitAdders == null) {
|
||||
this.clinitAdders = new ArrayList<>();
|
||||
}
|
||||
this.clinitAdders.add(clinitAdder);
|
||||
}
|
||||
|
||||
public int nextFieldId() {
|
||||
return this.nextFieldId++;
|
||||
}
|
||||
|
||||
public int nextFreeVariableId() {
|
||||
return this.nextFreeVariableId++;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return this.clazzName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Insert any necessary cast and value call to convert from a boxed type to a
|
||||
* primitive value
|
||||
@@ -778,76 +839,6 @@ public class CodeFlow implements Opcodes {
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the main expression evaluation method has been generated, this
|
||||
* method will callback any registered FieldAdders or ClinitAdders to add any
|
||||
* extra information to the class representing the compiled expression.
|
||||
*/
|
||||
public void finish() {
|
||||
if (fieldAdders != null) {
|
||||
for (FieldAdder fieldAdder: fieldAdders) {
|
||||
fieldAdder.generateField(cw,this);
|
||||
}
|
||||
}
|
||||
if (clinitAdders != null) {
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
nextFreeVariableId = 0; // To 0 because there is no 'this' in a clinit
|
||||
for (ClinitAdder clinitAdder: clinitAdders) {
|
||||
clinitAdder.generateCode(mv, this);
|
||||
}
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitMaxs(0,0); // not supplied due to COMPUTE_MAXS
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a FieldAdder which will add a new field to the generated
|
||||
* class to support the code produced by an ast nodes primary
|
||||
* generateCode() method.
|
||||
*/
|
||||
public void registerNewField(FieldAdder fieldAdder) {
|
||||
if (fieldAdders == null) {
|
||||
fieldAdders = new ArrayList<>();
|
||||
}
|
||||
fieldAdders.add(fieldAdder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a ClinitAdder which will add code to the static
|
||||
* initializer in the generated class to support the code
|
||||
* produced by an ast nodes primary generateCode() method.
|
||||
*/
|
||||
public void registerNewClinit(ClinitAdder clinitAdder) {
|
||||
if (clinitAdders == null) {
|
||||
clinitAdders = new ArrayList<>();
|
||||
}
|
||||
clinitAdders.add(clinitAdder);
|
||||
}
|
||||
|
||||
public int nextFieldId() {
|
||||
return nextFieldId++;
|
||||
}
|
||||
|
||||
public int nextFreeVariableId() {
|
||||
return nextFreeVariableId++;
|
||||
}
|
||||
|
||||
public String getClassname() {
|
||||
return clazzName;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface FieldAdder {
|
||||
void generateField(ClassWriter cw, CodeFlow codeflow);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ClinitAdder {
|
||||
void generateCode(MethodVisitor mv, CodeFlow codeflow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the optimal instruction for loading a number on the stack.
|
||||
* @param mv where to insert the bytecode
|
||||
@@ -979,4 +970,17 @@ public class CodeFlow implements Opcodes {
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface FieldAdder {
|
||||
|
||||
void generateField(ClassWriter cw, CodeFlow codeflow);
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ClinitAdder {
|
||||
|
||||
void generateCode(MethodVisitor mv, CodeFlow codeflow);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ public class InlineList extends SpelNodeImpl {
|
||||
|
||||
@Override
|
||||
public void generateCode(MethodVisitor mv, CodeFlow codeflow) {
|
||||
final String constantFieldName = "inlineList$"+codeflow.nextFieldId();
|
||||
final String clazzname = codeflow.getClassname();
|
||||
final String constantFieldName = "inlineList$" + codeflow.nextFieldId();
|
||||
final String className = codeflow.getClassName();
|
||||
|
||||
codeflow.registerNewField(new CodeFlow.FieldAdder() {
|
||||
public void generateField(ClassWriter cw, CodeFlow codeflow) {
|
||||
@@ -143,11 +143,11 @@ public class InlineList extends SpelNodeImpl {
|
||||
|
||||
codeflow.registerNewClinit(new CodeFlow.ClinitAdder() {
|
||||
public void generateCode(MethodVisitor mv, CodeFlow codeflow) {
|
||||
generateClinitCode(clazzname,constantFieldName, mv,codeflow,false);
|
||||
generateClinitCode(className, constantFieldName, mv, codeflow, false);
|
||||
}
|
||||
});
|
||||
|
||||
mv.visitFieldInsn(GETSTATIC, clazzname, constantFieldName, "Ljava/util/List;");
|
||||
mv.visitFieldInsn(GETSTATIC, className, constantFieldName, "Ljava/util/List;");
|
||||
codeflow.pushDescriptor("Ljava/util/List");
|
||||
}
|
||||
|
||||
@@ -158,8 +158,8 @@ public class InlineList extends SpelNodeImpl {
|
||||
if (!nested) {
|
||||
mv.visitFieldInsn(PUTSTATIC, clazzname, constantFieldName, "Ljava/util/List;");
|
||||
}
|
||||
int childcount = getChildCount();
|
||||
for (int c=0; c < childcount; c++) {
|
||||
int childCount = getChildCount();
|
||||
for (int c = 0; c < childCount; c++) {
|
||||
if (!nested) {
|
||||
mv.visitFieldInsn(GETSTATIC, clazzname, constantFieldName, "Ljava/util/List;");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user