All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.artemis.weaver.AccessorGenerator Maven / Gradle / Ivy

package com.artemis.weaver;

import static com.artemis.meta.ClassMetadataUtil.instanceFields;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import com.artemis.meta.ClassMetadata;
import com.artemis.meta.ClassMetadataUtil;
import com.artemis.meta.FieldDescriptor;

final class AccessorGenerator implements Opcodes {

	private final ClassReader cr;
	private final ClassMetadata meta;
	private final ClassWriter cw;

	public AccessorGenerator(ClassReader cr, ClassMetadata meta) {
		this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
		this.cr = cr;
		this.meta = meta;
	}

	public ClassReader transform() {
		return new ClassReader(injectAccessors());
	}

	private byte[] injectAccessors() {
		ClassMetadataUtil util = new ClassMetadataUtil(meta);
		for (FieldDescriptor field : instanceFields(meta)) {
			if (!util.hasGetter(field)) injectGetter(field);
			if (!util.hasSetter(field)) injectSetter(field);
		}
		
		cr.accept(cw, 0);
		return cw.toByteArray();
	}

	private void injectSetter(FieldDescriptor f) {
		TypedOpcodes opcodes = new TypedOpcodes(f);
		
		MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, f.name, "(" + f.desc + ")V", null, null);
		mv.visitCode();
		Label l0 = new Label();
		mv.visitLabel(l0);
		mv.visitVarInsn(ALOAD, 0);
		mv.visitVarInsn(opcodes.tLOAD(), 1);
		mv.visitFieldInsn(PUTFIELD, meta.type.getInternalName(), f.name, f.desc);
		Label l1 = new Label();
		mv.visitLabel(l1);
		mv.visitInsn(RETURN);
		Label l2 = new Label();
		mv.visitLabel(l2);
		mv.visitLocalVariable("this", meta.type.getDescriptor(), null, l0, l2, 0);
		mv.visitLocalVariable(f.name, f.desc, null, l0, l2, 1);
		mv.visitEnd();
	}

	private void injectGetter(FieldDescriptor f) {	
		TypedOpcodes opcodes = new TypedOpcodes(f);
		
		MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, f.name, "()" + f.desc, null, null);
		mv.visitCode();
		Label l0 = new Label();
		mv.visitLabel(l0);
		mv.visitVarInsn(ALOAD, 0);
		mv.visitFieldInsn(GETFIELD, meta.type.getInternalName(), f.name, f.desc);
		mv.visitInsn(opcodes.tRETURN());
		Label l1 = new Label();
		mv.visitLabel(l1);
		mv.visitLocalVariable("this", meta.type.getDescriptor(), null, l0, l1, 0);
		mv.visitEnd();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy