package com.infomancers.collections.yield.asm;
import com.infomancers.collections.yield.asm.promotion.AccessorCreators;
import com.infomancers.collections.yield.asmbase.Util;
import com.infomancers.collections.yield.asmbase.YielderInformationContainer;
import org.objectweb.asm.*;
import java.util.Collection;
import java.util.HashSet;
/**
* Copyright (c) 2007, Aviad Ben Dov
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
* 3. Neither the name of Infomancers, Ltd. nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* Promotes all local variables inside the yieldNextCore implementation
* to class member fields.
*/
final class LocalVariablePromoter extends ClassAdapter {
private final YielderInformationContainer info;
private String owner;
/**
* Constructs a new {@link org.objectweb.asm.ClassAdapter} object.
*
* @param cv the class visitor to which this adapter must delegate calls.
* @param info The visitor used to map where assignments to local variables
* take place, so that this visitor could prepare an ALOAD_0 for the PUTFIELD
*/
public LocalVariablePromoter(ClassVisitor cv, YielderInformationContainer info) {
super(cv);
this.info = info;
}
@Override
public void visitEnd() {
for (NewMember newMember : info.getSlots()) {
visitField(Opcodes.ACC_PRIVATE, newMember.getName(), newMember.getDesc(), newMember.getDesc(), null);
}
super.visitEnd();
}
@Override
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
owner = name;
}
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions);
if (com.infomancers.collections.yield.asmbase.Util.isYieldNextCoreMethod(name, desc)) {
return new MyMethodAdapter(methodVisitor);
} else {
return methodVisitor;
}
}
private class MyMethodAdapter extends MethodAdapter {
private Collection