/** Generates a dex file and returns its bytes. */ public byte[] generate() { DexOptions options = new DexOptions(); options.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES; DexFile outputDex = new DexFile(options); for (TypeDeclaration typeDeclaration : types.values()) { outputDex.add(typeDeclaration.toClassDefItem()); } try { return outputDex.toDex(null, false); } catch (IOException e) { throw new RuntimeException(e); } }
ClassDefItem toClassDefItem() { if (!declared) { throw new IllegalStateException( "Undeclared type " + type + " declares members: " + fields.keySet() + " " + methods.keySet()); } DexOptions dexOptions = new DexOptions(); dexOptions.targetApiLevel = DexFormat.API_NO_EXTENDED_OPCODES; CstType thisType = type.constant; ClassDefItem out = new ClassDefItem( thisType, flags, supertype.constant, interfaces.ropTypes, new CstString(sourceFile)); for (MethodDeclaration method : methods.values()) { EncodedMethod encoded = method.toEncodedMethod(dexOptions); if (method.isDirect()) { out.addDirectMethod(encoded); } else { out.addVirtualMethod(encoded); } } for (FieldDeclaration field : fields.values()) { EncodedField encoded = field.toEncodedField(); if (field.isStatic()) { out.addStaticField(encoded, Constants.getConstant(field.staticValue)); } else { out.addInstanceField(encoded); } } return out; }