@@ -826,6 +826,26 @@ object JavaParsers {
826
826
addCompanionObject(statics, cls)
827
827
}
828
828
829
+ def unnamedClassDecl (priorTypes : List [Tree ], firstMemberMods : Modifiers , start : Offset ): List [Tree ] = {
830
+ val name = source.name.replaceAll(" \\ .java$" , " " ).nn.toTypeName
831
+ val (statics, body) = typeBodyDecls(CLASS , name, parentTParams = Nil , firstMemberMods = Some (firstMemberMods))
832
+
833
+ val priorStatics = priorTypes.map {
834
+ case t : (TypeDef | ModuleDef ) => t.withMods(t.mods.withFlags(t.mods.flags | Flags .JavaStatic ))
835
+ case other => throw new Error (s " $other is neither TypeDef nor ModuleDef " )
836
+ }
837
+
838
+ val cls = atSpan(start, 0 ) {
839
+ TypeDef (name, makeTemplate(
840
+ parents = List (javaLangObject()),
841
+ stats = body,
842
+ tparams = Nil ,
843
+ needsDummyConstr = true )
844
+ ).withMods(Modifiers (Flags .Private | Flags .Final ))
845
+ }
846
+ addCompanionObject(priorStatics ::: statics, cls)
847
+ }
848
+
829
849
def recordDecl (start : Offset , mods : Modifiers ): List [Tree ] =
830
850
accept(RECORD )
831
851
val nameOffset = in.offset
@@ -899,13 +919,13 @@ object JavaParsers {
899
919
defs
900
920
}
901
921
902
- def typeBodyDecls (parentToken : Int , parentName : Name , parentTParams : List [TypeDef ]): (List [Tree ], List [Tree ]) = {
922
+ def typeBodyDecls (parentToken : Int , parentName : Name , parentTParams : List [TypeDef ], firstMemberMods : Option [ Modifiers ] = None ): (List [Tree ], List [Tree ]) = {
903
923
val inInterface = definesInterface(parentToken)
904
924
val statics = new ListBuffer [Tree ]
905
925
val members = new ListBuffer [Tree ]
906
926
while (in.token != RBRACE && in.token != EOF ) {
907
927
val start = in.offset
908
- var mods = modifiers(inInterface)
928
+ var mods = ( if (statics.isEmpty && members.isEmpty) firstMemberMods else None ).getOrElse( modifiers(inInterface) )
909
929
if (in.token == LBRACE ) {
910
930
skipAhead() // skip init block, we just assume we have seen only static
911
931
accept(RBRACE )
@@ -1067,16 +1087,35 @@ object JavaParsers {
1067
1087
val buf = new ListBuffer [Tree ]
1068
1088
while (in.token == IMPORT )
1069
1089
buf ++= importDecl()
1090
+
1091
+ val afterImports = in.offset
1092
+ val typesBuf = new ListBuffer [Tree ]
1093
+
1070
1094
while (in.token != EOF && in.token != RBRACE ) {
1071
1095
while (in.token == SEMI ) in.nextToken()
1072
1096
if (in.token != EOF ) {
1073
1097
val start = in.offset
1074
1098
val mods = modifiers(inInterface = false )
1075
1099
adaptRecordIdentifier() // needed for typeDecl
1076
- buf ++= typeDecl(start, mods)
1100
+
1101
+ in.token match {
1102
+ case ENUM | INTERFACE | AT | CLASS | RECORD => typesBuf ++= typeDecl(start, mods)
1103
+ case _ =>
1104
+ if (thisPackageName == tpnme.EMPTY_PACKAGE ) {
1105
+ // upon encountering non-types directly at a compilation unit level in an unnamed package,
1106
+ // the entire compilation unit is treated as a JEP-445 unnamed class
1107
+ val cls = unnamedClassDecl(priorTypes = typesBuf.toList, firstMemberMods = mods, start = afterImports)
1108
+ typesBuf.clear()
1109
+ typesBuf ++= cls
1110
+ } else {
1111
+ in.nextToken()
1112
+ syntaxError(em " illegal start of type declaration " , skipIt = true )
1113
+ List (errorTypeTree)
1114
+ }
1115
+ }
1077
1116
}
1078
1117
}
1079
- val unit = atSpan(start) { PackageDef (pkg, buf.toList) }
1118
+ val unit = atSpan(start) { PackageDef (pkg, ( buf++ typesBuf) .toList) }
1080
1119
accept(EOF )
1081
1120
unit match
1082
1121
case PackageDef (Ident (nme.EMPTY_PACKAGE ), Nil ) => EmptyTree
0 commit comments