blob: bd50527e201ee7a16f080a631cc43bf1244348af [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.desugar;
import static com.android.tools.r8.references.Reference.classFromClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.D8TestBuilder;
import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestDiagnosticMessages;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.errors.DesugarDiagnostic;
import com.android.tools.r8.errors.InterfaceDesugarMissingTypeDiagnostic;
import com.android.tools.r8.position.Position;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.AndroidApiLevel;
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 DesugarMissingTypeLambdaTest extends TestBase {
static final String EXPECTED = StringUtils.lines("Hello, world");
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimes().withAllApiLevels().build();
}
public DesugarMissingTypeLambdaTest(TestParameters parameters) {
this.parameters = parameters;
}
boolean supportsDefaultInterfaceMethods() {
return parameters.getRuntime().isCf()
|| AndroidApiLevel.N.getLevel() <= parameters.getApiLevel().getLevel();
}
@Test
public void test() throws Exception {
if (parameters.isCfRuntime()) {
testForJvm()
.addProgramClasses(TestClass.class, MissingInterface.class)
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
} else {
D8TestBuilder builder =
testForD8().addProgramClasses(TestClass.class).setMinApi(parameters.getApiLevel());
TestDiagnosticMessages messages = builder.getState().getDiagnosticsMessages();
D8TestCompileResult compileResult = builder.compile();
if (supportsDefaultInterfaceMethods()) {
messages.assertNoMessages();
compileResult
.addRunClasspathFiles(
testForD8()
.setMinApi(parameters.getApiLevel())
.addProgramClasses(MissingInterface.class)
.compile()
.writeToZip())
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED);
} else {
messages.assertOnlyWarnings();
assertEquals(1, messages.getWarnings().size());
Diagnostic diagnostic = messages.getWarnings().get(0);
assertTrue(diagnostic instanceof DesugarDiagnostic);
assertTrue(diagnostic instanceof InterfaceDesugarMissingTypeDiagnostic);
InterfaceDesugarMissingTypeDiagnostic desugarWarning = (InterfaceDesugarMissingTypeDiagnostic) diagnostic;
assertEquals(classFromClass(MissingInterface.class), desugarWarning.getMissingType());
// TODO(b/132671303): The diagnostics should also contain the lambda context, but it should
// not be the synthesized lambda class.
assertFalse(SyntheticItemsTestUtils.isInternalLambda(desugarWarning.getContextType()));
assertEquals(classFromClass(TestClass.class), desugarWarning.getContextType());
assertNotEquals(Position.UNKNOWN, desugarWarning.getPosition());
}
}
}
public interface MissingInterface {
void foo();
default void bar() {
foo();
}
}
static class TestClass {
public static void baz(MissingInterface fn) {
fn.bar();
}
public static void main(String[] args) {
baz(() -> System.out.println("Hello, world"));
}
}
}