ClassDef classDef = new ImmutableClassDef(classType, accessFlags, superClass, interfaces, sourceFile, buildClassAnnotations(c), fields, methods); dexBuilder.internClass(classDef);
public ImmutableDexFile(@Nullable Collection<? extends ClassDef> classes) { this.classes = ImmutableClassDef.immutableSetOf(classes); }
@Nonnull @Override protected ImmutableClassDef makeImmutable(@Nonnull ClassDef item) { return ImmutableClassDef.of(item); } };
public static ClassDef makeClassDef(@Nonnull String classType, @Nullable String superType, String... interfaces) { return new ImmutableClassDef(classType, 0, superType, ImmutableSet.copyOf(interfaces), null, null, null, null, null, null); }
public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable Collection<? extends ClassDef> classes) { this.classes = ImmutableClassDef.immutableSetOf(classes); this.opcodes = opcodes; }
@Nonnull @Override protected ImmutableClassDef makeImmutable(@Nonnull ClassDef item) { return ImmutableClassDef.of(item); } };
public static ClassDef makeInterfaceDef(@Nonnull String classType, String... interfaces) { return new ImmutableClassDef(classType, AccessFlags.INTERFACE.getValue(), "Ljava/lang/Object;", ImmutableSet.copyOf(interfaces), null, null, null, null, null, null); } }
public ImmutableDexFile(@Nonnull Opcodes opcodes, @Nullable Collection<? extends ClassDef> classes) { this.classes = ImmutableClassDef.immutableSetOf(classes); this.opcodes = opcodes; }
@Nonnull @Override protected ImmutableClassDef makeImmutable(@Nonnull ClassDef item) { return ImmutableClassDef.of(item); } };
private static ClassDef reDexClass(@Nonnull ClassDef classDef) { return new ImmutableClassDef(classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), classDef.getFields(), reDexMethods(classDef)); }
return new ImmutableClassDef( reType, classDef.getAccessFlags(),
@Test public void testAnnotationElementOrder() { // Elements are out of order wrt to the element name ImmutableSet<ImmutableAnnotationElement> elements = ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE), new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE)); ImmutableAnnotation annotation = new ImmutableAnnotation(AnnotationVisibility.RUNTIME, "Lorg/test/anno;", elements); ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null); MemoryDataStore dataStore = new MemoryDataStore(); try { DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.getDefault(), ImmutableSet.of(classDef))); } catch (IOException ex) { throw new RuntimeException(ex); } DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getBuffer()); ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null); Assert.assertNotNull(dbClassDef); Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null); Assert.assertNotNull(dbAnnotation); List<AnnotationElement> dbElements = Lists.newArrayList(dbAnnotation.getElements()); // Ensure that the elements were written out in sorted order Assert.assertEquals(2, dbElements.size()); Assert.assertEquals("blah", dbElements.get(0).getName()); Assert.assertEquals("zabaglione", dbElements.get(1).getName()); }
"Lorg/test/anno;", elements); ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null);
public static ImmutableClassDef of(ClassDef classDef) { if (classDef instanceof ImmutableClassDef) { return (ImmutableClassDef)classDef; } return new ImmutableClassDef( classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), classDef.getStaticFields(), classDef.getInstanceFields(), classDef.getDirectMethods(), classDef.getVirtualMethods()); }
classes.add(new ImmutableClassDef('L' + className.replace('.', '/') + ';', 0, null, null, null, null, null, null));
public static ImmutableClassDef of(ClassDef classDef) { if (classDef instanceof ImmutableClassDef) { return (ImmutableClassDef)classDef; } return new ImmutableClassDef( classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), classDef.getStaticFields(), classDef.getInstanceFields(), classDef.getDirectMethods(), classDef.getVirtualMethods()); }
public static ImmutableClassDef of(ClassDef classDef) { if (classDef instanceof ImmutableClassDef) { return (ImmutableClassDef)classDef; } return new ImmutableClassDef( classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), classDef.getStaticFields(), classDef.getInstanceFields(), classDef.getDirectMethods(), classDef.getVirtualMethods()); }
@Test public void testCustomMethodInlineTable_Virtual() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PUBLIC.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, null, ImmutableList.of(method)); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_VIRTUAL, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); }
@Test public void testCustomMethodInlineTable_Static() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.STATIC.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_STATIC, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); }
@Test public void should_generate_non_final_classes() throws IOException { ImmutableClassDef def = new ImmutableClassDef("Lfoo/Bar;", AccessFlags.FINAL.getValue(), "Ljava/lang/Object;", null, null, null, null, null); byte[] bytes = DexPoolUtils.toBytecode(new ImmutableDexFile(Opcodes.getDefault(), Collections.singleton(def))); given(dexFileLoader.loadDex(srcPathCaptor.capture(), anyString())) .will(answer((String src, String out) -> { assertTrue(src.endsWith("tmp.dex")); assertTrue(out.endsWith(".dex")); DexFile file; try (InputStream in = new FileInputStream(src)) { file = new DexBackedDexFile(null, ByteStreams.toByteArray(in)); } Set<? extends ClassDef> classes = file.getClasses(); assertSame(1, classes.size()); assertFalse(AccessFlags.FINAL.isSet(classes.iterator().next().getAccessFlags())); return dexFile; })); DexFile file = new DexBackedDexFile(null, bytes); ClassTransformer transformer = new ClassTransformer(file.getOpcodes(), file.getClasses(), folder.newFolder(), dexFileLoader); assertSame(dexFile, transformer.call()); assertTrue(transformer.getClasses().isEmpty()); assertFalse(new File(srcPathCaptor.getValue()).exists()); }