Skip to content

Commit 5e5021b

Browse files
committed
[JEP-409] Add support for sealed classes and interfaces in Java
1 parent a0ea484 commit 5e5021b

File tree

6 files changed

+28
-4
lines changed

6 files changed

+28
-4
lines changed

Diff for: compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala

+14
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,9 @@ object JavaParsers {
489489
addAnnot(scalaDot(jtpnme.VOLATILEkw))
490490
case SYNCHRONIZED | STRICTFP =>
491491
in.nextToken()
492+
case SEALED =>
493+
// TODO: Should we add the Sealed flag here ?? (flags |= Flags.Sealed)
494+
in.nextToken()
492495
case _ =>
493496
val privateWithin: TypeName =
494497
if (isPackageAccess && !inInterface) thisPackageName
@@ -812,6 +815,15 @@ object JavaParsers {
812815
else
813816
List()
814817

818+
819+
def permittedSubclassesOpt(isSealed: Boolean) : List[Tree] =
820+
if in.token == PERMITS then
821+
in.nextToken()
822+
repsep(() => typ(), COMMA)
823+
else
824+
if isSealed then syntaxError(em"sealed class must have subclasses", false)
825+
Nil
826+
815827
def classDecl(start: Offset, mods: Modifiers): List[Tree] = {
816828
accept(CLASS)
817829
val nameOffset = in.offset
@@ -825,6 +837,7 @@ object JavaParsers {
825837
else
826838
ObjectTpt()
827839
val interfaces = interfacesOpt()
840+
val permittedSubclasses = permittedSubclassesOpt(mods.is(Flags.Sealed))
828841
val (statics, body) = typeBody(CLASS, name)
829842
val cls = atSpan(start, nameOffset) {
830843
TypeDef(name, makeTemplate(superclass :: interfaces, body, tparams, needsDummyConstr = true)).withMods(mods)
@@ -889,6 +902,7 @@ object JavaParsers {
889902
}
890903
else
891904
List(ObjectTpt())
905+
val permittedSubclasses = permittedSubclassesOpt(mods is Flags.Sealed)
892906
val (statics, body) = typeBody(INTERFACE, name)
893907
val iface = atSpan(start, nameOffset) {
894908
TypeDef(

Diff for: compiler/src/dotty/tools/dotc/parsing/JavaScanners.scala

-1
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,6 @@ object JavaScanners {
393393
'5' | '6' | '7' | '8' | '9' =>
394394
putChar(ch)
395395
nextChar()
396-
397396
case '_' =>
398397
putChar(ch)
399398
nextChar()

Diff for: compiler/src/dotty/tools/dotc/parsing/JavaTokens.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object JavaTokens extends TokensCommon {
1010

1111
final val javaOnlyKeywords: TokenSet = tokenRange(INSTANCEOF, ASSERT)
1212
final val sharedKeywords: BitSet = BitSet( IF, FOR, ELSE, THIS, NULL, NEW, SUPER, ABSTRACT, FINAL, PRIVATE, PROTECTED,
13-
EXTENDS, TRUE, FALSE, CLASS, IMPORT, PACKAGE, DO, THROW, TRY, CATCH, FINALLY, WHILE, RETURN )
13+
EXTENDS, TRUE, FALSE, CLASS, IMPORT, PACKAGE, DO, THROW, TRY, CATCH, FINALLY, WHILE, RETURN, SEALED)
1414
final val primTypes: TokenSet = tokenRange(VOID, DOUBLE)
1515
final val keywords: BitSet = sharedKeywords | javaOnlyKeywords | primTypes
1616

@@ -22,6 +22,7 @@ object JavaTokens extends TokensCommon {
2222
inline val INTERFACE = 105; enter(INTERFACE, "interface")
2323
inline val ENUM = 106; enter(ENUM, "enum")
2424
inline val IMPLEMENTS = 107; enter(IMPLEMENTS, "implements")
25+
inline val PERMITS = 108; enter(PERMITS, "permits")
2526

2627
/** modifiers */
2728
inline val PUBLIC = 110; enter(PUBLIC, "public")

Diff for: compiler/src/dotty/tools/dotc/parsing/Tokens.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ abstract class TokensCommon {
7878
//inline val YIELD = 48; enter(YIELD, "yield")
7979
inline val DO = 49; enter(DO, "do")
8080
//inline val TRAIT = 50; enter(TRAIT, "trait")
81-
//inline val SEALED = 51; enter(SEALED, "sealed")
81+
inline val SEALED = 51; enter(SEALED, "sealed")
8282
inline val THROW = 52; enter(THROW, "throw")
8383
inline val TRY = 53; enter(TRY, "try")
8484
inline val CATCH = 54; enter(CATCH, "catch")
@@ -169,7 +169,7 @@ object Tokens extends TokensCommon {
169169
inline val OBJECT = 44; enter(OBJECT, "object")
170170
inline val YIELD = 48; enter(YIELD, "yield")
171171
inline val TRAIT = 50; enter(TRAIT, "trait")
172-
inline val SEALED = 51; enter(SEALED, "sealed")
172+
//inline val SEALED = 51; enter(SEALED, "sealed")
173173
inline val MATCH = 58; enter(MATCH, "match")
174174
inline val LAZY = 59; enter(LAZY, "lazy")
175175
inline val THEN = 60; enter(THEN, "then")

Diff for: tests/pos/i18533/Cat.java

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package i18533;
2+
3+
public final class Cat extends Pet {
4+
5+
}

Diff for: tests/pos/i18533/Pet.java

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package i18533;
2+
3+
public sealed class Pet permits Cat {
4+
5+
}

0 commit comments

Comments
 (0)