Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test fixes #173

Merged
merged 10 commits into from
Apr 17, 2024
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,10 @@ tasks.withType(Test).configureEach {

test {
include '**/NullSpecTest$Minimal.class'

inputs.files("${rootDir}/tests/minimal")

include '**/NullSpecTest$Regression.class'
inputs.files("${rootDir}/tests/regression")
}

tasks.register('jspecifySamplesTest', Test) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import com.sun.source.tree.AssignmentTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.Tree;
import java.util.List;
Expand Down Expand Up @@ -85,9 +84,6 @@ protected void reportTreeType(
String methodName = calledElem.getSimpleName().toString();
AnnotatedExecutableType calledType = (AnnotatedExecutableType) type;
List<? extends AnnotatedTypeMirror> params = calledType.getParameterTypes();
MethodInvocationTree mit = (MethodInvocationTree) tree;
List<? extends ExpressionTree> args = mit.getArguments();
assert params.size() == args.size();

for (int i = 0; i < params.size(); ++i) {
String paramName = calledElem.getParameters().get(i).getSimpleName().toString();
Expand Down
6 changes: 2 additions & 4 deletions src/test/java/tests/ConformanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
Expand Down Expand Up @@ -142,8 +141,7 @@ private static ImmutableSet<ReportedFact> analyze(
TestUtilities.getShouldEmitDebugInfo());
TypecheckResult result = new TypecheckExecutor().runTest(config);
return result.getUnexpectedDiagnostics().stream()
.map(d -> DetailMessage.parse(d.getMessage(), testDirectory))
.filter(Objects::nonNull)
.map(d -> DetailMessage.parse(d, testDirectory))
// Do not filter out messages without details.
// .filter(DetailMessage::hasDetails)
.map(DetailMessageReportedFact::new)
Expand Down Expand Up @@ -182,7 +180,7 @@ static final class DetailMessageReportedFact extends ReportedFact {
private final DetailMessage detailMessage;

DetailMessageReportedFact(DetailMessage detailMessage) {
super(detailMessage.file, detailMessage.lineNumber);
super(detailMessage.getFile(), detailMessage.getLineNumber());
this.detailMessage = detailMessage;
}

Expand Down
64 changes: 21 additions & 43 deletions src/test/java/tests/DetailMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.getLast;
import static java.lang.Integer.parseInt;
import static java.util.Arrays.stream;
import static java.util.regex.Pattern.DOTALL;
import static java.util.stream.Collectors.joining;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
Expand All @@ -30,13 +27,6 @@
*/
final class DetailMessage extends TestDiagnostic {

private static final Pattern MESSAGE_PATTERN =
Pattern.compile(
"(?<file>\\S+):(?<lineNumber>\\d+): (?<kind>"
+ stream(DiagnosticKind.values()).map(k -> k.parseString).collect(joining("|"))
+ "): (?<message>.*)",
DOTALL);

/** Parser for the output for -Adetailedmsgtext. */
// Implemented here: org.checkerframework.framework.source.SourceChecker#detailedMsgTextPrefix
private static final Pattern DETAIL_MESSAGE_PATTERN =
Expand All @@ -49,12 +39,6 @@ final class DetailMessage extends TestDiagnostic {
private static final Pattern OFFSETS_PATTERN =
Pattern.compile("(\\( (?<start>-?\\d+), (?<end>-?\\d+) \\))?");

/** The path to the source file containing the diagnostic. */
final Path file;

/** The line number (1-based) of the diagnostic in the {@link #file}. */
final int lineNumber;

/** The message key for the user-visible text message that is emitted. */
final String messageKey;

Expand All @@ -71,30 +55,30 @@ final class DetailMessage extends TestDiagnostic {
final String readableMessage;

/**
* Returns an object parsed from a diagnostic message, or {@code null} if the message doesn't
* match the expected format.
* Returns an object parsed from a diagnostic message.
*
* @param rootDirectory if not null, a root directory prefix to remove from the file part of the
* message
*/
static @Nullable DetailMessage parse(String input, @Nullable Path rootDirectory) {
Matcher messageMatcher = MESSAGE_PATTERN.matcher(input);
if (!messageMatcher.matches()) {
return null;
}

Path file = Paths.get(messageMatcher.group("file"));
if (rootDirectory != null) {
static DetailMessage parse(TestDiagnostic input, @Nullable Path rootDirectory) {
Path file = input.getFile();
if (rootDirectory != null && file.startsWith(rootDirectory)) {
// Empty file strings cannot be relativized.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can remove this comment.

file = rootDirectory.relativize(file);
}
int lineNumber = parseInt(messageMatcher.group("lineNumber"));
DiagnosticKind kind = DiagnosticKind.fromParseString(messageMatcher.group("kind"));

String message = messageMatcher.group("message");
Matcher detailsMatcher = DETAIL_MESSAGE_PATTERN.matcher(message);
Matcher detailsMatcher = DETAIL_MESSAGE_PATTERN.matcher(input.getMessage());
if (!detailsMatcher.matches()) {
// Return a message with no key or parts.
return new DetailMessage(file, lineNumber, kind, "", ImmutableList.of(), null, null, message);
return new DetailMessage(
file,
input.getLineNumber(),
input.getKind(),
"",
ImmutableList.of(),
null,
null,
input.getMessage());
}

int messagePartCount = parseInt(detailsMatcher.group("messagePartCount"));
Expand All @@ -112,8 +96,8 @@ final class DetailMessage extends TestDiagnostic {

return new DetailMessage(
file,
lineNumber,
kind,
input.getLineNumber(),
input.getKind(),
detailsMatcher.group("messageKey"),
messageArguments,
intOrNull(offsetsMatcher.group("start")),
Expand All @@ -127,28 +111,21 @@ private static Integer intOrNull(String input) {

private DetailMessage(
Path file,
int lineNumber,
long lineNumber,
DiagnosticKind diagnosticKind,
String messageKey,
ImmutableList<String> messageArguments,
Integer offsetStart,
Integer offsetEnd,
String readableMessage) {
super(file.toString(), lineNumber, diagnosticKind, readableMessage, false, true);
this.file = file;
this.lineNumber = lineNumber;
super(file, lineNumber, diagnosticKind, readableMessage, false);
this.messageKey = messageKey;
this.messageArguments = messageArguments;
this.offsetStart = offsetStart;
this.offsetEnd = offsetEnd;
this.readableMessage = readableMessage;
}

/** The last part of the {@link #file}. */
String getFileName() {
return file.getFileName().toString();
}

/**
* True if this was parsed from an actual {@code -Adetailedmsgtext} message; false if this was
* some other diagnostic.
Expand Down Expand Up @@ -183,14 +160,15 @@ public int hashCode() {

@Override
public String toString() {
return String.format("%s:%d: (%s) %s", file, lineNumber, messageKey, readableMessage);
return String.format("%s:%d:%s: (%s) %s", file, lineNumber, kind, messageKey, readableMessage);
}

/** String format for debugging use. */
String toDetailedString() {
return toStringHelper(this)
.add("file", file)
.add("lineNumber", lineNumber)
.add("kind", kind)
.add("messageKey", messageKey)
.add("messageArguments", messageArguments)
.add("offsetStart", offsetStart)
Expand Down
18 changes: 15 additions & 3 deletions src/test/java/tests/NullSpecTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ public static String[] getTestDirs() {
}
}

/** A small set of regression tests. */
public static class Regression extends NullSpecTest {
public Regression(List<File> testFiles) {
super(testFiles, false);
}

@Parameters
public static String[] getTestDirs() {
return new String[] {"regression"};
}
}

/** A test that ignores cases where there is limited nullness information. */
public static class Lenient extends NullSpecTest {
public Lenient(List<File> testFiles) {
Expand Down Expand Up @@ -105,7 +117,7 @@ public TypecheckResult adjustTypecheckResult(TypecheckResult testResult) {

for (ListIterator<TestDiagnostic> i = unexpected.listIterator(); i.hasNext(); ) {
TestDiagnostic diagnostic = i.next();
DetailMessage detailMessage = DetailMessage.parse(diagnostic.getMessage(), null);
DetailMessage detailMessage = DetailMessage.parse(diagnostic, null);
if (detailMessage != null && detailMessage.hasDetails()) {
// Replace diagnostics that can be parsed with DetailMessage diagnostics.
i.set(detailMessage);
Expand Down Expand Up @@ -145,8 +157,8 @@ private boolean corresponds(TestDiagnostic missing, TestDiagnostic unexpected) {
*/
private boolean corresponds(TestDiagnostic missing, DetailMessage unexpected) {
// First, make sure the two diagnostics are on the same file and line.
if (!missing.getFilename().equals(unexpected.getFileName())
|| missing.getLineNumber() != unexpected.lineNumber) {
if (!missing.getFilename().equals(unexpected.getFilename())
|| missing.getLineNumber() != unexpected.getLineNumber()) {
return false;
}

Expand Down
Loading