Skip to content

Commit 6dc591a

Browse files
authored
Merge pull request #14597 from dotty-staging/warn-symbolic-package
check if package names will be encoded in desugar
2 parents fb618ad + 30a88be commit 6dc591a

File tree

5 files changed

+58
-2
lines changed

5 files changed

+58
-2
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import Symbols._, StdNames._, Trees._, ContextOps._
88
import Decorators._, transform.SymUtils._
99
import NameKinds.{UniqueName, EvidenceParamName, DefaultGetterName}
1010
import typer.{Namer, Checking}
11-
import util.{Property, SourceFile, SourcePosition}
11+
import util.{Property, SourceFile, SourcePosition, Chars}
1212
import config.Feature.{sourceVersion, migrateTo3, enabled}
1313
import config.SourceVersion._
1414
import collection.mutable.ListBuffer
@@ -834,7 +834,8 @@ object desugar {
834834
val impl = mdef.impl
835835
val mods = mdef.mods
836836
val moduleName = normalizeName(mdef, impl).asTermName
837-
if (mods.is(Package))
837+
if mods.is(Package) then
838+
checkPackageName(mdef)
838839
PackageDef(Ident(moduleName),
839840
cpy.ModuleDef(mdef)(nme.PACKAGE, impl).withMods(mods &~ Package) :: Nil)
840841
else
@@ -950,6 +951,26 @@ object desugar {
950951
else tree
951952
}
952953

954+
def checkPackageName(mdef: ModuleDef | PackageDef)(using Context): Unit =
955+
956+
def check(name: Name, errSpan: Span): Unit = name match
957+
case name: SimpleName if !errSpan.isSynthetic && name.exists(Chars.willBeEncoded) =>
958+
report.warning(em"The package name `$name` will be encoded on the classpath, and can lead to undefined behaviour.", mdef.source.atSpan(errSpan))
959+
case _ =>
960+
961+
def loop(part: RefTree): Unit = part match
962+
case part @ Ident(name) => check(name, part.span)
963+
case part @ Select(qual: RefTree, name) =>
964+
check(name, part.nameSpan)
965+
loop(qual)
966+
case _ =>
967+
968+
mdef match
969+
case pdef: PackageDef => loop(pdef.pid)
970+
case mdef: ModuleDef if mdef.mods.is(Package) => check(mdef.name, mdef.nameSpan)
971+
case _ =>
972+
end checkPackageName
973+
953974
/** The normalized name of `mdef`. This means
954975
* 1. Check that the name does not redefine a Scala core class.
955976
* If it does redefine, issue an error and return a mangled name instead
@@ -1321,6 +1342,7 @@ object desugar {
13211342
* (i.e. objects having the same name as a wrapped type)
13221343
*/
13231344
def packageDef(pdef: PackageDef)(using Context): PackageDef = {
1345+
checkPackageName(pdef)
13241346
val wrappedTypeNames = pdef.stats.collect {
13251347
case stat: TypeDef if isTopLevelDef(stat) => stat.name
13261348
}

compiler/src/dotty/tools/dotc/util/Chars.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,7 @@ object Chars {
9393
'|' | '/' | '\\' => true
9494
case c => isSpecial(c)
9595
}
96+
97+
/** Would the character be encoded by `NameTransformer.encode`? */
98+
def willBeEncoded(c : Char) : Boolean = !JCharacter.isJavaIdentifierPart(c)
9699
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- Error: tests/neg-custom-args/fatal-warnings/symbolic-packages.scala:1:8 ---------------------------------------------
2+
1 |package `with spaces` { // error
3+
| ^^^^^^^^^^^^^
4+
| The package name `with spaces` will be encoded on the classpath, and can lead to undefined behaviour.
5+
-- Error: tests/neg-custom-args/fatal-warnings/symbolic-packages.scala:5:10 --------------------------------------------
6+
5 |package +.* { // error // error
7+
| ^
8+
| The package name `*` will be encoded on the classpath, and can lead to undefined behaviour.
9+
-- Error: tests/neg-custom-args/fatal-warnings/symbolic-packages.scala:5:8 ---------------------------------------------
10+
5 |package +.* { // error // error
11+
| ^
12+
| The package name `+` will be encoded on the classpath, and can lead to undefined behaviour.
13+
-- Error: tests/neg-custom-args/fatal-warnings/symbolic-packages.scala:9:16 --------------------------------------------
14+
9 |package object `mixed_*` { // error
15+
| ^^^^^^^
16+
| The package name `mixed_*` will be encoded on the classpath, and can lead to undefined behaviour.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package `with spaces` { // error
2+
class Foo
3+
}
4+
5+
package +.* { // error // error
6+
class Bar
7+
}
8+
9+
package object `mixed_*` { // error
10+
class Baz
11+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
def foo = 23
2+
val bar = foo
3+
var baz = bar
4+
type Qux = Int

0 commit comments

Comments
 (0)