blob: 971aee5a88a755a1a51df01c4ea6e936a0f486a4 [file] [log] [blame]
// Copyright (c) 2019, 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.proguard.rules;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.fail;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.utils.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class NegatedClassMemberTest extends TestBase {
@Test
public void testProguard() {
try {
testForProguard()
.addProgramClasses(
NegatedClassMemberTestClassA.class,
NegatedClassMemberTestClassB.class,
NegatedClassMemberTestClassC.class)
.addKeepRules(getKeepRule())
.compile();
// For some reason, Proguard fails with "The output jar is empty". One likely explanation is
// that Proguard only keeps classes that have a field y with type "!long", which is not a
// valid type name, and therefore never matches anything.
fail("Expected Proguard to fail with \"The output jar is empty\"");
} catch (CompilationFailedException e) {
assertThat(e.getMessage(), containsString("The output jar is empty"));
}
}
@Test
public void testR8() throws Exception {
try {
testForR8(Backend.DEX)
.addProgramClasses(
NegatedClassMemberTestClassA.class,
NegatedClassMemberTestClassB.class,
NegatedClassMemberTestClassC.class)
.addKeepRules(getKeepRule())
.compile();
fail("Expected R8 to fail during parsing of the Proguard configuration file");
} catch (CompilationFailedException e) {
int expectedOffset = getKeepRule().indexOf("!");
int expectedColumn = expectedOffset + 1;
assertThat(
e.getCause().getMessage(),
allOf(
containsString(
"Error: offset: "
+ expectedOffset
+ ", line: 1, column: "
+ expectedColumn
+ ", Unexpected character '!': "
+ "The negation character can only be used to negate access flags"),
containsString(
StringUtils.join(
"\n",
"-keepclasseswithmembers class ** { long x; !long y; }",
" ^"))));
}
}
private String getKeepRule() {
return "-keepclasseswithmembers class ** { long x; !long y; }";
}
}
class NegatedClassMemberTestClassA {
long x = System.currentTimeMillis();
}
class NegatedClassMemberTestClassB {
long x = System.currentTimeMillis();
private long y = System.currentTimeMillis();
}
class NegatedClassMemberTestClassC {
long x = System.currentTimeMillis();
int y = (int) System.currentTimeMillis();
}