protected ClassWriter buildClassHeader(ClassLoader classLoader, EnumClassDefinition classDef) { return createClassWriter( classLoader, ACC_PUBLIC + ACC_FINAL + ACC_SUPER + ACC_ENUM, BuildUtils.getInternalType(classDef.getClassName()), "Ljava/lang/Enum<" + BuildUtils.getTypeDescriptor(classDef.getClassName()) + ">;", BuildUtils.getInternalType(classDef.getSuperClass()), BuildUtils.getInternalTypes(classDef.getInterfaces())); }
protected void buildLiterals(ClassWriter cw, EnumClassDefinition classDef) { FieldVisitor fv; for (EnumLiteralDefinition lit : classDef.getEnumLiterals()) { fv = cw.visitField( ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM, lit.getName(), BuildUtils.getTypeDescriptor(classDef.getClassName()), null, null); fv.visitEnd(); } { fv = cw.visitField( ACC_PRIVATE + ACC_FINAL + ACC_STATIC + ACC_SYNTHETIC, "$VALUES", "[" + BuildUtils.getTypeDescriptor(classDef.getClassName()), null, null); fv.visitEnd(); } }
protected void buildFields(ClassWriter cw, EnumClassDefinition classDef) { FieldVisitor fv; for (FieldDefinition fld : classDef.getFieldsDefinitions()) { fv = cw.visitField( ACC_PRIVATE + ACC_FINAL, fld.getName(), BuildUtils.getTypeDescriptor(fld.getTypeName()), null, null); fv.visitEnd(); } { fv = cw.visitField( ACC_PRIVATE + ACC_STATIC, "$context", "Lorg/mvel2/ParserContext;", null, null); fv.visitEnd(); } }
protected void buildGettersAndSetters(ClassWriter cw, EnumClassDefinition classDef) { MethodVisitor mv; { mv = cw.visitMethod( ACC_PUBLIC + ACC_STATIC, "values", "()[" + BuildUtils.getTypeDescriptor(classDef.getClassName()), null, null); mv.visitCode(); mv.visitFieldInsn( GETSTATIC, BuildUtils.getInternalType(classDef.getClassName()), "$VALUES", "[" + BuildUtils.getTypeDescriptor(classDef.getClassName())); mv.visitMethodInsn( INVOKEVIRTUAL, "[" + BuildUtils.getTypeDescriptor(classDef.getClassName()), "clone", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, "[" + BuildUtils.getTypeDescriptor(classDef.getClassName())); mv.visitInsn(ARETURN); mv.visitMaxs(1, 0); mv.visitEnd(); } for (FieldDefinition fld : classDef.getFieldsDefinitions()) { mv = cw.visitMethod( ACC_PUBLIC, BuildUtils.getterName(fld.getName(), fld.getTypeName()), "()" + BuildUtils.getTypeDescriptor(fld.getTypeName()), null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, BuildUtils.getInternalType(classDef.getName()), fld.getName(), BuildUtils.getTypeDescriptor(fld.getTypeName())); mv.visitInsn(BuildUtils.returnType(fld.getTypeName())); mv.visitMaxs(BuildUtils.sizeOf(fld.getTypeName()), 1); mv.visitEnd(); mv = cw.visitMethod( ACC_PUBLIC, BuildUtils.setterName(fld.getName(), fld.getTypeName()), "(" + BuildUtils.getTypeDescriptor(fld.getTypeName()) + ")V", null, null); mv.visitCode(); mv.visitInsn(RETURN); mv.visitMaxs(0, 1 + BuildUtils.sizeOf(fld.getTypeName())); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_STATIC, "get$context", "()Lorg/mvel2/ParserContext;", null, null); mv.visitCode(); mv.visitFieldInsn( GETSTATIC, BuildUtils.getInternalType(classDef.getName()), "$context", "Lorg/mvel2/ParserContext;"); mv.visitInsn(ARETURN); mv.visitMaxs(1, 0); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_STATIC, "set$context", "(Lorg/mvel2/ParserContext;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( PUTSTATIC, BuildUtils.getInternalType(classDef.getName()), "$context", "Lorg/mvel2/ParserContext;"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } }
protected void buildConstructors(ClassWriter cw, EnumClassDefinition classDef) throws IOException, ClassNotFoundException { MethodVisitor mv; String argTypes = ""; int size = 0; for (FieldDefinition fld : classDef.getFieldsDefinitions()) { argTypes += BuildUtils.getTypeDescriptor(fld.getTypeName()); size += BuildUtils.sizeOf(fld.getTypeName()); } { int ofs = 3; mv = cw.visitMethod( ACC_PRIVATE, "<init>", "(Ljava/lang/String;I" + argTypes + ")V", "(" + argTypes + ")V", null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Enum", "<init>", "(Ljava/lang/String;I)V"); for (FieldDefinition fld : classDef.getFieldsDefinitions()) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(BuildUtils.varType(fld.getTypeName()), ofs); mv.visitFieldInsn( PUTFIELD, BuildUtils.getInternalType(classDef.getName()), fld.getName(), BuildUtils.getTypeDescriptor(fld.getTypeName())); ofs += BuildUtils.sizeOf(fld.getTypeName()); } mv.visitInsn(RETURN); mv.visitMaxs(3, ofs); mv.visitEnd(); } { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); int N = classDef.getEnumLiterals().size(); mv.visitTypeInsn(NEW, BuildUtils.getInternalType(classDef.getClassName())); for (int j = 0; j < N; j++) { EnumLiteralDefinition lit = classDef.getEnumLiterals().get(j); mv.visitInsn(DUP); mv.visitLdcInsn(lit.getName()); BuildUtils.pushInt(mv, j); List<String> args = lit.getConstructorArgs(); for (int k = 0; k < args.size(); k++) { String argType = classDef.getField(k).getTypeName(); mv.visitLdcInsn(args.get(k)); mv.visitMethodInsn( INVOKESTATIC, "org/mvel2/MVEL", "eval", "(Ljava/lang/String;)Ljava/lang/Object;"); if (BuildUtils.isPrimitive(argType)) { mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(BuildUtils.box(argType))); mv.visitMethodInsn( INVOKEVIRTUAL, BuildUtils.getInternalType(BuildUtils.box(argType)), BuildUtils.numericMorph(BuildUtils.box(argType)), "()" + BuildUtils.getTypeDescriptor(argType)); } else { mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(argType)); } } mv.visitMethodInsn( INVOKESPECIAL, BuildUtils.getInternalType(classDef.getClassName()), "<init>", "(Ljava/lang/String;I" + argTypes + ")V"); mv.visitFieldInsn( PUTSTATIC, BuildUtils.getInternalType(classDef.getClassName()), lit.getName(), BuildUtils.getTypeDescriptor(classDef.getClassName())); mv.visitTypeInsn(NEW, BuildUtils.getInternalType(classDef.getClassName())); } BuildUtils.pushInt(mv, N); mv.visitTypeInsn(ANEWARRAY, BuildUtils.getInternalType(classDef.getClassName())); for (int j = 0; j < N; j++) { EnumLiteralDefinition lit = classDef.getEnumLiterals().get(j); mv.visitInsn(DUP); BuildUtils.pushInt(mv, j); mv.visitFieldInsn( GETSTATIC, BuildUtils.getInternalType(classDef.getClassName()), lit.getName(), BuildUtils.getTypeDescriptor(classDef.getClassName())); mv.visitInsn(AASTORE); } mv.visitFieldInsn( PUTSTATIC, BuildUtils.getInternalType(classDef.getClassName()), "$VALUES", "[" + BuildUtils.getTypeDescriptor(classDef.getClassName())); mv.visitInsn(RETURN); mv.visitMaxs(4 + size, 0); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_STATIC, "valueOf", "(Ljava/lang/String;)" + BuildUtils.getTypeDescriptor(classDef.getClassName()), null, null); mv.visitCode(); mv.visitLdcInsn(Type.getType(BuildUtils.getTypeDescriptor(classDef.getClassName()))); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKESTATIC, "java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(classDef.getClassName())); mv.visitInsn(ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } }