Skip to content

Commit 63d4afb

Browse files
committed
8304671: javac regression: Compilation with --release 8 fails on underscore in enum identifiers
Reviewed-by: vromero, darcy
1 parent e2cfcfb commit 63d4afb

File tree

2 files changed

+188
-9
lines changed

2 files changed

+188
-9
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -4303,10 +4303,13 @@ List<JCTree> enumBody(Name enumName) {
43034303
return defs.toList();
43044304
}
43054305

4306+
@SuppressWarnings("fallthrough")
43064307
private EnumeratorEstimate estimateEnumeratorOrMember(Name enumName) {
43074308
// if we are seeing a record declaration inside of an enum we want the same error message as expected for a
43084309
// let's say an interface declaration inside an enum
4309-
if (token.kind == TokenKind.IDENTIFIER && token.name() != enumName &&
4310+
boolean ident = token.kind == TokenKind.IDENTIFIER ||
4311+
token.kind == TokenKind.UNDERSCORE;
4312+
if (ident && token.name() != enumName &&
43104313
(!allowRecords || !isRecordStart())) {
43114314
Token next = S.token(1);
43124315
switch (next.kind) {
@@ -4315,12 +4318,11 @@ private EnumeratorEstimate estimateEnumeratorOrMember(Name enumName) {
43154318
}
43164319
}
43174320
switch (token.kind) {
4318-
case IDENTIFIER: case MONKEYS_AT: case LT:
4319-
if (token.kind == IDENTIFIER) {
4320-
if (allowRecords && isRecordStart()) {
4321-
return EnumeratorEstimate.MEMBER;
4322-
}
4321+
case IDENTIFIER:
4322+
if (allowRecords && isRecordStart()) {
4323+
return EnumeratorEstimate.MEMBER;
43234324
}
4325+
case MONKEYS_AT: case LT: case UNDERSCORE:
43244326
return EnumeratorEstimate.UNKNOWN;
43254327
default:
43264328
return EnumeratorEstimate.MEMBER;

test/langtools/tools/javac/parser/JavacParserTest.java

Lines changed: 179 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8271928 8275097 8293897 8295401
26+
* @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8271928 8275097 8293897 8295401 8304671
2727
* @summary tests error and diagnostics positions
2828
* @author Jan Lahoda
2929
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -2061,6 +2061,183 @@ public Void visitModule(ModuleTree node, Void p) {
20612061
});
20622062
}
20632063

2064+
@Test //JDK-8304671
2065+
void testEnumConstantUnderscore() throws IOException {
2066+
record TestCase(String code, String release, String ast, String errors) {}
2067+
TestCase[] testCases = new TestCase[] {
2068+
new TestCase("""
2069+
package t;
2070+
enum Test {
2071+
_
2072+
}
2073+
""",
2074+
"8",
2075+
"""
2076+
package t;
2077+
\n\
2078+
enum Test {
2079+
/*public static final*/ _ /* = new Test() */ /*enum*/ ;
2080+
} """,
2081+
"""
2082+
- compiler.warn.option.obsolete.source: 8
2083+
- compiler.warn.option.obsolete.target: 8
2084+
- compiler.warn.option.obsolete.suppression
2085+
Test.java:3:5: compiler.warn.underscore.as.identifier
2086+
"""),
2087+
new TestCase("""
2088+
package t;
2089+
enum Test {
2090+
_
2091+
}
2092+
""",
2093+
System.getProperty("java.specification.version"),
2094+
"""
2095+
package t;
2096+
\n\
2097+
enum Test {
2098+
/*public static final*/ _ /* = new Test() */ /*enum*/ ;
2099+
} """,
2100+
"""
2101+
Test.java:3:5: compiler.err.underscore.as.identifier
2102+
"""),
2103+
new TestCase("""
2104+
package t;
2105+
enum Test {
2106+
_;
2107+
}
2108+
""",
2109+
"8",
2110+
"""
2111+
package t;
2112+
\n\
2113+
enum Test {
2114+
/*public static final*/ _ /* = new Test() */ /*enum*/ ;
2115+
} """,
2116+
"""
2117+
- compiler.warn.option.obsolete.source: 8
2118+
- compiler.warn.option.obsolete.target: 8
2119+
- compiler.warn.option.obsolete.suppression
2120+
Test.java:3:5: compiler.warn.underscore.as.identifier
2121+
"""),
2122+
new TestCase("""
2123+
package t;
2124+
enum Test {
2125+
_;
2126+
}
2127+
""",
2128+
System.getProperty("java.specification.version"),
2129+
"""
2130+
package t;
2131+
\n\
2132+
enum Test {
2133+
/*public static final*/ _ /* = new Test() */ /*enum*/ ;
2134+
} """,
2135+
"""
2136+
Test.java:3:5: compiler.err.underscore.as.identifier
2137+
"""),
2138+
new TestCase("""
2139+
package t;
2140+
enum Test {
2141+
A;
2142+
void t() {}
2143+
_;
2144+
}
2145+
""",
2146+
"8",
2147+
"""
2148+
package t;
2149+
\n\
2150+
enum Test {
2151+
/*public static final*/ A /* = new Test() */ /*enum*/ ,
2152+
/*public static final*/ _ /* = new Test() */ /*enum*/ ;
2153+
\n\
2154+
void t() {
2155+
}
2156+
} """,
2157+
"""
2158+
- compiler.warn.option.obsolete.source: 8
2159+
- compiler.warn.option.obsolete.target: 8
2160+
- compiler.warn.option.obsolete.suppression
2161+
Test.java:5:5: compiler.err.enum.constant.not.expected
2162+
Test.java:5:5: compiler.warn.underscore.as.identifier
2163+
"""),
2164+
new TestCase("""
2165+
package t;
2166+
enum Test {
2167+
A;
2168+
void t() {}
2169+
_;
2170+
}
2171+
""",
2172+
System.getProperty("java.specification.version"),
2173+
"""
2174+
package t;
2175+
\n\
2176+
enum Test {
2177+
/*public static final*/ A /* = new Test() */ /*enum*/ ,
2178+
/*public static final*/ _ /* = new Test() */ /*enum*/ ;
2179+
\n\
2180+
void t() {
2181+
}
2182+
} """,
2183+
"""
2184+
Test.java:5:5: compiler.err.enum.constant.not.expected
2185+
"""),
2186+
new TestCase("""
2187+
package t;
2188+
enum Test {
2189+
_ {},
2190+
A;
2191+
}
2192+
""",
2193+
"8",
2194+
"""
2195+
package t;
2196+
\n\
2197+
enum Test {
2198+
/*public static final*/ _ /* = new Test() */ /*enum*/ {
2199+
},
2200+
/*public static final*/ A /* = new Test() */ /*enum*/ ;
2201+
} """,
2202+
"""
2203+
- compiler.warn.option.obsolete.source: 8
2204+
- compiler.warn.option.obsolete.target: 8
2205+
- compiler.warn.option.obsolete.suppression
2206+
Test.java:3:5: compiler.warn.underscore.as.identifier
2207+
"""),
2208+
new TestCase("""
2209+
package t;
2210+
enum Test {
2211+
_ {},
2212+
A;
2213+
}
2214+
""",
2215+
System.getProperty("java.specification.version"),
2216+
"""
2217+
package t;
2218+
\n\
2219+
enum Test {
2220+
/*public static final*/ _ /* = new Test() */ /*enum*/ {
2221+
},
2222+
/*public static final*/ A /* = new Test() */ /*enum*/ ;
2223+
} """,
2224+
"""
2225+
Test.java:3:5: compiler.err.underscore.as.identifier
2226+
"""),
2227+
};
2228+
for (TestCase testCase : testCases) {
2229+
StringWriter out = new StringWriter();
2230+
JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(out, fm, null,
2231+
List.of("-XDrawDiagnostics", "--release", testCase.release),
2232+
null, Arrays.asList(new MyFileObject(testCase.code)));
2233+
String ast = ct.parse().iterator().next().toString().replaceAll("\\R", "\n");
2234+
assertEquals("Unexpected AST, got:\n" + ast, testCase.ast, ast);
2235+
assertEquals("Unexpected errors, got:\n" + out.toString(),
2236+
out.toString().replaceAll("\\R", "\n"),
2237+
testCase.errors);
2238+
}
2239+
}
2240+
20642241
void run(String[] args) throws Exception {
20652242
int passed = 0, failed = 0;
20662243
final Pattern p = (args != null && args.length > 0)

0 commit comments

Comments
 (0)