mirror of
https://github.com/darlinghq/darling-openjdk.git
synced 2024-11-23 12:29:56 +00:00
8235474: JShell does not handle records properly
Reviewed-by: vromero, rfield
This commit is contained in:
parent
a20fa5b995
commit
308aea3e0b
@ -140,7 +140,8 @@ module java.base {
|
||||
exports jdk.internal to
|
||||
java.compiler,
|
||||
jdk.jfr,
|
||||
jdk.compiler;
|
||||
jdk.compiler,
|
||||
jdk.jshell;
|
||||
exports jdk.internal.access to
|
||||
java.desktop,
|
||||
java.logging,
|
||||
|
@ -1238,6 +1238,7 @@ public class Check {
|
||||
if ((flags & RECORD) != 0) {
|
||||
// records can't be declared abstract
|
||||
mask &= ~ABSTRACT;
|
||||
implicit |= FINAL;
|
||||
}
|
||||
// Imply STRICTFP if owner has STRICTFP set.
|
||||
implicit |= sym.owner.flags_field & STRICTFP;
|
||||
|
@ -3722,7 +3722,7 @@ public class JavacParser implements Parser {
|
||||
protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) {
|
||||
int pos = token.pos;
|
||||
nextToken();
|
||||
mods.flags |= Flags.RECORD | Flags.FINAL;
|
||||
mods.flags |= Flags.RECORD;
|
||||
Name name = typeName();
|
||||
|
||||
List<JCTypeParameter> typarams = typeParametersOpt();
|
||||
@ -4117,9 +4117,10 @@ public class JavacParser implements Parser {
|
||||
}
|
||||
}
|
||||
|
||||
boolean isRecordStart() {
|
||||
protected boolean isRecordStart() {
|
||||
if (token.kind == IDENTIFIER && token.name() == names.record &&
|
||||
(peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
|
||||
peekToken(TokenKind.IDENTIFIER, TokenKind.EOF) ||
|
||||
peekToken(TokenKind.IDENTIFIER, TokenKind.LT))) {
|
||||
checkSourceLevel(Feature.RECORDS);
|
||||
return true;
|
||||
|
@ -670,12 +670,12 @@ class CompletenessAnalyzer {
|
||||
|
||||
public Completeness parseDeclaration() {
|
||||
boolean isImport = token.kind == IMPORT;
|
||||
boolean isDatum = false;
|
||||
boolean isRecord = false;
|
||||
boolean afterModifiers = false;
|
||||
boolean isBracesNeeded = false;
|
||||
while (token.kind.isDeclaration()) {
|
||||
isBracesNeeded |= token.kind.isBracesNeeded();
|
||||
isDatum |= !afterModifiers && token.kind == TK.IDENTIFIER && token.tok.name() == names.record;
|
||||
isRecord |= !afterModifiers && token.kind == TK.IDENTIFIER && token.tok.name() == names.record;
|
||||
afterModifiers |= !token.kind.isModifier();
|
||||
nextToken();
|
||||
}
|
||||
@ -696,17 +696,11 @@ class CompletenessAnalyzer {
|
||||
case SEMI:
|
||||
return Completeness.COMPLETE;
|
||||
case IDENTIFIER:
|
||||
return isBracesNeeded
|
||||
return isBracesNeeded || isRecord
|
||||
? Completeness.DEFINITELY_INCOMPLETE
|
||||
: Completeness.COMPLETE_WITH_SEMI;
|
||||
case BRACKETS:
|
||||
return Completeness.COMPLETE_WITH_SEMI;
|
||||
case PARENS:
|
||||
if (isDatum) {
|
||||
return Completeness.COMPLETE_WITH_SEMI;
|
||||
} else {
|
||||
return Completeness.DEFINITELY_INCOMPLETE;
|
||||
}
|
||||
case DOTSTAR:
|
||||
if (isImport) {
|
||||
return Completeness.COMPLETE_WITH_SEMI;
|
||||
@ -780,6 +774,7 @@ class CompletenessAnalyzer {
|
||||
case ENUM:
|
||||
case ANNOTATION_TYPE:
|
||||
case INTERFACE:
|
||||
case RECORD:
|
||||
case METHOD:
|
||||
return parseDeclaration();
|
||||
default:
|
||||
|
@ -229,6 +229,10 @@ class Eval {
|
||||
return processClass(userSource, unitTree, compileSourceInt, SubKind.ANNOTATION_TYPE_SUBKIND, pt);
|
||||
case INTERFACE:
|
||||
return processClass(userSource, unitTree, compileSourceInt, SubKind.INTERFACE_SUBKIND, pt);
|
||||
case RECORD:
|
||||
@SuppressWarnings("preview")
|
||||
List<Snippet> snippets = processClass(userSource, unitTree, compileSourceInt, SubKind.RECORD_SUBKIND, pt);
|
||||
return snippets;
|
||||
case METHOD:
|
||||
return processMethod(userSource, unitTree, compileSourceInt, pt);
|
||||
default:
|
||||
|
@ -179,7 +179,7 @@ class ReplParser extends JavacParser {
|
||||
default:
|
||||
JCModifiers mods = modifiersOpt(pmods);
|
||||
if (token.kind == CLASS
|
||||
|| token.kind == IDENTIFIER && token.name() == token.name().table.names.record
|
||||
|| isRecordStart()
|
||||
|| token.kind == INTERFACE
|
||||
|| token.kind == ENUM) {
|
||||
return List.<JCTree>of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
|
||||
|
@ -235,6 +235,23 @@ public abstract class Snippet {
|
||||
*/
|
||||
ENUM_SUBKIND(Kind.TYPE_DECL),
|
||||
|
||||
/**
|
||||
* {@preview Associated with records, a preview feature of the Java language.
|
||||
*
|
||||
* This enum constant is associated with <i>records</i>, a preview
|
||||
* feature of the Java language. Preview features
|
||||
* may be removed in a future release, or upgraded to permanent
|
||||
* features of the Java language.}
|
||||
*
|
||||
* A record declaration.
|
||||
* A {@code SubKind} of {@link Kind#TYPE_DECL}.
|
||||
* @jls 8.10 Record Types
|
||||
* @since 14
|
||||
*
|
||||
*/
|
||||
@jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS)
|
||||
RECORD_SUBKIND(Kind.TYPE_DECL),
|
||||
|
||||
/**
|
||||
* An annotation interface declaration. A {@code SubKind} of
|
||||
* {@link Kind#TYPE_DECL}.
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842 8182268 8223782
|
||||
* @bug 8149524 8131024 8165211 8080071 8130454 8167343 8129559 8114842 8182268 8223782 8235474
|
||||
* @summary Test SourceCodeAnalysis
|
||||
* @build KullaTesting TestingInputStream
|
||||
* @run testng CompletenessTest
|
||||
@ -31,11 +31,15 @@
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.function.Consumer;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import jdk.jshell.JShell;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import jdk.jshell.SourceCodeAnalysis.Completeness;
|
||||
|
||||
import static jdk.jshell.SourceCodeAnalysis.Completeness.*;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
@Test
|
||||
public class CompletenessTest extends KullaTesting {
|
||||
@ -82,6 +86,10 @@ public class CompletenessTest extends KullaTesting {
|
||||
"i >= 0 && Character.isWhitespace(s.charAt(i))",
|
||||
"int.class",
|
||||
"String.class",
|
||||
"record.any",
|
||||
"record()",
|
||||
"record(1)",
|
||||
"record.length()"
|
||||
};
|
||||
|
||||
static final String[] complete_with_semi = new String[] {
|
||||
@ -123,7 +131,7 @@ public class CompletenessTest extends KullaTesting {
|
||||
"int[] m = {1, 2}",
|
||||
"int[] m = {1, 2}, n = null",
|
||||
"int[] m = {1, 2}, n",
|
||||
"int[] m = {1, 2}, n = {3, 4}"
|
||||
"int[] m = {1, 2}, n = {3, 4}",
|
||||
};
|
||||
|
||||
static final String[] considered_incomplete = new String[] {
|
||||
@ -193,6 +201,28 @@ public class CompletenessTest extends KullaTesting {
|
||||
"var v = switch (x) { case ",
|
||||
"var v = switch (x) { case 0:",
|
||||
"var v = switch (x) { case 0: break 12; ",
|
||||
"record D",
|
||||
"record D(",
|
||||
"record D(String",
|
||||
"record D(String i",
|
||||
"record D(String i,",
|
||||
"record D(String i, String",
|
||||
"record D(String i, String j",
|
||||
"record D(String i)",
|
||||
"record D(String i, String j)",
|
||||
"record D(String i) {",
|
||||
"record D(String i, String j) {",
|
||||
"static record D",
|
||||
"static record D(",
|
||||
"static record D(String",
|
||||
"static record D(String i",
|
||||
"static record D(String i,",
|
||||
"static record D(String i, String",
|
||||
"static record D(String i, String j",
|
||||
"static record D(String i)",
|
||||
"static record D(String i, String j)",
|
||||
"static record D(String i) {",
|
||||
"static record D(String i, String j) {",
|
||||
};
|
||||
|
||||
static final String[] unknown = new String[] {
|
||||
@ -241,7 +271,7 @@ public class CompletenessTest extends KullaTesting {
|
||||
}
|
||||
|
||||
public void test_complete() {
|
||||
assertStatus(complete, COMPLETE);
|
||||
assertStatus(complete, COMPLETE);
|
||||
}
|
||||
|
||||
public void test_expression() {
|
||||
@ -349,4 +379,10 @@ public class CompletenessTest extends KullaTesting {
|
||||
assertStatus("int[] m = {1, 2}, n = new int[0]; int i;", COMPLETE,
|
||||
"int[] m = {1, 2}, n = new int[0];");
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
setUp(b -> b.compilerOptions("--enable-preview", "-source", String.valueOf(SourceVersion.latest().ordinal())));
|
||||
}
|
||||
|
||||
}
|
||||
|
65
test/langtools/jdk/jshell/RecordsTest.java
Normal file
65
test/langtools/jdk/jshell/RecordsTest.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8235474
|
||||
* @summary Tests for evalution of records
|
||||
* @modules jdk.jshell
|
||||
* @build KullaTesting TestingInputStream ExpectedDiagnostic
|
||||
* @run testng RecordsTest
|
||||
*/
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.lang.model.SourceVersion;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
@Test
|
||||
public class RecordsTest extends KullaTesting {
|
||||
|
||||
public void testRecordClass() {
|
||||
assertEval("record R(String s, int i) { }");
|
||||
assertEquals(varKey(assertEval("R r = new R(\"r\", 42);")).name(), "r");
|
||||
assertEval("r.s()", "\"r\"");
|
||||
assertEval("r.i()", "42");
|
||||
}
|
||||
|
||||
public void testRecordField() {
|
||||
assertEquals(varKey(assertEval("String record = \"\";")).name(), "record");
|
||||
assertEval("record.length()", "0");
|
||||
}
|
||||
|
||||
public void testRecordMethod() {
|
||||
assertEquals(methodKey(assertEval("String record(String record) { return record + record; }")).name(), "record");
|
||||
assertEval("record(\"r\")", "\"rr\"");
|
||||
assertEval("record(\"r\").length()", "2");
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void setUp() {
|
||||
setUp(b -> b.compilerOptions("--enable-preview", "-source", String.valueOf(SourceVersion.latest().ordinal()))
|
||||
.remoteVMOptions("--enable-preview"));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user