Allow the structure modifier to read final fields.
Dieser Commit ist enthalten in:
Ursprung
addc62457a
Commit
76d27017de
@ -152,6 +152,18 @@ public class StructureModifier<TField> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not a field is read-only (final).
|
||||
* @param fieldIndex - index of the field.
|
||||
* @return TRUE if the field by the given index is read-only, FALSE otherwise.
|
||||
*/
|
||||
public boolean isReadOnly(int fieldIndex) {
|
||||
if (fieldIndex < 0 || fieldIndex >= data.size())
|
||||
new IllegalArgumentException("Index parameter is not within [0 - " + data.size() + ")");
|
||||
|
||||
return Modifier.isFinal(data.get(fieldIndex).getModifiers());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the value of a field given its index.
|
||||
* @param fieldIndex - index of the field.
|
||||
@ -424,9 +436,10 @@ public class StructureModifier<TField> {
|
||||
|
||||
for (Field field : fields) {
|
||||
Class<?> type = field.getType();
|
||||
int modifier = field.getModifiers();
|
||||
|
||||
// First, ignore primitive fields
|
||||
if (!type.isPrimitive()) {
|
||||
// First, ignore primitive fields and final fields
|
||||
if (!type.isPrimitive() && !Modifier.isFinal(modifier)) {
|
||||
// Next, see if we actually can generate a default value
|
||||
if (generator.getDefault(type) != null) {
|
||||
// If so, require it
|
||||
@ -449,9 +462,9 @@ public class StructureModifier<TField> {
|
||||
for (Field field : FuzzyReflection.fromClass(type, true).getFields()) {
|
||||
int mod = field.getModifiers();
|
||||
|
||||
// Ignore static, final and "abstract packet" fields
|
||||
if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod) && (
|
||||
superclassExclude == null || !field.getDeclaringClass().equals(superclassExclude)
|
||||
// Ignore static and "abstract packet" fields
|
||||
if (!Modifier.isStatic(mod) &&
|
||||
(superclassExclude == null || !field.getDeclaringClass().equals(superclassExclude)
|
||||
)) {
|
||||
|
||||
result.add(field);
|
||||
|
@ -272,6 +272,10 @@ public final class StructureCompiler {
|
||||
return Modifier.isPublic(field.getModifiers());
|
||||
}
|
||||
|
||||
private boolean isNonFinal(Field field) {
|
||||
return !Modifier.isFinal(field.getModifiers());
|
||||
}
|
||||
|
||||
private void createFields(ClassWriter cw, String targetSignature) {
|
||||
FieldVisitor typedField = cw.visitField(Opcodes.ACC_PRIVATE, "typedTarget", targetSignature, null, null);
|
||||
typedField.visitEnd();
|
||||
@ -305,7 +309,8 @@ public final class StructureCompiler {
|
||||
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
|
||||
Class<?> outputType = fields.get(i).getType();
|
||||
Field field = fields.get(i);
|
||||
Class<?> outputType = field.getType();
|
||||
Class<?> inputType = Primitives.wrap(outputType);
|
||||
String typeDescriptor = Type.getDescriptor(outputType);
|
||||
String inputPath = inputType.getName().replace('.', '/');
|
||||
@ -318,8 +323,8 @@ public final class StructureCompiler {
|
||||
else
|
||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||
|
||||
// Only write to public fields
|
||||
if (isPublic(fields.get(i))) {
|
||||
// Only write to public non-final fields
|
||||
if (isPublic(field) && isNonFinal(field)) {
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 3);
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
||||
|
||||
@ -328,7 +333,7 @@ public final class StructureCompiler {
|
||||
else
|
||||
boxingHelper.unbox(Type.getType(outputType));
|
||||
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, targetName, fields.get(i).getName(), typeDescriptor);
|
||||
mv.visitFieldInsn(Opcodes.PUTFIELD, targetName, field.getName(), typeDescriptor);
|
||||
|
||||
} else {
|
||||
// Use reflection. We don't have a choice, unfortunately.
|
||||
@ -386,7 +391,9 @@ public final class StructureCompiler {
|
||||
mv.visitTableSwitchInsn(0, fields.size() - 1, errorLabel, labels);
|
||||
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
Class<?> outputType = fields.get(i).getType();
|
||||
|
||||
Field field = fields.get(i);
|
||||
Class<?> outputType = field.getType();
|
||||
String typeDescriptor = Type.getDescriptor(outputType);
|
||||
|
||||
mv.visitLabel(labels[i]);
|
||||
@ -398,9 +405,9 @@ public final class StructureCompiler {
|
||||
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||
|
||||
// Note that byte code cannot access non-public fields
|
||||
if (isPublic(fields.get(i))) {
|
||||
if (isPublic(field)) {
|
||||
mv.visitVarInsn(Opcodes.ALOAD, 2);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, targetName, fields.get(i).getName(), typeDescriptor);
|
||||
mv.visitFieldInsn(Opcodes.GETFIELD, targetName, field.getName(), typeDescriptor);
|
||||
|
||||
boxingHelper.box(Type.getType(outputType));
|
||||
} else {
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren