Implement -renamesourcefileattribute with the source file provider API.
Bug: 201269335
Change-Id: I1cdc8b562dd9505af1e32f80fa2b9839a86cf9e4
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 8617b7e..0516577 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -778,7 +778,7 @@
// Overwrite SourceFile if specified. This step should be done after IR conversion.
timing.begin("Rename SourceFile");
- new SourceFileRewriter(appView, appView.appInfo().app()).run();
+ new SourceFileRewriter(appView).run();
timing.end();
// If a method filter is present don't produce output since the application is likely partial.
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 5441a9e..dab9181 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -321,7 +321,7 @@
}
}
- private SourceFileEnvironment createSourceFileEnvironment(ProguardMapId proguardMapId) {
+ public static SourceFileEnvironment createSourceFileEnvironment(ProguardMapId proguardMapId) {
if (proguardMapId == null) {
return new SourceFileEnvironment() {
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index f211a3b..22eaec8 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -643,7 +643,9 @@
public final DexProto deserializeLambdaMethodProto =
createProto(objectType, serializedLambdaType);
- public final DexString defaultSourceFileAttribute = createString("SourceFile");
+ public final String defaultSourceFileAttributeString = "SourceFile";
+ public final DexString defaultSourceFileAttribute =
+ createString(defaultSourceFileAttributeString);
// Dex system annotations.
// See https://source.android.com/devices/tech/dalvik/dex-format.html#system-annotation
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index c3677ba..7b8da09 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.SourceFileEnvironment;
import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.dex.Marker;
@@ -40,6 +41,7 @@
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.ProguardMapSupplier;
+import com.android.tools.r8.naming.ProguardMapSupplier.ProguardMapId;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.utils.AsmUtils;
@@ -131,16 +133,24 @@
}
private void writeApplication(ClassFileConsumer consumer) {
- if (proguardMapSupplier != null && options.proguardMapConsumer != null) {
- marker.setPgMapId(proguardMapSupplier.writeProguardMap().getId());
+ ProguardMapId proguardMapId =
+ (proguardMapSupplier != null && options.proguardMapConsumer != null)
+ ? proguardMapSupplier.writeProguardMap()
+ : null;
+ if (proguardMapId != null) {
+ marker.setPgMapId(proguardMapId.getId());
}
Optional<String> markerString =
includeMarker(marker) ? Optional.of(marker.toString()) : Optional.empty();
+ SourceFileEnvironment sourceFileEnvironment = null;
+ if (options.sourceFileProvider != null) {
+ sourceFileEnvironment = ApplicationWriter.createSourceFileEnvironment(proguardMapId);
+ }
LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(appView);
for (DexProgramClass clazz : application.classes()) {
assert SyntheticNaming.verifyNotInternalSynthetic(clazz.getType());
try {
- writeClass(clazz, consumer, rewriter, markerString);
+ writeClass(clazz, consumer, rewriter, markerString, sourceFileEnvironment);
} catch (ClassTooLargeException e) {
throw appView
.options()
@@ -172,14 +182,21 @@
DexProgramClass clazz,
ClassFileConsumer consumer,
LensCodeRewriterUtils rewriter,
- Optional<String> markerString) {
+ Optional<String> markerString,
+ SourceFileEnvironment sourceFileEnvironment) {
ClassWriter writer = new ClassWriter(0);
if (markerString.isPresent()) {
int markerStringPoolIndex = writer.newConst(markerString.get());
assert markerStringPoolIndex == MARKER_STRING_CONSTANT_POOL_INDEX;
}
+ String sourceFile;
+ if (options.sourceFileProvider == null) {
+ sourceFile = clazz.sourceFile != null ? clazz.sourceFile.toString() : null;
+ } else {
+ sourceFile = options.sourceFileProvider.get(sourceFileEnvironment);
+ }
String sourceDebug = getSourceDebugExtension(clazz.annotations());
- writer.visitSource(clazz.sourceFile != null ? clazz.sourceFile.toString() : null, sourceDebug);
+ writer.visitSource(sourceFile, sourceDebug);
CfVersion version = getClassFileVersion(clazz);
if (version.isGreaterThanOrEqualTo(CfVersion.V1_8)) {
// JDK8 and after ignore ACC_SUPER so unset it.
diff --git a/src/main/java/com/android/tools/r8/naming/SourceFileRewriter.java b/src/main/java/com/android/tools/r8/naming/SourceFileRewriter.java
index aed0499..696bce1 100644
--- a/src/main/java/com/android/tools/r8/naming/SourceFileRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/SourceFileRewriter.java
@@ -3,71 +3,73 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.naming;
+import com.android.tools.r8.SourceFileEnvironment;
+import com.android.tools.r8.SourceFileProvider;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexApplication;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexString;
-/**
- * Visit program {@link DexClass}es and replace their sourceFile with the given string.
- *
- * If -keepattribute SourceFile is not set, we rather remove that attribute.
- */
+/** Computes the source file provider based on the proguard configuration if none is set. */
public class SourceFileRewriter {
private final AppView<?> appView;
- private final DexApplication application;
- public SourceFileRewriter(AppView<?> appView, DexApplication application) {
+ public SourceFileRewriter(AppView<?> appView) {
this.appView = appView;
- this.application = application;
}
public void run() {
- if (!appView.options().getProguardConfiguration().getKeepAttributes().sourceFile) {
- doRenaming(getDefaultSourceFileAttribute());
- } else if (appView.options().forceProguardCompatibility) {
- runCompat();
- } else {
- runNonCompat();
+ if (appView.options().sourceFileProvider != null) {
+ return;
}
+ appView.options().sourceFileProvider = computeSourceFileProvider();
}
- private void runCompat() {
+ public SourceFileProvider computeSourceFileProvider() {
+ if (!appView.options().getProguardConfiguration().getKeepAttributes().sourceFile) {
+ return rewriteToDefaultSourceFile();
+ }
+ if (appView.options().forceProguardCompatibility) {
+ return computeCompatProvider();
+ }
+ return computeNonCompatProvider();
+ }
+
+ private SourceFileProvider computeCompatProvider() {
// Compatibility mode will only apply -renamesourcefileattribute when minifying names.
if (appView.options().isMinifying()) {
String renaming = getRenameSourceFileAttribute();
if (renaming != null) {
- doRenaming(renaming);
+ return rewriteTo(renaming);
}
}
+ return null;
}
- private void runNonCompat() {
+ private SourceFileProvider computeNonCompatProvider() {
String renaming = getRenameSourceFileAttribute();
if (renaming != null) {
- doRenaming(renaming);
- } else if (appView.options().isMinifying()) {
- // TODO(b/202367773): This should also apply if optimizing.
- doRenaming(getDefaultSourceFileAttribute());
+ return rewriteTo(renaming);
}
+ if (appView.options().isMinifying()) {
+ // TODO(b/202367773): This should also apply if optimizing.
+ return rewriteToDefaultSourceFile();
+ }
+ return null;
}
private String getRenameSourceFileAttribute() {
return appView.options().getProguardConfiguration().getRenameSourceFileAttribute();
}
- private DexString getDefaultSourceFileAttribute() {
- return appView.dexItemFactory().defaultSourceFileAttribute;
+ private SourceFileProvider rewriteToDefaultSourceFile() {
+ return rewriteTo(appView.dexItemFactory().defaultSourceFileAttributeString);
}
- private void doRenaming(String renaming) {
- doRenaming(appView.dexItemFactory().createString(renaming));
- }
-
- private void doRenaming(DexString renaming) {
- for (DexClass clazz : application.classes()) {
- clazz.sourceFile = renaming;
- }
+ private SourceFileProvider rewriteTo(String renaming) {
+ return new SourceFileProvider() {
+ @Override
+ public String get(SourceFileEnvironment environment) {
+ return renaming;
+ }
+ };
}
}