blob: a52c76203f324a90a27b754c9653e929f1c2b6cd [file] [log] [blame]
// Copyright (c) 2018, 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.invalid;
import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.jasmin.JasminTestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class DuplicateDefinitionsTest extends JasminTestBase {
@Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withDefaultDexRuntime().withApiLevel(AndroidApiLevel.B).build();
}
private final TestParameters parameters;
public DuplicateDefinitionsTest(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testDuplicateMethods() throws Exception {
JasminBuilder jasminBuilder = new JasminBuilder();
ClassBuilder classBuilder = jasminBuilder.addClass("C");
classBuilder.addMainMethod(".limit locals 1", ".limit stack 0", "return");
classBuilder.addMainMethod(".limit locals 1", ".limit stack 0", "return");
classBuilder.addVirtualMethod("method", "V", ".limit locals 1", ".limit stack 0", "return");
classBuilder.addVirtualMethod("method", "V", ".limit locals 1", ".limit stack 0", "return");
testForD8(parameters.getBackend())
.addProgramClassFileData(jasminBuilder.buildClasses())
.setMinApi(parameters.getApiLevel())
.compileWithExpectedDiagnostics(
diagnostics ->
diagnostics
.assertOnlyWarnings()
.assertWarningsMatch(
diagnosticMessage(
containsString(
"Ignoring an implementation of the method `void"
+ " C.main(java.lang.String[])` because it has multiple"
+ " definitions")),
diagnosticMessage(
containsString(
"Ignoring an implementation of the method `void C.method()` because"
+ " it has multiple definitions"))))
.inspect(
inspector -> {
ClassSubject clazz = inspector.clazz("C");
assertThat(clazz, isPresent());
// There are two direct methods, but only because one is <init>.
assertEquals(
2, clazz.getDexProgramClass().getMethodCollection().numberOfDirectMethods());
assertThat(clazz.method("void", "<init>", ImmutableList.of()), isPresent());
// There is only one virtual method.
assertEquals(
1, clazz.getDexProgramClass().getMethodCollection().numberOfVirtualMethods());
});
}
@Test
public void testDuplicateFields() throws Exception {
JasminBuilder jasminBuilder = new JasminBuilder();
ClassBuilder classBuilder = jasminBuilder.addClass("C");
classBuilder.addField("public", "fld", "LC;", null);
classBuilder.addField("public", "fld", "LC;", null);
classBuilder.addStaticField("staticFld", "LC;", null);
classBuilder.addStaticField("staticFld", "LC;", null);
testForD8(parameters.getBackend())
.addProgramClassFileData(jasminBuilder.buildClasses())
.setMinApi(parameters.getApiLevel())
.compileWithExpectedDiagnostics(
diagnostics ->
diagnostics
.assertOnlyWarnings()
.assertWarningsMatch(
diagnosticMessage(
containsString("Field `C C.fld` has multiple definitions")),
diagnosticMessage(
containsString("Field `C C.staticFld` has multiple definitions"))))
.inspect(
inspector -> {
ClassSubject clazz = inspector.clazz("C");
assertThat(clazz, isPresent());
// Redundant fields have been removed.
assertEquals(1, clazz.getDexProgramClass().instanceFields().size());
assertEquals(1, clazz.getDexProgramClass().staticFields().size());
});
}
}