| // Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| package com.android.tools.r8; | |
| import com.android.tools.r8.dex.ApplicationReader; | |
| import com.android.tools.r8.graph.DexApplication; | |
| import com.android.tools.r8.graph.DexEncodedField; | |
| import com.android.tools.r8.graph.DexEncodedMethod; | |
| import com.android.tools.r8.graph.DexField; | |
| import com.android.tools.r8.graph.DexMethod; | |
| import com.android.tools.r8.graph.DexProgramClass; | |
| import com.android.tools.r8.graph.DexType; | |
| import com.android.tools.r8.naming.ClassNameMapper; | |
| import com.android.tools.r8.naming.MemberNaming.FieldSignature; | |
| import com.android.tools.r8.naming.MemberNaming.MethodSignature; | |
| import com.android.tools.r8.utils.AndroidApp; | |
| import com.android.tools.r8.utils.AndroidApp.Builder; | |
| import com.android.tools.r8.utils.InternalOptions; | |
| import com.android.tools.r8.utils.internal.ListUtils; | |
| import com.android.tools.r8.utils.timing.Timing; | |
| import java.io.IOException; | |
| import java.nio.file.Path; | |
| import java.nio.file.Paths; | |
| import java.util.Arrays; | |
| import java.util.List; | |
| import java.util.concurrent.ExecutorService; | |
| import java.util.concurrent.Executors; | |
| public class PrintClassList { | |
| @SuppressWarnings("BadImport") | |
| public static void main(String[] args) throws IOException { | |
| List<String> dexFiles = Arrays.asList(args); | |
| Builder builder = AndroidApp.builder(); | |
| Path proguardMapFile = null; | |
| if (args[0].endsWith("map")) { | |
| proguardMapFile = Paths.get(args[0]); | |
| dexFiles = dexFiles.subList(1, dexFiles.size()); | |
| } | |
| builder.addProgramFiles(ListUtils.map(dexFiles, Paths::get)); | |
| ExecutorService executorService = Executors.newCachedThreadPool(); | |
| InternalOptions options = new InternalOptions(); | |
| DexApplication application = | |
| new ApplicationReader(builder.build(), options, Timing.empty()) | |
| .read( | |
| proguardMapFile == null ? null : StringResource.fromFile(proguardMapFile), | |
| executorService); | |
| ClassNameMapper map = application.getProguardMap(); | |
| for (DexProgramClass clazz : application.classes()) { | |
| System.out.print(maybeDeobfuscateType(map, clazz.type)); | |
| System.out.println(); | |
| clazz.forEachMethod(method -> printMethod(method, map)); | |
| clazz.forEachField(field -> printField(field, map)); | |
| } | |
| executorService.shutdown(); | |
| } | |
| private static void printMethod(DexEncodedMethod encodedMethod, ClassNameMapper map) { | |
| DexMethod method = encodedMethod.getReference(); | |
| if (map != null) { | |
| System.out.println(map.originalNameOf(method)); | |
| } else { | |
| // Detour via Signature to get the same formatting. | |
| MethodSignature signature = MethodSignature.fromDexMethod(method); | |
| System.out.println(method.holder.toSourceString() + " " + signature); | |
| } | |
| } | |
| private static void printField(DexEncodedField encodedField, ClassNameMapper map) { | |
| DexField field = encodedField.getReference(); | |
| if (map != null) { | |
| System.out.println(map.originalNameOf(field)); | |
| } else { | |
| // Detour via Signature to get the same formatting. | |
| FieldSignature signature = | |
| new FieldSignature(field.name.toSourceString(), field.type.toSourceString()); | |
| System.out.println(field.holder.toSourceString() + " " + signature); | |
| } | |
| } | |
| private static String maybeDeobfuscateType(ClassNameMapper map, DexType type) { | |
| return map == null ? type.toSourceString() : map.originalNameOf(type); | |
| } | |
| } |