@@ -22,6 +22,7 @@ import config.Printers.refcheck
2222import reporting .*
2323import Constants .Constant
2424import cc .stripCapturing
25+ import dotty .tools .dotc .printing .Formatting .hl
2526
2627object RefChecks {
2728 import tpd .*
@@ -1274,6 +1275,18 @@ object RefChecks {
12741275 case tp : NamedType if tp.prefix.typeSymbol != ctx.owner.enclosingClass =>
12751276 report.warning(UnqualifiedCallToAnyRefMethod (tree, tree.symbol), tree)
12761277 case _ => ()
1278+
1279+ def checkJavaStaticProtected (tree : tpd.Apply | tpd.Select | tpd.Assign )(using Context ): Unit =
1280+ val sym = tree.symbol
1281+ if sym.isAllOf(StaticProtected ) then
1282+ val definedPackage = sym.enclosingPackageClass
1283+ val definedClass = sym.owner.companionClass // it's _not_ sym.enclosingClass because it's static, therefore enclosed in a companion object, not a class
1284+ val enclosingPackage = ctx.owner.enclosingPackageClass
1285+
1286+ if definedPackage != enclosingPackage && ! ctx.owner.ownersIterator.exists(_.derivesFrom(definedClass)) then
1287+ report.error(em " ${StaticProtected } $sym which is defined in $definedPackage is inaccessible at runtime from $enclosingPackage" , tree.srcPos)
1288+ end checkJavaStaticProtected
1289+
12771290}
12781291import RefChecks .*
12791292
@@ -1363,6 +1376,15 @@ class RefChecks extends MiniPhase { thisPhase =>
13631376 override def transformSelect (tree : tpd.Select )(using Context ): tpd.Tree =
13641377 if defn.ScalaBoxedClasses ().contains(tree.qualifier.tpe.typeSymbol) && tree.name == nme.synchronized_ then
13651378 report.warning(SynchronizedCallOnBoxedClass (tree), tree.srcPos)
1379+ checkJavaStaticProtected(tree)
1380+ tree
1381+
1382+ override def transformApply (tree : tpd.Apply )(using Context ): tpd.Apply =
1383+ checkJavaStaticProtected(tree)
1384+ tree
1385+
1386+ override def transformAssign (tree : tpd.Assign )(using Context ): tpd.Assign =
1387+ checkJavaStaticProtected(tree)
13661388 tree
13671389}
13681390
0 commit comments