Skip to content

Commit

Permalink
[JEP-409] Add support for sealed and non-sealed templates in parser
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzaremmal committed Dec 9, 2023
1 parent 55c2002 commit bddf379
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 4 deletions.
16 changes: 16 additions & 0 deletions compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,11 @@ object JavaParsers {
addAnnot(scalaDot(jtpnme.VOLATILEkw))
case SYNCHRONIZED | STRICTFP =>
in.nextToken()
case SEALED =>
//flags |= Flags.Sealed
in.nextToken()
case NON_SEALED =>
in.nextToken()
case _ =>
val privateWithin: TypeName =
if (isPackageAccess && !inInterface) thisPackageName
Expand Down Expand Up @@ -806,6 +811,15 @@ object JavaParsers {
else
List()


def permittedSubclassesOpt(isSealed: Boolean) : List[Tree] =
if in.token == PERMITS then
in.nextToken()
repsep(() => typ(), COMMA)
else
if isSealed then syntaxError(em"sealed class must have subclasses", false)
Nil

def classDecl(start: Offset, mods: Modifiers): List[Tree] = {
accept(CLASS)
val nameOffset = in.offset
Expand All @@ -819,6 +833,7 @@ object JavaParsers {
else
javaLangObject()
val interfaces = interfacesOpt()
val permittedSubclasses = permittedSubclassesOpt(mods.is(Flags.Sealed))
val (statics, body) = typeBody(CLASS, name, tparams)
val cls = atSpan(start, nameOffset) {
TypeDef(name, makeTemplate(superclass :: interfaces, body, tparams, true)).withMods(mods)
Expand Down Expand Up @@ -883,6 +898,7 @@ object JavaParsers {
}
else
List(javaLangObject())
val permittedSubclasses = permittedSubclassesOpt(mods is Flags.Sealed)
val (statics, body) = typeBody(INTERFACE, name, tparams)
val iface = atSpan(start, nameOffset) {
TypeDef(
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/parsing/JavaScanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,10 @@ object JavaScanners {
'5' | '6' | '7' | '8' | '9' =>
putChar(ch)
nextChar()

case '-' =>
// TODO HR : Add lookahead to only allow the 'non-sealed keyword'
putChar(ch)
nextChar()
case '_' =>
putChar(ch)
nextChar()
Expand Down
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/parsing/JavaTokens.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object JavaTokens extends TokensCommon {

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

Expand All @@ -22,6 +22,8 @@ object JavaTokens extends TokensCommon {
inline val INTERFACE = 105; enter(INTERFACE, "interface")
inline val ENUM = 106; enter(ENUM, "enum")
inline val IMPLEMENTS = 107; enter(IMPLEMENTS, "implements")
inline val PERMITS = 108; enter(PERMITS, "permits")
inline val NON_SEALED = 109; enter(NON_SEALED, "non-sealed")

/** modifiers */
inline val PUBLIC = 110; enter(PUBLIC, "public")
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/parsing/Tokens.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ abstract class TokensCommon {
//inline val YIELD = 48; enter(YIELD, "yield")
inline val DO = 49; enter(DO, "do")
//inline val TRAIT = 50; enter(TRAIT, "trait")
//inline val SEALED = 51; enter(SEALED, "sealed")
inline val SEALED = 51; enter(SEALED, "sealed")
inline val THROW = 52; enter(THROW, "throw")
inline val TRY = 53; enter(TRY, "try")
inline val CATCH = 54; enter(CATCH, "catch")
Expand Down Expand Up @@ -169,7 +169,7 @@ object Tokens extends TokensCommon {
inline val OBJECT = 44; enter(OBJECT, "object")
inline val YIELD = 48; enter(YIELD, "yield")
inline val TRAIT = 50; enter(TRAIT, "trait")
inline val SEALED = 51; enter(SEALED, "sealed")
//inline val SEALED = 51; enter(SEALED, "sealed")
inline val MATCH = 58; enter(MATCH, "match")
inline val LAZY = 59; enter(LAZY, "lazy")
inline val THEN = 60; enter(THEN, "then")
Expand Down
5 changes: 5 additions & 0 deletions tests/pos/i18533/Cat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package i18533;

public final class Cat extends Pet {

}
5 changes: 5 additions & 0 deletions tests/pos/i18533/Dog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package i18533;

public non-sealed class Dog extends Pet {

}
5 changes: 5 additions & 0 deletions tests/pos/i18533/Pet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package i18533;

public sealed class Pet permits Cat, Dog {

}

0 comments on commit bddf379

Please sign in to comment.