blob: de654b8ba8ee5a63bd5a83d8f27c4b7fa23026db [file] [log] [blame]
// Copyright (c) 2017, 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.naming;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.code.ConstString;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.code.ReturnVoid;
import com.android.tools.r8.code.SgetObject;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexDebugEvent.SetFile;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliBuilder.MethodSignature;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests -renamesourcefileattribute.
*/
@RunWith(Parameterized.class)
public class RenameSourceFileSmaliTest extends SmaliTestBase {
private static final String TEST_FILE = "TestFile.java";
private static final List<String> DEFAULT_PG_CONFIGS =
ImmutableList.of(
"-keep class *** { *; }",
"-dontoptimize",
"-keepattributes SourceFile,LineNumberTable");
private void configure(ProguardConfiguration.Builder pg) {
if (renaming) {
pg.setRenameSourceFileAttribute(TEST_FILE);
}
}
@Parameter
public boolean renaming;
@Parameters(name="renaming:{0}")
public static Object[] parameters() {
return new Object[] {true, false};
}
/**
* replica of {@link RunArtSmokeTest#test}
*/
@Test
public void artSmokeTest() throws Exception {
// Build simple "Hello, world!" application.
SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);
String originalSourceFile = DEFAULT_CLASS_NAME + FileUtils.JAVA_EXTENSION;
builder.setSourceFile(originalSourceFile);
MethodSignature mainSignature = builder.addMainMethod(
2,
".line 1",
" sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
" const-string v1, \"Hello, world!\"",
".source \"PrintStream.java\"",
".line 337",
" invoke-virtual { v0, v1 }, Ljava/io/PrintStream;->println(Ljava/lang/String;)V",
".source \"" + originalSourceFile + "\"",
".line 2",
" return-void"
);
Path processedApp = runR8(builder, DEFAULT_PG_CONFIGS, this::configure, null);
DexClass mainClass = getClass(processedApp, DEFAULT_CLASS_NAME);
verifySourceFileInCodeItem(mainClass, originalSourceFile, TEST_FILE);
DexEncodedMethod mainMethod = getMethod(processedApp, mainSignature);
assertNotNull(mainMethod);
DexCode code = mainMethod.getCode().asDexCode();
assertTrue(code.instructions[0] instanceof SgetObject);
assertTrue(code.instructions[1] instanceof ConstString);
assertTrue(code.instructions[2] instanceof InvokeVirtual);
assertTrue(code.instructions[3] instanceof ReturnVoid);
// Run the generated code in Art.
String result = runArt(processedApp, DEFAULT_MAIN_CLASS_NAME);
assertEquals(StringUtils.lines("Hello, world!"), result);
verifySourceFileInDebugInfo(code);
}
private void verifySourceFileInCodeItem(DexClass clazz, String original, String rename) {
String processedSourceFile = clazz.sourceFile.toString();
if (renaming) {
assertEquals(rename, processedSourceFile);
} else {
assertEquals(original, processedSourceFile);
}
}
private void verifySourceFileInDebugInfo(DexCode code) {
assertNotNull(code.getDebugInfo());
assertNotEquals(0, code.getDebugInfo().events.length);
long setFileCount =
Arrays.stream(code.getDebugInfo().events)
.filter(dexDebugEvent -> dexDebugEvent instanceof SetFile)
.count();
if (renaming) {
assertEquals(0, setFileCount);
} else {
assertNotEquals(0, setFileCount);
}
}
}