private void replaceAndValidateFieldAccess(Code code, Instruction ins,
boolean get, Instruction stat) throws NoSuchMethodException {
code.beforeFirst();
FieldInstruction fi;
MethodInstruction mi;
ClassMetaData owner;
String name, typeName, methodName;
while (code.searchForward(ins)) {
// back up to the matched instruction
fi = (FieldInstruction) code.previous();
name = fi.getFieldName();
typeName = fi.getFieldTypeName();
owner = getPersistenceCapableOwner(name, fi.getFieldDeclarerType());
if (owner != null
&& owner.getAccessType() == ClassMetaData.ACCESS_PROPERTY) {
// if we're directly accessing a field in another class
// hierarchy that uses property access, something is wrong
if (owner != _meta && owner.getDeclaredField(name) != null &&
_meta != null && !owner.getDescribedType()
.isAssignableFrom(_meta.getDescribedType()))
throw new UserException(_loc.get("property-field-access",
new Object[]{ _meta, owner, name,
code.getMethod().getName() }));
// if we're directly accessing a property-backing field outside
// the property in our own class, notify user
if (isBackingFieldOfAnotherProperty(name, code))
addViolation("property-field-access", new Object[]{ _meta,
owner, name, code.getMethod().getName() }, false);
}
if (owner == null ||
owner.getDeclaredField(fromBackingFieldName(name)) == null) {
// not persistent field?
code.next();
continue;
} else if (!getRedefine() && !getCreateSubclass()
&& owner.getAccessType() == ClassMetaData.ACCESS_FIELD) {
// replace the instruction with a call to the generated access
// method
mi = (MethodInstruction) code.set(stat);
// invoke the proper access method, whether getter or setter
String prefix = (get) ? PRE + "Get" : PRE + "Set";
methodName = prefix + name;
if (get) {
mi.setMethod(getType(owner).getName(),
methodName, typeName, new String[]
{ getType(owner).getName() });
} else {
mi.setMethod(getType(owner).getName(),
methodName, "void", new String[]
{ getType(owner).getName(), typeName });
}
code.next();
} else if (getRedefine()) {