8247456: JShell: Handling of top-level final, abstract, and static modifiers

Reviewed-by: jlahoda
This commit is contained in:
Robert Field 2020-09-02 09:37:25 -07:00
parent a588752fd6
commit 261eb76ea2
13 changed files with 149 additions and 87 deletions

View File

@ -50,6 +50,8 @@ import jdk.jshell.Wrap.CompoundWrap;
import jdk.jshell.Wrap.Range; import jdk.jshell.Wrap.Range;
import jdk.jshell.Wrap.RangeWrap; import jdk.jshell.Wrap.RangeWrap;
import java.util.Set;
/** /**
* Produce a corralled version of the Wrap for a snippet. * Produce a corralled version of the Wrap for a snippet.
*/ */
@ -227,17 +229,21 @@ class Corraller extends Visitor {
bodyBegin = -1; bodyBegin = -1;
} }
} }
if (bodyBegin > 0) { String adjustedSource;
//debugWrap("-visitMethodDef BEGIN: %d = '%s'\n", bodyBegin, if (bodyBegin < 0) {
// source.substring(methodBegin, bodyBegin)); adjustedSource = new MaskCommentsAndModifiers(source, Set.of("abstract")).cleared();
Range noBodyRange = new Range(methodBegin, bodyBegin); bodyBegin = adjustedSource.charAt(methodEnd - 1) == ';'
result = new CompoundWrap( ? methodEnd - 1
new RangeWrap(source, noBodyRange), : methodEnd;
resolutionExceptionBlock);
} else { } else {
Range range = new Range(methodBegin, methodEnd); adjustedSource = source;
result = new RangeWrap(source, range);
} }
debugWrap("-visitMethodDef BEGIN: %d = '%s'\n", bodyBegin,
adjustedSource.substring(methodBegin, bodyBegin));
Range noBodyRange = new Range(methodBegin, bodyBegin);
result = new CompoundWrap(
new RangeWrap(adjustedSource, noBodyRange),
resolutionExceptionBlock);
} }
// Remove initializer, if present // Remove initializer, if present

View File

@ -76,6 +76,9 @@ import static java.util.stream.Collectors.toSet;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol;
import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN; import static jdk.internal.jshell.debug.InternalDebugControl.DBG_GEN;
import static jdk.jshell.Snippet.Status.RECOVERABLE_DEFINED;
import static jdk.jshell.Snippet.Status.RECOVERABLE_NOT_DEFINED;
import static jdk.jshell.Snippet.Status.VALID;
import static jdk.jshell.Util.DOIT_METHOD_NAME; import static jdk.jshell.Util.DOIT_METHOD_NAME;
import static jdk.jshell.Util.PREFIX_PATTERN; import static jdk.jshell.Util.PREFIX_PATTERN;
import static jdk.jshell.Util.expunge; import static jdk.jshell.Util.expunge;
@ -777,21 +780,40 @@ class Eval {
.map(param -> dis.treeToRange(param.getType()).part(compileSource)) .map(param -> dis.treeToRange(param.getType()).part(compileSource))
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
Tree returnType = mt.getReturnType(); Tree returnType = mt.getReturnType();
DiagList modDiag = modifierDiagnostics(mt.getModifiers(), dis, true); DiagList modDiag = modifierDiagnostics(mt.getModifiers(), dis, false);
MethodKey key = state.keyMap.keyForMethod(name, parameterTypes);
// Corralling
Wrap corralled = new Corraller(dis, key.index(), compileSource).corralMethod(mt);
if (modDiag.hasErrors()) { if (modDiag.hasErrors()) {
return compileFailResult(modDiag, userSource, Kind.METHOD); return compileFailResult(modDiag, userSource, Kind.METHOD);
} }
Wrap guts = Wrap.classMemberWrap(compileSource); MethodKey key = state.keyMap.keyForMethod(name, parameterTypes);
Wrap corralled;
Wrap guts;
String unresolvedSelf;
if (mt.getModifiers().getFlags().contains(Modifier.ABSTRACT)) {
if (mt.getBody() == null) {
// abstract method -- pre-corral
corralled = null; // no fall-back
guts = new Corraller(dis, key.index(), compileSource).corralMethod(mt);
unresolvedSelf = "method " + name + "(" + parameterTypes + ")";
} else {
// abstract with body, don't pollute the error message
corralled = null;
guts = Wrap.simpleWrap(compileSource);
unresolvedSelf = null;
}
} else {
// normal method
corralled = new Corraller(dis, key.index(), compileSource).corralMethod(mt);
guts = Wrap.classMemberWrap(compileSource);
unresolvedSelf = null;
}
Range typeRange = dis.treeToRange(returnType); Range typeRange = dis.treeToRange(returnType);
String signature = "(" + parameterTypes + ")" + typeRange.part(compileSource); String signature = "(" + parameterTypes + ")" + typeRange.part(compileSource);
Snippet snip = new MethodSnippet(key, userSource, guts, Snippet snip = new MethodSnippet(key, userSource, guts,
name, signature, name, signature,
corralled, tds.declareReferences(), tds.bodyReferences(), modDiag); corralled, tds.declareReferences(), tds.bodyReferences(),
unresolvedSelf, modDiag);
return singletonList(snip); return singletonList(snip);
} }
@ -891,6 +913,18 @@ class Eval {
ins.add(c); ins.add(c);
Set<Unit> outs = compileAndLoad(ins); Set<Unit> outs = compileAndLoad(ins);
if (si.status().isActive() && si instanceof MethodSnippet) {
// special processing for abstract methods
MethodSnippet msi = (MethodSnippet) si;
String unresolvedSelf = msi.unresolvedSelf;
if (unresolvedSelf != null) {
List<String> unresolved = new ArrayList<>(si.unresolved());
unresolved.add(unresolvedSelf);
si.setCompilationStatus(si.status() == VALID ? RECOVERABLE_DEFINED : si.status(),
unresolved, si.diagnostics());
}
}
if (!si.status().isDefined() if (!si.status().isDefined()
&& si.diagnostics().isEmpty() && si.diagnostics().isEmpty()
&& si.unresolved().isEmpty()) { && si.unresolved().isEmpty()) {
@ -1251,6 +1285,9 @@ class Eval {
fatal = true; fatal = true;
break; break;
case ABSTRACT: case ABSTRACT:
// for classes, abstract is valid
// for variables, generate an error message
// for methods, we generate a placeholder method
if (isAbstractProhibited) { if (isAbstractProhibited) {
list.add(mod); list.add(mod);
fatal = true; fatal = true;
@ -1266,7 +1303,7 @@ class Eval {
//final classes needed for sealed classes //final classes needed for sealed classes
break; break;
case STATIC: case STATIC:
list.add(mod); // everything is static -- warning just adds noise when pasting
break; break;
} }
} }

View File

@ -40,8 +40,11 @@ class MaskCommentsAndModifiers {
Stream.of( "public", "protected", "private", "static" ) Stream.of( "public", "protected", "private", "static" )
.collect( Collectors.toSet() ); .collect( Collectors.toSet() );
private final static Set<String> OTHER_MODIFIERS = private final static Set<String> ALL_MODIFIERS =
Stream.of( "abstract", "strictfp", "transient", "volatile", "synchronized", "native", "default", "final" ) Stream.of(
"public", "protected", "private",
"static", "abstract", "final",
"strictfp", "transient", "volatile", "synchronized", "native", "default" )
.collect( Collectors.toSet() ); .collect( Collectors.toSet() );
// Builder to accumulate non-masked characters // Builder to accumulate non-masked characters
@ -56,6 +59,9 @@ class MaskCommentsAndModifiers {
// Entire input string length // Entire input string length
private final int length; private final int length;
// Which modifiers to mask-out
private final Set<String> ignoredModifiers;
// The next character position // The next character position
private int next = 0; private int next = 0;
@ -70,9 +76,18 @@ class MaskCommentsAndModifiers {
private boolean openToken = false; private boolean openToken = false;
MaskCommentsAndModifiers(String s, boolean maskModifiers) { MaskCommentsAndModifiers(String s, boolean maskModifiers) {
this(s, maskModifiers, IGNORED_MODIFIERS);
}
MaskCommentsAndModifiers(String s, Set<String> ignoredModifiers) {
this(s, true, ignoredModifiers);
}
MaskCommentsAndModifiers(String s, boolean maskModifiers, Set<String> ignoredModifiers) {
this.str = s; this.str = s;
this.length = s.length(); this.length = s.length();
this.maskModifiers = maskModifiers; this.maskModifiers = maskModifiers;
this.ignoredModifiers = ignoredModifiers;
read(); read();
while (c >= 0) { while (c >= 0) {
next(); next();
@ -250,11 +265,11 @@ class MaskCommentsAndModifiers {
} while (Character.isJavaIdentifierPart(c)); } while (Character.isJavaIdentifierPart(c));
unread(); unread();
String id = sb.toString(); String id = sb.toString();
if (maskModifiers && IGNORED_MODIFIERS.contains(id)) { if (maskModifiers && ignoredModifiers.contains(id)) {
writeMask(sb); writeMask(sb);
} else { } else {
write(sb); write(sb);
if (maskModifiers && !OTHER_MODIFIERS.contains(id)) { if (maskModifiers && !ALL_MODIFIERS.contains(id)) {
maskModifiers = false; maskModifiers = false;
} }
} }

View File

@ -42,15 +42,18 @@ import jdk.jshell.Key.MethodKey;
public class MethodSnippet extends DeclarationSnippet { public class MethodSnippet extends DeclarationSnippet {
final String signature; final String signature;
final String unresolvedSelf;
private String qualifiedParameterTypes; private String qualifiedParameterTypes;
MethodSnippet(MethodKey key, String userSource, Wrap guts, MethodSnippet(MethodKey key, String userSource, Wrap guts,
String name, String signature, Wrap corralled, String name, String signature, Wrap corralled,
Collection<String> declareReferences, Collection<String> bodyReferences, Collection<String> declareReferences, Collection<String> bodyReferences,
String unresolvedSelf,
DiagList syntheticDiags) { DiagList syntheticDiags) {
super(key, userSource, guts, name, SubKind.METHOD_SUBKIND, corralled, super(key, userSource, guts, name, SubKind.METHOD_SUBKIND, corralled,
declareReferences, bodyReferences, syntheticDiags); declareReferences, bodyReferences, syntheticDiags);
this.signature = signature; this.signature = signature;
this.unresolvedSelf = unresolvedSelf;
} }
/** /**

View File

@ -237,7 +237,6 @@ final class Unit {
if (dl.hasErrors()) { if (dl.hasErrors()) {
setDiagnostics(dl); setDiagnostics(dl);
status = RECOVERABLE_NOT_DEFINED; status = RECOVERABLE_NOT_DEFINED;
// overwrite orginal bytes
state.debug(DBG_GEN, "++smashingErrorDiagnostics %s\n%s\n-- diags: %s\n", state.debug(DBG_GEN, "++smashingErrorDiagnostics %s\n%s\n-- diags: %s\n",
si, si.outerWrap().wrapped(), dl); si, si.outerWrap().wrapped(), dl);
return true; return true;

View File

@ -23,10 +23,10 @@
# questions. # questions.
# #
jshell.diag.modifier.plural.fatal = Modifiers {0} not permitted in top-level declarations jshell.diag.modifier.plural.fatal = Modifiers {0} not permitted
jshell.diag.modifier.plural.ignore = Modifiers {0} not permitted in top-level declarations, ignored jshell.diag.modifier.plural.ignore = Modifiers {0} not permitted, ignored
jshell.diag.modifier.single.fatal = Modifier {0} not permitted in top-level declarations jshell.diag.modifier.single.fatal = Modifier {0} not permitted
jshell.diag.modifier.single.ignore = Modifier {0} not permitted in top-level declarations, ignored jshell.diag.modifier.single.ignore = Modifier {0} not permitted, ignored
jshell.diag.object.method.fatal = JShell method names must not match Object methods: {0} jshell.diag.object.method.fatal = JShell method names must not match Object methods: {0}
jshell.exc.null = Snippet must not be null jshell.exc.null = Snippet must not be null

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8145239 8129559 8080354 8189248 8010319 8246353 * @bug 8145239 8129559 8080354 8189248 8010319 8246353 8247456
* @summary Tests for EvaluationState.classes * @summary Tests for EvaluationState.classes
* @build KullaTesting TestingInputStream ExpectedDiagnostic * @build KullaTesting TestingInputStream ExpectedDiagnostic
* @run testng ClassesTest * @run testng ClassesTest
@ -249,29 +249,23 @@ public class ClassesTest extends KullaTesting {
public void classesIgnoredModifiers() { public void classesIgnoredModifiers() {
assertEval("public interface A { }"); assertEval("public interface A { }");
assertDeclareWarn1("static class B implements A { }", assertEval("static class B implements A { }");
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING)); assertEval("static interface C extends A { }");
assertDeclareWarn1("static interface C extends A { }",
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING));
assertActiveKeys(); assertActiveKeys();
} }
public void classesIgnoredModifiersAnnotation() { public void classesIgnoredModifiersAnnotation() {
assertEval("public @interface X { }"); assertEval("public @interface X { }");
assertEval("@X public interface A { }"); assertEval("@X public interface A { }");
assertDeclareWarn1("@X static class B implements A { }", assertEval("@X static class B implements A { }");
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING)); assertEval("@X static interface C extends A { }");
assertDeclareWarn1("@X static interface C extends A { }",
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 9, 0, -1, -1, Diagnostic.Kind.WARNING));
assertActiveKeys(); assertActiveKeys();
} }
public void classesIgnoredModifiersOtherModifiers() { public void classesIgnoredModifiersOtherModifiers() {
assertEval("strictfp public interface A { }"); assertEval("strictfp public interface A { }");
assertDeclareWarn1("strictfp static class B implements A { }", assertEval("strictfp static class B implements A { }");
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 15, 0, -1, -1, Diagnostic.Kind.WARNING)); assertEval("strictfp static interface C extends A { }");
assertDeclareWarn1("strictfp static interface C extends A { }",
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 15, 0, -1, -1, Diagnostic.Kind.WARNING));
assertActiveKeys(); assertActiveKeys();
} }

View File

@ -73,21 +73,6 @@ public class ErrorTranslationTest extends ReplToolTesting {
); );
} }
public void testWarnings() {
List<ReplTest> list = new ArrayList<>();
ExpectedDiagnostic[] diagnostics = new ExpectedDiagnostic[]{
newExpectedDiagnostic(0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
newExpectedDiagnostic(0, 5, 0, -1, -1, Diagnostic.Kind.WARNING)};
String[] mods = {"static"};
for (int i = 0; i < mods.length; ++i) {
for (String code : new String[] {"class A {}", "void f() {}", "int a;"}) {
final int finalI = i;
list.add(a -> assertDiagnostic(a, mods[finalI] + " " + code, diagnostics[finalI]));
}
}
test(list.toArray(new ReplTest[list.size()]));
}
@Test(enabled = false) // TODO 8132147 @Test(enabled = false) // TODO 8132147
public void stressTest() { public void stressTest() {
Compiler compiler = new Compiler(); Compiler compiler = new Compiler();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8129559 8246353 * @bug 8129559 8246353 8247456
* @summary Test the ignoring of comments and certain modifiers * @summary Test the ignoring of comments and certain modifiers
* @build KullaTesting TestingInputStream * @build KullaTesting TestingInputStream
* @run testng IgnoreTest * @run testng IgnoreTest
@ -65,8 +65,8 @@ public class IgnoreTest extends KullaTesting {
assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x3 = varKey(assertEval("private int x3;")); VarSnippet x3 = varKey(assertEval("private int x3;"));
assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x4 = (VarSnippet) assertDeclareWarn1("static int x4;", "jdk.eval.warn.illegal.modifiers"); VarSnippet x4 = varKey(assertEval("static int x4;"));
assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1); assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x5 = varKey(assertEval("final int x5;")); VarSnippet x5 = varKey(assertEval("final int x5;"));
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
} }
@ -79,8 +79,8 @@ public class IgnoreTest extends KullaTesting {
assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x3 = varKey(assertEval("@A(value=111)private int x3;")); VarSnippet x3 = varKey(assertEval("@A(value=111)private int x3;"));
assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x4 = (VarSnippet) assertDeclareWarn1("@A static int x4;", "jdk.eval.warn.illegal.modifiers"); VarSnippet x4 = varKey(assertEval("@A static int x4;"));
assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1); assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x5 = varKey(assertEval("@A(1111) final int x5;")); VarSnippet x5 = varKey(assertEval("@A(1111) final int x5;"));
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
} }
@ -92,8 +92,8 @@ public class IgnoreTest extends KullaTesting {
assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x2, "x2", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x3 = varKey(assertEval("transient private int x3;")); VarSnippet x3 = varKey(assertEval("transient private int x3;"));
assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x3, "x3", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x4 = (VarSnippet) assertDeclareWarn1("volatile static int x4;", "jdk.eval.warn.illegal.modifiers"); VarSnippet x4 = varKey(assertEval("volatile static int x4;"));
assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 1); assertVariableDeclSnippet(x4, "x4", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
VarSnippet x5 = varKey(assertEval("transient final int x5;")); VarSnippet x5 = varKey(assertEval("transient final int x5;"));
assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0); assertVariableDeclSnippet(x5, "x5", "int", VALID, VAR_DECLARATION_SUBKIND, 0, 0);
} }
@ -105,23 +105,23 @@ public class IgnoreTest extends KullaTesting {
} }
public void testMethodModifier() { public void testMethodModifier() {
MethodSnippet m4 = (MethodSnippet) assertDeclareWarn1("static void m4() {}", "jdk.eval.warn.illegal.modifiers"); MethodSnippet m4 = methodKey(assertEval("static void m4() {}"));
assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 1); assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 0);
MethodSnippet m5 = methodKey(assertEval("final void m5() {}")); MethodSnippet m5 = methodKey(assertEval("final void m5() {}"));
assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 0); assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 0);
} }
public void testMethodModifierAnnotation() { public void testMethodModifierAnnotation() {
assertEval("@interface A { int value() default 0; }"); assertEval("@interface A { int value() default 0; }");
MethodSnippet m4 = (MethodSnippet) assertDeclareWarn1("@A static void m4() {}", "jdk.eval.warn.illegal.modifiers"); MethodSnippet m4 = methodKey(assertEval("@A static void m4() {}"));
assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 1); assertMethodDeclSnippet(m4, "m4", "()void", VALID, 0, 0);
MethodSnippet m5 = methodKey(assertEval("@A(value=66)final void m5() {}")); MethodSnippet m5 = methodKey(assertEval("@A(value=66)final void m5() {}"));
assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 0); assertMethodDeclSnippet(m5, "m5", "()void", VALID, 0, 0);
} }
public void testClassModifier() { public void testClassModifier() {
TypeDeclSnippet c4 = (TypeDeclSnippet) assertDeclareWarn1("static class C4 {}", "jdk.eval.warn.illegal.modifiers"); TypeDeclSnippet c4 = classKey(assertEval("static class C4 {}"));
assertTypeDeclSnippet(c4, "C4", VALID, CLASS_SUBKIND, 0, 1); assertTypeDeclSnippet(c4, "C4", VALID, CLASS_SUBKIND, 0, 0);
TypeDeclSnippet c5 = classKey(assertEval("final class C5 {}")); TypeDeclSnippet c5 = classKey(assertEval("final class C5 {}"));
assertTypeDeclSnippet(c5, "C5", VALID, CLASS_SUBKIND, 0, 0); assertTypeDeclSnippet(c5, "C5", VALID, CLASS_SUBKIND, 0, 0);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8080357 8167643 8187359 8199762 8080353 8246353 * @bug 8080357 8167643 8187359 8199762 8080353 8246353 8247456
* @summary Tests for EvaluationState.methods * @summary Tests for EvaluationState.methods
* @build KullaTesting TestingInputStream ExpectedDiagnostic * @build KullaTesting TestingInputStream ExpectedDiagnostic
* @run testng MethodsTest * @run testng MethodsTest
@ -36,7 +36,11 @@ import jdk.jshell.MethodSnippet;
import jdk.jshell.Snippet.Status; import jdk.jshell.Snippet.Status;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.util.List;
import java.util.stream.Collectors;
import static jdk.jshell.Snippet.Status.*; import static jdk.jshell.Snippet.Status.*;
import static org.testng.Assert.assertEquals;
@Test @Test
public class MethodsTest extends KullaTesting { public class MethodsTest extends KullaTesting {
@ -216,17 +220,28 @@ public class MethodsTest extends KullaTesting {
assertActiveKeys(); assertActiveKeys();
} }
public void methodsAbstract() {
MethodSnippet m1 = methodKey(assertEval("abstract String f();",
ste(MAIN_SNIPPET, NONEXISTENT, RECOVERABLE_DEFINED, true, null)));
assertEquals(getState().unresolvedDependencies(m1).collect(Collectors.toList()),
List.of("method f()"));
MethodSnippet m2 = methodKey(assertEval("abstract int mm(Blah b);",
ste(MAIN_SNIPPET, NONEXISTENT, RECOVERABLE_NOT_DEFINED, false, null)));
List<String> unr = getState().unresolvedDependencies(m2).collect(Collectors.toList());
assertEquals(unr.size(), 2);
unr.remove("class Blah");
unr.remove("method mm(Blah)");
assertEquals(unr.size(), 0, "unexpected entry: " + unr);
assertNumberOfActiveMethods(2);
assertActiveKeys();
}
public void methodsErrors() { public void methodsErrors() {
assertDeclareFail("String f();", assertDeclareFail("String f();",
new ExpectedDiagnostic("compiler.err.missing.meth.body.or.decl.abstract", 0, 11, 7, -1, -1, Diagnostic.Kind.ERROR)); new ExpectedDiagnostic("compiler.err.missing.meth.body.or.decl.abstract", 0, 11, 7, -1, -1, Diagnostic.Kind.ERROR));
assertNumberOfActiveMethods(0); assertNumberOfActiveMethods(0);
assertActiveKeys(); assertActiveKeys();
assertDeclareFail("abstract String f();",
new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 8, 0, -1, -1, Diagnostic.Kind.ERROR));
assertNumberOfActiveMethods(0);
assertActiveKeys();
assertDeclareFail("native String f();", assertDeclareFail("native String f();",
new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.ERROR)); new ExpectedDiagnostic("jdk.eval.error.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.ERROR));
assertNumberOfActiveMethods(0); assertNumberOfActiveMethods(0);
@ -290,10 +305,8 @@ public class MethodsTest extends KullaTesting {
assertActiveKeys(); assertActiveKeys();
} }
public void methodsWarn() { public void methodsIgnoredModifiers() {
Snippet f = assertDeclareWarn1("static String f() {return null;}", Snippet f = methodKey(assertEval("static String f() {return null;}"));
new ExpectedDiagnostic("jdk.eval.warn.illegal.modifiers", 0, 6, 0, -1, -1, Diagnostic.Kind.WARNING),
added(VALID));
assertNumberOfActiveMethods(1); assertNumberOfActiveMethods(1);
assertActiveKeys(); assertActiveKeys();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,7 +22,7 @@
*/ */
/* /*
* @test 8167643 8129559 * @test 8167643 8129559 8247456
* @summary Tests for modifiers * @summary Tests for modifiers
* @build KullaTesting TestingInputStream ExpectedDiagnostic * @build KullaTesting TestingInputStream ExpectedDiagnostic
* @run testng ModifiersTest * @run testng ModifiersTest
@ -44,10 +44,9 @@ public class ModifiersTest extends KullaTesting {
public Object[][] getTestCases() { public Object[][] getTestCases() {
List<Object[]> testCases = new ArrayList<>(); List<Object[]> testCases = new ArrayList<>();
String[] ignoredModifiers = new String[] { String[] ignoredModifiers = new String[] {
"static"
}; };
String[] silentlyIgnoredModifiers = new String[] { String[] silentlyIgnoredModifiers = new String[] {
"public", "protected", "private" "public", "protected", "private", "static"
}; };
String[] before = new String[] { String[] before = new String[] {
"strictfp", "abstract", "final", "@X", "@X(value=9)" "strictfp", "abstract", "final", "@X", "@X(value=9)"

View File

@ -699,8 +699,7 @@ public class ToolBasicTest extends ReplToolTesting {
a -> assertCommand(a, "/set feedback " + off, ""), a -> assertCommand(a, "/set feedback " + off, ""),
a -> assertCommand(a, "int a", ""), a -> assertCommand(a, "int a", ""),
a -> assertCommand(a, "void f() {}", ""), a -> assertCommand(a, "void f() {}", ""),
a -> assertCommandCheckOutput(a, "aaaa", assertStartsWith("| Error:")), a -> assertCommandCheckOutput(a, "aaaa", assertStartsWith("| Error:"))
a -> assertCommandCheckOutput(a, "static void f() {}", assertStartsWith("| Warning:"))
); );
} }
} }

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797 8177079 8180508 8177466 8172154 8192979 8191842 8198573 8198801 8210596 8210959 8215099 8199623 8236715 8239536 * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797 8177079 8180508 8177466 8172154 8192979 8191842 8198573 8198801 8210596 8210959 8215099 8199623 8236715 8239536 8247456
* @summary Simple jshell tool tests * @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.main
@ -270,6 +270,18 @@ public class ToolSimpleTest extends ReplToolTesting {
); );
} }
@Test
public void testAbstractMethod() {
test(
(a) -> assertCommand(a, "abstract int f(int x);",
"| created method f(int), however, it cannot be invoked until method f(int) is declared"),
(a) -> assertCommand(a, "f(13)",
"| attempted to call method f(int) which cannot be invoked until method f(int) is declared"),
(a) -> assertCommand(a, " abstract void m(Blah b);",
"| created method m(Blah), however, it cannot be referenced until class Blah, and method m(Blah) are declared")
);
}
// 8199623 // 8199623
@Test @Test
public void testTwoForkedDrop() { public void testTwoForkedDrop() {