/**
* Implement the methods in the {@link ProxyMap} interface.
*/
private void addProxyMapMethods(BCClass bc, Class type) {
// change tracker
BCField changeTracker = bc.declareField("changeTracker",
MapChangeTracker.class);
changeTracker.setTransient(true);
BCMethod m = bc.declareMethod("getChangeTracker", ChangeTracker.class,
null);
m.makePublic();
Code code = m.getCode(true);
code.aload().setThis();
code.getfield().setField(changeTracker);
code.areturn();
code.calculateMaxStack();
code.calculateMaxLocals();
// map copy
Constructor cons = findCopyConstructor(type);
if (cons == null && SortedMap.class.isAssignableFrom(type))
cons = findComparatorConstructor(type);
Class[] params = (cons == null) ? new Class[0]
: cons.getParameterTypes();
m = bc.declareMethod("copy", Object.class, new Class[] {Object.class});
m.makePublic();
code = m.getCode(true);
code.anew().setType(type);
code.dup();
if (params.length == 1) {
code.aload().setParam(0);
if (params[0] == Comparator.class) {
code.checkcast().setType(SortedMap.class);
code.invokeinterface().setMethod(SortedMap.class, "comparator",
Comparator.class, null);
} else
code.checkcast().setType(params[0]);
}
code.invokespecial().setMethod(type, "<init>", void.class, params);
if (params.length == 0 || params[0] == Comparator.class) {
code.dup();
code.aload().setParam(0);
code.checkcast().setType(Map.class);
code.invokevirtual().setMethod(type, "putAll", void.class,
new Class[] { Map.class });
}
code.areturn();
code.calculateMaxStack();
code.calculateMaxLocals();
// key type
BCField keyType = bc.declareField("keyType", Class.class);
keyType.setTransient(true);
m = bc.declareMethod("getKeyType", Class.class, null);
m.makePublic();
code = m.getCode(true);
code.aload().setThis();
code.getfield().setField(keyType);
code.areturn();
code.calculateMaxStack();
code.calculateMaxLocals();
// value type
BCField valueType = bc.declareField("valueType", Class.class);
valueType.setTransient(true);
m = bc.declareMethod("getValueType", Class.class, null);
m.makePublic();
code = m.getCode(true);
code.aload().setThis();
code.getfield().setField(valueType);