| // Copyright (c) 2022, 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 static com.android.tools.r8.BaseCompilerCommandParser.ART_PROFILE_FLAG; | |
| import static com.android.tools.r8.BaseCompilerCommandParser.MAP_DIAGNOSTICS; | |
| import static com.android.tools.r8.BaseCompilerCommandParser.MIN_API_FLAG; | |
| import static com.android.tools.r8.BaseCompilerCommandParser.THREAD_COUNT_FLAG; | |
| import static com.android.tools.r8.D8CommandParser.STARTUP_PROFILE_FLAG; | |
| import static com.android.tools.r8.R8CommandParser.ISOLATED_SPLITS_FLAG; | |
| import com.android.tools.r8.utils.AndroidApiLevel; | |
| import com.google.common.collect.ImmutableList; | |
| import java.util.Arrays; | |
| import java.util.Collections; | |
| import java.util.List; | |
| public class ParseFlagInfoImpl implements ParseFlagInfo { | |
| private static String defaultSuffix(boolean isDefault) { | |
| return isDefault ? " (default)" : ""; | |
| } | |
| public static ParseFlagInfoImpl getRelease(boolean isDefault) { | |
| return flag0( | |
| "--release", "Compile without debugging information" + defaultSuffix(isDefault) + "."); | |
| } | |
| public static ParseFlagInfoImpl getDebug(boolean isDefault) { | |
| return flag0("--debug", "Compile with debugging information" + defaultSuffix(isDefault) + "."); | |
| } | |
| public static ParseFlagInfoImpl getDex(boolean isDefault) { | |
| return flag0("--dex", "Compile program to DEX file format" + defaultSuffix(isDefault) + "."); | |
| } | |
| public static ParseFlagInfoImpl getClassfile() { | |
| return flag0("--classfile", "Compile program to Java classfile format."); | |
| } | |
| public static ParseFlagInfoImpl getOutput() { | |
| return flag1( | |
| "--output", | |
| "<file>", | |
| "Output result in <file>.", | |
| "<file> must be an existing directory or a zip file."); | |
| } | |
| public static ParseFlagInfoImpl getGlobals() { | |
| return flag1( | |
| "--globals", | |
| "<file>", | |
| "Global synthetics <file> from a previous intermediate compilation.", | |
| "The <file> may be either a zip-archive of global synthetics or the", | |
| "global-synthetic files directly."); | |
| } | |
| public static ParseFlagInfoImpl getGlobalsOutput() { | |
| return flag1( | |
| "--globals-output", | |
| "<file>", | |
| "Output global synthetics in <file>.", | |
| "<file> must be an existing directory or a non-existent zip archive."); | |
| } | |
| public static ParseFlagInfoImpl getLib() { | |
| return flag1("--lib", "<file|jdk-home>", "Add <file|jdk-home> as a library resource."); | |
| } | |
| public static ParseFlagInfoImpl getClasspath() { | |
| return flag1("--classpath", "<file>", "Add <file> as a classpath resource."); | |
| } | |
| public static ParseFlagInfoImpl getMinApi() { | |
| return flag1( | |
| MIN_API_FLAG, | |
| "<number>", | |
| "Minimum Android API level compatibility (default: " | |
| + AndroidApiLevel.getDefault().getLevel() | |
| + ")."); | |
| } | |
| public static ParseFlagInfoImpl getDesugaredLib() { | |
| return flag1( | |
| "--desugared-lib", | |
| "<file>", | |
| "Specify desugared library configuration.", | |
| "<file> is a desugared library configuration (json)."); | |
| } | |
| public static ParseFlagInfoImpl getMainDexRules() { | |
| return flag1( | |
| "--main-dex-rules", | |
| "<file>", | |
| "Proguard keep rules for classes to place in the", | |
| "primary dex file."); | |
| } | |
| public static ParseFlagInfoImpl getMainDexList() { | |
| return flag1("--main-dex-list", "<file>", "List of classes to place in the primary dex file."); | |
| } | |
| public static ParseFlagInfoImpl getMainDexListOutput() { | |
| return flag1("--main-dex-list-output", "<file>", "Output resulting main dex list in <file>."); | |
| } | |
| public static ParseFlagInfoImpl getVersion(String tool) { | |
| return flag0("--version", "Print the version of " + tool + "."); | |
| } | |
| public static ParseFlagInfoImpl getHelp() { | |
| return flag0("--help", "Print this message."); | |
| } | |
| public static ParseFlagInfoImpl getPgConf() { | |
| return ParseFlagInfoImpl.flag1("--pg-conf", "<file>", "Proguard configuration <file>."); | |
| } | |
| public static ParseFlagInfoImpl getPgMapOutput() { | |
| return ParseFlagInfoImpl.flag1( | |
| "--pg-map-output", "<file>", "Output the resulting name and line mapping to <file>."); | |
| } | |
| public static ParseFlagInfoImpl getPartitionMapOutput() { | |
| return ParseFlagInfoImpl.flag1( | |
| "--partition-map-output", "<file>", "Output the resulting mapping to <file>."); | |
| } | |
| public static List<ParseFlagInfoImpl> getAssertionsFlags() { | |
| return ImmutableList.of( | |
| flag0a1( | |
| "--force-enable-assertions[:[<class name>|<package name>...]]", | |
| "--force-ea[:[<class name>|<package name>...]]", | |
| "Forcefully enable javac generated assertion code."), | |
| flag0a1( | |
| "--force-disable-assertions[:[<class name>|<package name>...]]", | |
| "--force-da[:[<class name>|<package name>...]]", | |
| "Forcefully disable javac generated assertion code.", | |
| "This is the default handling of javac assertion code", | |
| "when generating DEX file format."), | |
| flag0a1( | |
| "--force-passthrough-assertions[:[<class name>|<package name>...]]", | |
| "--force-pa[:[<class name>|<package name>...]]", | |
| "Don't change javac generated assertion code. This", | |
| "is the default handling of javac assertion code when", | |
| "generating class file format."), | |
| flag0a1( | |
| "--force-assertions-handler:<handler method>[:[<class name>|<package name>...]]", | |
| "--force-ah:<handler method>[:[<class name>|<package name>...]]", | |
| "Change javac and kotlinc generated assertion code", | |
| "to invoke the method <handler method> with each", | |
| "assertion error instead of throwing it.", | |
| "The <handler method> is specified as a class name", | |
| "followed by a dot and the method name.", | |
| "The handler method must take a single argument of", | |
| "type java.lang.Throwable and have return type void.")); | |
| } | |
| public static ParseFlagInfoImpl getThreadCount() { | |
| return flag1( | |
| THREAD_COUNT_FLAG, | |
| "<number>", | |
| "Use <number> of threads for compilation.", | |
| "If not specified the number will be based on", | |
| "heuristics taking the number of cores into account."); | |
| } | |
| public static ParseFlagInfoImpl getMapDiagnostics() { | |
| return flag2( | |
| MAP_DIAGNOSTICS + "[:<type>]", | |
| "<from-level>", | |
| "<to-level>", | |
| "Map diagnostics of <type> (default any) reported as", | |
| "<from-level> to <to-level> where <from-level> and", | |
| "<to-level> are one of 'info', 'warning', or 'error'", | |
| "and the optional <type> is either the simple or", | |
| "fully qualified Java type name of a diagnostic.", | |
| "If <type> is unspecified, all diagnostics at ", | |
| "<from-level> will be mapped.", | |
| "Note that fatal compiler errors cannot be mapped."); | |
| } | |
| public static ParseFlagInfoImpl getAndroidPlatformBuild() { | |
| return flag0( | |
| "--android-platform-build", | |
| "Compile as a platform build where the runtime/bootclasspath", | |
| "is assumed to be the version specified by --min-api."); | |
| } | |
| public static ParseFlagInfoImpl getArtProfile() { | |
| return flag2( | |
| ART_PROFILE_FLAG, | |
| "<input>", | |
| "<output>", | |
| "Rewrite human readable ART profile read from <input> and write to <output>."); | |
| } | |
| public static ParseFlagInfoImpl getStartupProfile() { | |
| return flag1(STARTUP_PROFILE_FLAG, "<file>", "Startup profile <file> to use for dex layout."); | |
| } | |
| public static ParseFlagInfoImpl getIsolatedSplits() { | |
| return flag0( | |
| ISOLATED_SPLITS_FLAG, | |
| "Specifies that the application is using isolated splits, i.e., if split APKs installed " | |
| + "for this application are loaded into their own Context objects."); | |
| } | |
| public static ParseFlagInfoImpl flag0(String flag, String... help) { | |
| return flag(flag, Collections.emptyList(), Arrays.asList(help)); | |
| } | |
| public static ParseFlagInfoImpl flag1(String flag, String arg, String... help) { | |
| return flag(flag, Collections.singletonList(arg), Arrays.asList(help)); | |
| } | |
| public static ParseFlagInfoImpl flag2(String flag, String arg1, String arg2, String... help) { | |
| return flag(flag, ImmutableList.of(arg1, arg2), Arrays.asList(help)); | |
| } | |
| private static String fmt(String flag, List<String> args) { | |
| StringBuilder builder = new StringBuilder(flag); | |
| for (String arg : args) { | |
| builder.append(" ").append(arg); | |
| } | |
| return builder.toString(); | |
| } | |
| @SuppressWarnings("UnusedVariable") | |
| public static ParseFlagInfoImpl flag(String flag, List<String> args, List<String> help) { | |
| return new ParseFlagInfoImpl(flag, fmt(flag, args), Collections.emptyList(), help); | |
| } | |
| public static ParseFlagInfoImpl flag0a1(String flag, String alternative, String... help) { | |
| return new ParseFlagInfoImpl( | |
| null, flag, Collections.singletonList(alternative), Arrays.asList(help)); | |
| } | |
| // Note that the raw flag may be non-representable as in the case of the family of flags for | |
| // assertions. | |
| @SuppressWarnings("UnusedVariable") | |
| private final String rawFlag; | |
| private final String flagWithArgs; | |
| private final List<String> alternatives; | |
| private final List<String> flagHelp; | |
| public ParseFlagInfoImpl( | |
| String rawFlag, String flagWithArgs, List<String> alternatives, List<String> flagHelp) { | |
| // Raw flag may be null if it does not have a unique definition. | |
| assert flagWithArgs != null; | |
| assert alternatives != null; | |
| assert flagHelp != null; | |
| this.rawFlag = rawFlag; | |
| this.flagWithArgs = flagWithArgs; | |
| this.alternatives = alternatives; | |
| this.flagHelp = flagHelp; | |
| } | |
| @Override | |
| public String getFlagFormat() { | |
| return flagWithArgs; | |
| } | |
| @Override | |
| public List<String> getFlagFormatAlternatives() { | |
| return alternatives; | |
| } | |
| @Override | |
| public List<String> getFlagHelp() { | |
| return flagHelp; | |
| } | |
| } |