From cd3d9efeee1bf90bad77be89ebe2ac0c2242524f Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 19 Nov 2023 09:16:07 +0800 Subject: [PATCH 1/2] . --- .../feature/private-methods/repo/build.sc | 43 +++++++++++++++++ .../test/src/PrivateMethodsTests.scala | 46 +++++++++++++++++++ main/eval/src/mill/eval/GroupEvaluator.scala | 10 +++- tmp/build.sc | 44 ++++++++++++++++++ 4 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 integration/feature/private-methods/repo/build.sc create mode 100644 integration/feature/private-methods/test/src/PrivateMethodsTests.scala create mode 100644 tmp/build.sc diff --git a/integration/feature/private-methods/repo/build.sc b/integration/feature/private-methods/repo/build.sc new file mode 100644 index 00000000000..62bf2f18791 --- /dev/null +++ b/integration/feature/private-methods/repo/build.sc @@ -0,0 +1,43 @@ +import mill._ + +def pub = T { + priv() +} + +private def priv = T { + "priv" +} + +object foo extends Module { + def bar = T { + baz() + } +} + +private def baz = T { + "bazOuter" +} + +object qux extends Module { + object foo extends Module { + def bar = T { + baz() + } + } + private def baz = T { + "bazInner" + } +} + +object cls extends cls +class cls extends Module { + object foo extends Module { + def bar = T { + baz() + } + } + + private def baz = T { + "bazCls" + } +} diff --git a/integration/feature/private-methods/test/src/PrivateMethodsTests.scala b/integration/feature/private-methods/test/src/PrivateMethodsTests.scala new file mode 100644 index 00000000000..15a2a90e59a --- /dev/null +++ b/integration/feature/private-methods/test/src/PrivateMethodsTests.scala @@ -0,0 +1,46 @@ +package mill.integration + +import utest._ + +object PrivateMethodsTests extends IntegrationTestSuite { + val tests = Tests { + val wsRoot = initWorkspace() + "simple" - { + // Simple public target depending on private target works + val pub = evalStdout("show", "pub") + assert(pub.out == "\"priv\"") + assert(pub.isSuccess) + + // Make sure calling private methods indirectly in a variety of scenarios works + // even when they're "not really private" due to + val fooBar = evalStdout("show", "foo.bar") + assert(fooBar.out == "\"bazOuter\"") + assert(fooBar.isSuccess) + + val quxFooBar = evalStdout("show", "qux.foo.bar") + assert(quxFooBar.out == "\"bazInner\"") + assert(quxFooBar.isSuccess) + + val clsFooBar = evalStdout("show", "cls.foo.bar") + assert(clsFooBar.out == "\"bazCls\"") + assert(clsFooBar.isSuccess) + + // Make sure calling private methods directly fails + val priv = evalStdout("show", "priv") + assert(priv.err.contains("Cannot resolve priv")) + assert(priv.isSuccess == false) + + val baz = evalStdout("show", "baz") + assert(baz.err.contains("Cannot resolve baz")) + assert(baz.isSuccess == false) + + val quxBaz = evalStdout("show", "qux.baz") + assert(quxBaz.err.contains("Cannot resolve qux.baz")) + assert(quxBaz.isSuccess == false) + + val clsBaz = evalStdout("show", "cls.baz") + assert(clsBaz.err.contains("Cannot resolve cls.baz")) + assert(clsBaz.isSuccess == false) + } + } +} diff --git a/main/eval/src/mill/eval/GroupEvaluator.scala b/main/eval/src/mill/eval/GroupEvaluator.scala index f2f5f10f9ad..8754b67a539 100644 --- a/main/eval/src/mill/eval/GroupEvaluator.scala +++ b/main/eval/src/mill/eval/GroupEvaluator.scala @@ -8,7 +8,7 @@ import mill.eval.Evaluator.TaskResult import mill.util._ import scala.collection.mutable -import scala.reflect.NameTransformer.decode +import scala.reflect.NameTransformer.{encode, decode} import scala.util.DynamicVariable import scala.util.control.NonFatal @@ -98,7 +98,13 @@ private[mill] trait GroupEvaluator { val methods = for { c <- transitiveParents m <- c.getDeclaredMethods - if decode(m.getName) == namedTask.ctx.segment.pathSegments.head + encodedTaskName = encode(namedTask.ctx.segment.pathSegments.head) + if m.getName == encodedTaskName || + // Handle scenarios where private method names get mangled when they are + // not really JVM-private due to being accessed by Scala nested objects + // or classes https://github.com/scala/bug/issues/9306 + m.getName == (c.getName.replace('.', '$') + "$$" + encodedTaskName) || + m.getName == (c.getName.replace('.', '$') + "$" + encodedTaskName) } yield m val methodClass = methods.head.getDeclaringClass.getName diff --git a/tmp/build.sc b/tmp/build.sc new file mode 100644 index 00000000000..38021ce51b1 --- /dev/null +++ b/tmp/build.sc @@ -0,0 +1,44 @@ +import mill._ + + +def pub = T { + priv() +} + +private def priv = T { + "priv" +} + +object foo extends Module { + def bar = T { + baz() + } +} + +private def baz = T { + "bazOuter" +} + +object qux extends Module { + object foo extends Module { + def bar = T { + baz() + } + } + private def baz = T { + "bazInner" + } +} + +object cls extends cls +class cls extends Module { + object foo extends Module { + def bar = T { + baz() + } + } + + private def baz = T { + "bazCls" + } +} From eae9836d6903bd56203e506e1851426ce4878b90 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 19 Nov 2023 09:28:08 +0800 Subject: [PATCH 2/2] . --- tmp/build.sc | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 tmp/build.sc diff --git a/tmp/build.sc b/tmp/build.sc deleted file mode 100644 index 38021ce51b1..00000000000 --- a/tmp/build.sc +++ /dev/null @@ -1,44 +0,0 @@ -import mill._ - - -def pub = T { - priv() -} - -private def priv = T { - "priv" -} - -object foo extends Module { - def bar = T { - baz() - } -} - -private def baz = T { - "bazOuter" -} - -object qux extends Module { - object foo extends Module { - def bar = T { - baz() - } - } - private def baz = T { - "bazInner" - } -} - -object cls extends cls -class cls extends Module { - object foo extends Module { - def bar = T { - baz() - } - } - - private def baz = T { - "bazCls" - } -}