@@ -1220,6 +1220,29 @@ object desugar {
12201220 else Apply (ref(tupleTypeRef.classSymbol.companionModule.termRef), ts)
12211221 }
12221222
1223+ private def isTopLevelDef (stat : Tree )(given Context ): Boolean = stat match
1224+ case _ : ValDef | _ : PatDef | _ : DefDef | _ : Export => true
1225+ case stat : ModuleDef =>
1226+ stat.mods.isOneOf(GivenOrImplicit )
1227+ case stat : TypeDef =>
1228+ ! stat.isClassDef || stat.mods.isOneOf(GivenOrImplicit )
1229+ case _ =>
1230+ false
1231+
1232+ /** Does this package contains at least one top-level definition
1233+ * that will require a wrapping object ?
1234+ */
1235+ def hasTopLevelDef (pdef : PackageDef )(given Context ): Boolean =
1236+ pdef.stats.exists(isTopLevelDef)
1237+
1238+ /** Assuming `src` contains top-level definition, returns the name that should
1239+ * be using for the package object that will wrap them.
1240+ */
1241+ def packageObjectName (src : SourceFile ): TermName =
1242+ val fileName = src.file.name
1243+ val sourceName = fileName.take(fileName.lastIndexOf('.' ))
1244+ (sourceName ++ str.TOPLEVEL_SUFFIX ).toTermName
1245+
12231246 /** Group all definitions that can't be at the toplevel in
12241247 * an object named `<source>$package` where `<source>` is the name of the source file.
12251248 * Definitions that can't be at the toplevel are:
@@ -1231,26 +1254,22 @@ object desugar {
12311254 * (i.e. objects having the same name as a wrapped type)
12321255 */
12331256 def packageDef (pdef : PackageDef )(implicit ctx : Context ): PackageDef = {
1234- def isWrappedType (stat : TypeDef ): Boolean =
1235- ! stat.isClassDef || stat.mods.isOneOf(GivenOrImplicit )
12361257 val wrappedTypeNames = pdef.stats.collect {
1237- case stat : TypeDef if isWrappedType(stat) => stat.name
1238- }
1239- def needsObject (stat : Tree ) = stat match {
1240- case _ : ValDef | _ : PatDef | _ : DefDef | _ : Export => true
1241- case stat : ModuleDef =>
1242- stat.mods.isOneOf(GivenOrImplicit ) ||
1243- wrappedTypeNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
1244- case stat : TypeDef => isWrappedType(stat)
1245- case _ => false
1258+ case stat : TypeDef if isTopLevelDef(stat) => stat.name
12461259 }
1247- val (nestedStats, topStats) = pdef.stats.partition(needsObject)
1260+ def inPackageObject (stat : Tree ) =
1261+ isTopLevelDef(stat) || {
1262+ stat match
1263+ case stat : ModuleDef =>
1264+ wrappedTypeNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
1265+ case _ =>
1266+ false
1267+ }
1268+ val (nestedStats, topStats) = pdef.stats.partition(inPackageObject)
12481269 if (nestedStats.isEmpty) pdef
12491270 else {
1250- var fileName = ctx.source.file.name
1251- val sourceName = fileName.take(fileName.lastIndexOf('.' ))
1252- val groupName = (sourceName ++ str.TOPLEVEL_SUFFIX ).toTermName.asSimpleName
1253- val grouped = ModuleDef (groupName, Template (emptyConstructor, Nil , Nil , EmptyValDef , nestedStats))
1271+ val name = packageObjectName(ctx.source)
1272+ val grouped = ModuleDef (name, Template (emptyConstructor, Nil , Nil , EmptyValDef , nestedStats))
12541273 cpy.PackageDef (pdef)(pdef.pid, topStats :+ grouped)
12551274 }
12561275 }
0 commit comments