| // 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; | |
| import static org.hamcrest.MatcherAssert.assertThat; | |
| import static org.junit.Assert.assertEquals; | |
| import static org.junit.Assert.assertFalse; | |
| import static org.junit.Assert.assertNotEquals; | |
| import static org.junit.Assert.fail; | |
| import com.android.tools.r8.utils.internal.ListUtils; | |
| import com.google.common.collect.Iterables; | |
| import java.util.ArrayList; | |
| import java.util.Collection; | |
| import java.util.List; | |
| import java.util.function.BiFunction; | |
| import org.hamcrest.Matcher; | |
| public class TestDiagnosticMessagesImpl extends TestDiagnosticMessages | |
| implements DiagnosticsHandler { | |
| private final List<Diagnostic> infos = new ArrayList<>(); | |
| private final List<Diagnostic> warnings = new ArrayList<>(); | |
| private final List<Diagnostic> errors = new ArrayList<>(); | |
| BiFunction<DiagnosticsLevel, Diagnostic, DiagnosticsLevel> modifier; | |
| @Override | |
| public String toString() { | |
| StringBuilder builder = new StringBuilder(); | |
| builder.append("Infos: ").append('\n'); | |
| for (Diagnostic info : infos) { | |
| builder.append(" - ").append(info.getDiagnosticMessage()).append('\n'); | |
| } | |
| builder.append("Warnings: ").append('\n'); | |
| for (Diagnostic warning : warnings) { | |
| builder.append(" - ").append(warning.getDiagnosticMessage()).append('\n'); | |
| } | |
| builder.append("Errors: ").append('\n'); | |
| for (Diagnostic error : errors) { | |
| builder.append(" - ").append(error.getDiagnosticMessage()).append('\n'); | |
| } | |
| return builder.toString(); | |
| } | |
| @Override | |
| public void info(Diagnostic info) { | |
| // We are almost always compiling with assertions enabled and R8 will print a message. We | |
| // discard the message here because for almost all tests, this message is not relevant. | |
| if (!info.getDiagnosticMessage() | |
| .equals("Running R8 version " + Version.LABEL + " with assertions enabled.")) { | |
| infos.add(info); | |
| } | |
| } | |
| @Override | |
| public void warning(Diagnostic warning) { | |
| warnings.add(warning); | |
| } | |
| @Override | |
| public void error(Diagnostic error) { | |
| errors.add(error); | |
| } | |
| @Override | |
| public DiagnosticsLevel modifyDiagnosticsLevel(DiagnosticsLevel level, Diagnostic diagnostic) { | |
| return modifier == null ? level : modifier.apply(level, diagnostic); | |
| } | |
| @Override | |
| public List<Diagnostic> getInfos() { | |
| return infos; | |
| } | |
| @Override | |
| public List<Diagnostic> getWarnings() { | |
| return warnings; | |
| } | |
| @Override | |
| public List<Diagnostic> getErrors() { | |
| return errors; | |
| } | |
| private void assertEmpty(String type, List<Diagnostic> messages) { | |
| assertEquals( | |
| "Expected no " | |
| + type | |
| + " messages, got:\n" | |
| + String.join("\n", ListUtils.map(messages, Diagnostic::getDiagnosticMessage)), | |
| 0, | |
| messages.size()); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertNoMessages() { | |
| assertEmpty("info", getInfos()); | |
| assertEmpty("warning", getWarnings()); | |
| assertEmpty("error", getErrors()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertHasWarnings() { | |
| assertFalse(warnings.isEmpty()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertOnlyInfos() { | |
| assertNotEquals(0, getInfos().size()); | |
| assertEmpty("warning", getWarnings()); | |
| assertEmpty("error", getErrors()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertOnlyWarnings() { | |
| assertEmpty("info", getInfos()); | |
| assertNotEquals(0, getWarnings().size()); | |
| assertEmpty("error", getErrors()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertOnlyErrors() { | |
| assertEmpty("info", getInfos()); | |
| assertEmpty("warning", getWarnings()); | |
| assertNotEquals(0, getErrors().size()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertInfosCount(int count) { | |
| assertEquals(count, getInfos().size()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertWarningsCount(int count) { | |
| assertEquals(count, getWarnings().size()); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertErrorsCount(int count) { | |
| assertEquals(count, getErrors().size()); | |
| return this; | |
| } | |
| private TestDiagnosticMessages assertAllDiagnosticsMatches( | |
| Iterable<Diagnostic> diagnostics, String tag, Matcher<Diagnostic> matcher) { | |
| for (Diagnostic diagnostic : diagnostics) { | |
| assertThat(diagnostic, matcher); | |
| } | |
| return this; | |
| } | |
| private TestDiagnosticMessages assertDiagnosticThatMatches( | |
| Iterable<Diagnostic> diagnostics, String tag, Matcher<Diagnostic> matcher) { | |
| int numberOfDiagnostics = 0; | |
| for (Diagnostic diagnostic : diagnostics) { | |
| if (matcher.matches(diagnostic)) { | |
| return this; | |
| } | |
| numberOfDiagnostics++; | |
| } | |
| StringBuilder builder = new StringBuilder("No " + tag + " matches " + matcher.toString()); | |
| builder.append(System.lineSeparator()); | |
| if (numberOfDiagnostics == 0) { | |
| builder.append("There were no " + tag + "s."); | |
| } else { | |
| builder.append("There were " + numberOfDiagnostics + " " + tag + "s:"); | |
| builder.append(System.lineSeparator()); | |
| for (Diagnostic diagnostic : diagnostics) { | |
| builder.append(diagnostic.getDiagnosticMessage()); | |
| builder.append(System.lineSeparator()); | |
| } | |
| } | |
| fail(builder.toString()); | |
| return this; | |
| } | |
| private static void assertDiagnosticsMatch( | |
| Iterable<Diagnostic> diagnostics, String tag, Collection<Matcher<Diagnostic>> matchers) { | |
| assertThat( | |
| diagnostics, | |
| UnorderedCollectionMatcher.matchesOneToOne(matchers, Diagnostic::getDiagnosticMessage)); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertDiagnosticsMatch(Collection<Matcher<Diagnostic>> matchers) { | |
| assertDiagnosticsMatch(getAllDiagnostics(), "diagnostics", matchers); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertInfosMatch(Collection<Matcher<Diagnostic>> matchers) { | |
| assertDiagnosticsMatch(getInfos(), "infos", matchers); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertWarningsMatch(Collection<Matcher<Diagnostic>> matchers) { | |
| assertDiagnosticsMatch(getWarnings(), "warnings", matchers); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertErrorsMatch(Collection<Matcher<Diagnostic>> matchers) { | |
| assertDiagnosticsMatch(getErrors(), "errors", matchers); | |
| return this; | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertDiagnosticThatMatches(Matcher<Diagnostic> matcher) { | |
| return assertDiagnosticThatMatches(getAllDiagnostics(), "diagnostic message", matcher); | |
| } | |
| private Iterable<Diagnostic> getAllDiagnostics() { | |
| return Iterables.concat(getInfos(), getWarnings(), getErrors()); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertInfoThatMatches(Matcher<Diagnostic> matcher) { | |
| return assertDiagnosticThatMatches(getInfos(), "info", matcher); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertWarningThatMatches(Matcher<Diagnostic> matcher) { | |
| return assertDiagnosticThatMatches(getWarnings(), "warning", matcher); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertErrorThatMatches(Matcher<Diagnostic> matcher) { | |
| return assertDiagnosticThatMatches(getErrors(), "error", matcher); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertAllDiagnosticsMatch(Matcher<Diagnostic> matcher) { | |
| return assertAllDiagnosticsMatches(getAllDiagnostics(), "diagnostic message", matcher); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertAllInfosMatch(Matcher<Diagnostic> matcher) { | |
| return assertAllDiagnosticsMatches(getInfos(), "info", matcher); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertAllWarningsMatch(Matcher<Diagnostic> matcher) { | |
| return assertAllDiagnosticsMatches(getWarnings(), "warning", matcher); | |
| } | |
| @Override | |
| public TestDiagnosticMessages assertAllErrorsMatch(Matcher<Diagnostic> matcher) { | |
| return assertAllDiagnosticsMatches(getErrors(), "error", matcher); | |
| } | |
| void setDiagnosticsLevelModifier( | |
| BiFunction<DiagnosticsLevel, Diagnostic, DiagnosticsLevel> modifier) { | |
| this.modifier = modifier; | |
| } | |
| } |