/**
* Implement the methods in the {@link ProxyCollection} interface.
*/
private void addProxyCollectionMethods(BCClass bc, Class type) {
// change tracker
BCField changeTracker = bc.declareField("changeTracker",
CollectionChangeTracker.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();
// collection copy
Constructor cons = findCopyConstructor(type);
if (cons == null && SortedSet.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(SortedSet.class);
code.invokeinterface().setMethod(SortedSet.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(Collection.class);
code.invokevirtual().setMethod(type, "addAll", boolean.class,
new Class[] { Collection.class });
code.pop();
}
code.areturn();
code.calculateMaxStack();
code.calculateMaxLocals();
// element type
BCField elementType = bc.declareField("elementType", Class.class);
elementType.setTransient(true);
m = bc.declareMethod("getElementType", Class.class, null);
m.makePublic();
code = m.getCode(true);
code.aload().setThis();
code.getfield().setField(elementType);