8341176: Permit access to diagnostics for transient snippets
Reviewed-by: vromero
This commit is contained in:
parent
a93bd9dfdd
commit
5ca6698ba4
@ -176,7 +176,16 @@ class Eval {
|
||||
List<Snippet> toScratchSnippets(String userSource) {
|
||||
try {
|
||||
preserveState = true;
|
||||
return sourceToSnippets(userSource);
|
||||
List<Snippet> result = sourceToSnippetsWithWrappers(userSource);
|
||||
result.forEach(snippet -> {
|
||||
if (snippet.diagnostics() == null || snippet.diagnostics().isEmpty()) {
|
||||
//if no better diagnostics set yet, do trial compilation, and
|
||||
//set diagnostic found:
|
||||
DiagList fullDiagnostics = state.taskFactory.analyze(snippet.outerWrap(), AnalyzeTask::getDiagnostics);
|
||||
snippet.setDiagnostics(fullDiagnostics);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
} finally {
|
||||
preserveState = false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -678,6 +678,12 @@ public class JShell implements AutoCloseable {
|
||||
* Return the diagnostics of the most recent evaluation of the snippet.
|
||||
* The evaluation can either because of an explicit {@code eval()} call or
|
||||
* an automatic update triggered by a dependency.
|
||||
*
|
||||
* <p>This method will return best-effort diagnostics for snippets returned
|
||||
* from {@link SourceCodeAnalysis#sourceToSnippets(java.lang.String) }. The
|
||||
* diagnostics returned for such snippets may differ from diagnostics provided
|
||||
* after the snippet is {@link #eval(java.lang.String) }-ed.
|
||||
*
|
||||
* @param snippet the {@code Snippet} to look up
|
||||
* @return the diagnostics corresponding to this snippet. This does not
|
||||
* include unresolvedDependencies references reported in {@code unresolvedDependencies()}.
|
||||
@ -686,7 +692,7 @@ public class JShell implements AutoCloseable {
|
||||
* this {@code JShell} instance.
|
||||
*/
|
||||
public Stream<Diag> diagnostics(Snippet snippet) {
|
||||
return checkValidSnippet(snippet).diagnostics().stream();
|
||||
return checkValidSnippet(snippet, true).diagnostics().stream();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -901,10 +907,22 @@ public class JShell implements AutoCloseable {
|
||||
* @return the input Snippet (for chained calls)
|
||||
*/
|
||||
private Snippet checkValidSnippet(Snippet sn) {
|
||||
return checkValidSnippet(sn, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a Snippet parameter coming from the API user
|
||||
* @param sn the Snippet to check
|
||||
* @param acceptUnassociated accept snippets that are unassociated
|
||||
* @throws NullPointerException if Snippet parameter is null
|
||||
* @throws IllegalArgumentException if Snippet is not from this JShell
|
||||
* @return the input Snippet (for chained calls)
|
||||
*/
|
||||
private Snippet checkValidSnippet(Snippet sn, boolean acceptUnassociated) {
|
||||
if (sn == null) {
|
||||
throw new NullPointerException(messageFormat("jshell.exc.null"));
|
||||
} else {
|
||||
if (sn.key().state() != this || sn.id() == Snippet.UNASSOCIATED_ID) {
|
||||
if (sn.key().state() != this || (!acceptUnassociated && sn.id() == Snippet.UNASSOCIATED_ID)) {
|
||||
throw new IllegalArgumentException(messageFormat("jshell.exc.alien", sn.toString()));
|
||||
}
|
||||
return sn;
|
||||
|
@ -145,7 +145,8 @@ public abstract class SourceCodeAnalysis {
|
||||
* will be {@code "*UNASSOCIATED*"}.
|
||||
* The returned snippets are not associated with the
|
||||
* {@link JShell} instance, so attempts to pass them to {@code JShell}
|
||||
* methods will throw an {@code IllegalArgumentException}.
|
||||
* methods will throw an {@code IllegalArgumentException}, unless otherwise
|
||||
* noted.
|
||||
* They will not appear in queries for snippets --
|
||||
* for example, {@link JShell#snippets() }.
|
||||
* <p>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8182270
|
||||
* @bug 8182270 8341176
|
||||
* @summary test non-eval Snippet analysis
|
||||
* @build KullaTesting TestingInputStream
|
||||
* @run testng AnalyzeSnippetTest
|
||||
@ -32,8 +32,10 @@
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import jdk.jshell.Snippet;
|
||||
import jdk.jshell.DeclarationSnippet;
|
||||
import jdk.jshell.Diag;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import jdk.jshell.JShell;
|
||||
@ -52,6 +54,7 @@ import jdk.jshell.StatementSnippet;
|
||||
import jdk.jshell.TypeDeclSnippet;
|
||||
import jdk.jshell.VarSnippet;
|
||||
import static jdk.jshell.Snippet.SubKind.*;
|
||||
import jdk.jshell.SourceCodeAnalysis.SnippetWrapper;
|
||||
|
||||
@Test
|
||||
public class AnalyzeSnippetTest {
|
||||
@ -141,6 +144,49 @@ public class AnalyzeSnippetTest {
|
||||
SubKind.UNKNOWN_SUBKIND);
|
||||
}
|
||||
|
||||
public void testDiagnosticsForSourceSnippet() {
|
||||
Snippet sn;
|
||||
sn = assertSnippet("unknown()", UNKNOWN_SUBKIND);
|
||||
assertDiagnostics(sn, "0-7:compiler.err.cant.resolve.location.args");
|
||||
sn = assertSnippet("new String(null, )", UNKNOWN_SUBKIND);
|
||||
assertDiagnostics(sn, "17-17:compiler.err.illegal.start.of.expr");
|
||||
sn = assertSnippet("1 + ", UNKNOWN_SUBKIND);
|
||||
assertDiagnostics(sn, "3-3:compiler.err.premature.eof");
|
||||
sn = assertSnippet("class C {", UNKNOWN_SUBKIND);
|
||||
assertDiagnostics(sn, "9-9:compiler.err.premature.eof");
|
||||
sn = assertSnippet("class C {}", CLASS_SUBKIND);
|
||||
assertDiagnostics(sn);
|
||||
sn = assertSnippet("void t() { throw new java.io.IOException(); }", METHOD_SUBKIND);
|
||||
assertDiagnostics(sn, "11-43:compiler.err.unreported.exception.need.to.catch.or.throw");
|
||||
sn = assertSnippet("void t() { unknown(); }", METHOD_SUBKIND);
|
||||
assertDiagnostics(sn, "11-18:compiler.err.cant.resolve.location.args");
|
||||
sn = assertSnippet("import unknown.unknown;", SINGLE_TYPE_IMPORT_SUBKIND);
|
||||
assertDiagnostics(sn, "7-22:compiler.err.doesnt.exist");
|
||||
}
|
||||
|
||||
public void testSnippetWrapper() {
|
||||
SourceCodeAnalysis analysis = state.sourceCodeAnalysis();
|
||||
Snippet sn;
|
||||
String code = "unknown()";
|
||||
sn = assertSnippet(code, UNKNOWN_SUBKIND);
|
||||
SnippetWrapper wrapper = analysis.wrapper(sn);
|
||||
String wrapped = wrapper.wrapped();
|
||||
assertEquals(wrapped, """
|
||||
package REPL;
|
||||
|
||||
class $JShell$DOESNOTMATTER {
|
||||
public static java.lang.Object do_it$() throws java.lang.Throwable {
|
||||
return unknown();
|
||||
}
|
||||
}
|
||||
""");
|
||||
for (int pos = 0; pos < code.length(); pos++) {
|
||||
int wrappedPos = wrapper.sourceToWrappedPosition(pos);
|
||||
assertEquals(wrapped.charAt(wrappedPos), code.charAt(pos));
|
||||
assertEquals(wrapper.wrappedToSourcePosition(wrappedPos), pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void testNoStateChange() {
|
||||
assertSnippet("int a = 5;", SubKind.VAR_DECLARATION_WITH_INITIALIZER_SUBKIND);
|
||||
assertSnippet("a", SubKind.UNKNOWN_SUBKIND);
|
||||
@ -159,4 +205,14 @@ public class AnalyzeSnippetTest {
|
||||
assertEquals(sn.subKind(), sk);
|
||||
return sn;
|
||||
}
|
||||
|
||||
private String diagToString(Diag d) {
|
||||
return d.getStartPosition() + "-" + d.getEndPosition() + ":" + d.getCode();
|
||||
}
|
||||
|
||||
private void assertDiagnostics(Snippet s, String... expectedDiags) {
|
||||
List<String> actual = state.diagnostics(s).map(this::diagToString).toList();
|
||||
List<String> expected = List.of(expectedDiags);
|
||||
assertEquals(actual, expected);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user