Skip to content

Commit f36dac8

Browse files
authored
Simplify handling of MillBuildRootModule in CodeGen (#5057)
* Now that we are on Scala 3, `MillBuildRootModule` can be a `trait` like most other modules and still take implicit parameters * That allows us to remove the special casing of `MillBuildRootModule` in codegen, since it can now stack with the default `MainRootModule` that non-meta-build root modules inherit from * We can also remove the synthetic `import _root_.mill.runner.meta.MillBuildRootModule` that we were previously injecting into the scope, since now it is just another stackable trait like any other * Also tidied up `CodeGen.scala` a bit to reduce duplication
1 parent 0e0282a commit f36dac8

File tree

10 files changed

+41
-57
lines changed

10 files changed

+41
-57
lines changed

example/extending/metabuild/4-meta-build/mill-build/build.mill

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package build
22
import mill._, scalalib._
3+
import mill.runner.meta.MillBuildRootModule
34

45
object `package` extends MillBuildRootModule {
56
val scalatagsVersion = "0.13.1"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
package build
22
import mill._
3+
import mill.runner.meta.MillBuildRootModule
34

45
object `package` extends MillBuildRootModule

integration/failure/root-module-compile-error/src/RootModuleCompileErrorTests.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite {
2626

2727
locally {
2828
// For now these error messages still show generated/mangled code; not ideal, but it'll do
29-
assert(res.err.replace('\\', '/').contains("""foo/package.mill:6:85"""))
29+
assert(res.err.replace('\\', '/').contains("""foo/package.mill:6:92"""))
3030
assert(res.err.contains("""Not found: type UnknownFooModule"""))
3131
assert(res.err.contains(
32-
"""abstract class package_ extends mill.main.SubfolderModule(build.millDiscover) with UnknownFooModule {"""
32+
"""abstract class package_ extends _root_.mill.main.SubfolderModule(build.millDiscover) with UnknownFooModule {"""
3333
))
3434
assert(res.err.contains(
35-
""" ^^^^^^^^^^^^^^^^"""
35+
""" ^^^^^^^^^^^^^^^^"""
3636
))
3737
}
3838

integration/feature/scala-3-syntax/resources/mill-build/build.mill

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package build
33
import mill.*
44
import mill.scalalib.*
55

6-
object `package` extends MillBuildRootModule:
6+
object `package` extends mill.runner.meta.MillBuildRootModule:
77
def mvnDeps = Seq(
88
mvn"org.scala-lang::toolkit:0.5.0"
99
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package build
22
import mill.*
33
import mill.scalalib.*
4+
import mill.runner.meta.MillBuildRootModule
45

56
object `package` extends MillBuildRootModule

integration/ide/gen-idea/resources/extended/mill-build/build.mill

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import mill._
22
import mill.scalalib._
3+
import mill.runner.meta.MillBuildRootModule
34

45
object `package` extends MillBuildRootModule {
56
def mvnDeps = Seq(mvn"org.scalameta::munit:0.7.29")

integration/invalidation/multi-level-editing/resources/mill-build/build.mill

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package build
22

33
import mill._, scalalib._
4+
import mill.runner.meta.MillBuildRootModule
45

56
object `package` extends MillBuildRootModule {
67
def mvnDeps = Seq(mvn"com.lihaoyi::scalatags:${constant.MetaConstant.scalatagsVersion}")

integration/invalidation/multi-level-editing/resources/mill-build/mill-build/build.mill

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package build
22
// build.mill
33
import mill._, scalalib._
4+
import mill.runner.meta.MillBuildRootModule
45

56
object `package` extends MillBuildRootModule {
67
def generatedSources = Task {

runner/meta/src/mill/runner/meta/CodeGen.scala

Lines changed: 28 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -26,43 +26,39 @@ object CodeGen {
2626
val isBuildScript = specialNames(scriptPath.last)
2727
val scriptFolderPath = scriptPath / os.up
2828

29-
if (scriptFolderPath == projectRoot && scriptPath.last.split('.').head == "package") {
30-
break()
31-
}
29+
val scriptBaseName = scriptPath.last.split('.').head
3230

33-
if (scriptFolderPath != projectRoot && scriptPath.last.split('.').head == "build") {
34-
break()
35-
}
31+
if (scriptFolderPath == projectRoot && scriptBaseName == "package") break()
32+
if (scriptFolderPath != projectRoot && scriptBaseName == "build") break()
3633

3734
val packageSegments = FileImportGraph.fileImportToSegments(projectRoot, scriptPath)
3835
val dest = targetDest / packageSegments
3936

4037
val childNames = scriptSources
41-
.flatMap { path =>
42-
if (path == scriptPath) None
43-
else if (nestedBuildFileNames.contains(path.last)) {
44-
Option.when(path / os.up / os.up == scriptFolderPath) {
45-
(path / os.up).last
46-
}
47-
} else None
38+
.collect {
39+
case path
40+
if path != scriptPath
41+
&& nestedBuildFileNames.contains(path.last)
42+
&& path / os.up / os.up == scriptFolderPath => (path / os.up).last
4843
}
4944
.distinct
5045

5146
val pkgSegments = packageSegments.drop(1).dropRight(1)
5247

5348
def pkgSelector0(pre: Option[String], s: Option[String]) =
5449
(pre ++ pkgSegments ++ s).map(backtickWrap).mkString(".")
50+
5551
def pkgSelector2(s: Option[String]) = s"_root_.${pkgSelector0(Some(globalPackagePrefix), s)}"
56-
val (childSels, childAliases0) = childNames
52+
53+
val childAliases = childNames
5754
.map { c =>
5855
// Dummy references to sub-modules. Just used as metadata for the discover and
5956
// resolve logic to traverse, cannot actually be evaluated and used
60-
val comment = "// subfolder module reference"
6157
val lhs = backtickWrap(c)
6258
val rhs = s"${pkgSelector2(Some(c))}.package_"
63-
(rhs, s"final lazy val $lhs: $rhs.type = $rhs $comment")
64-
}.unzip
65-
val childAliases = childAliases0.mkString("\n")
59+
s"final lazy val $lhs: $rhs.type = $rhs // subfolder module reference"
60+
}
61+
.mkString("\n")
6662

6763
val pkg = pkgSelector0(Some(globalPackagePrefix), None)
6864

@@ -155,16 +151,11 @@ object CodeGen {
155151
scriptFolderPath,
156152
compilerWorkerClasspath,
157153
millTopLevelProjectRoot,
158-
output,
159-
projectRoot != millTopLevelProjectRoot
154+
output
160155
)
161156

162157
val objectData = parser.parseObjectData(scriptCode)
163158

164-
val expectedParent =
165-
if (projectRoot != millTopLevelProjectRoot) "MillBuildRootModule"
166-
else "_root_.mill.main.MainRootModule"
167-
168159
val expectedModuleMsg =
169160
if (projectRoot != millTopLevelProjectRoot) "MillBuildRootModule" else "mill.Module"
170161

@@ -184,10 +175,12 @@ object CodeGen {
184175
|}
185176
|""".stripMargin
186177

178+
val newParent =
179+
if (segments.isEmpty) "_root_.mill.main.MainRootModule"
180+
else "_root_.mill.main.SubfolderModule(build.millDiscover)"
181+
187182
objectData.find(o => o.name.text == "`package`") match {
188183
case Some(objectData) =>
189-
val newParent =
190-
if (segments.isEmpty) expectedParent else s"mill.main.SubfolderModule(build.millDiscover)"
191184

192185
var newScriptCode = scriptCode
193186
objectData.endMarker match {
@@ -198,18 +191,13 @@ object CodeGen {
198191
}
199192
objectData.finalStat match {
200193
case Some((leading, finalStat)) =>
194+
val statLines = finalStat.text.linesWithSeparators.toSeq
201195
val fenced = Seq(
202-
"", {
203-
val statLines = finalStat.text.linesWithSeparators.toSeq
204-
if statLines.sizeIs > 1 then
205-
statLines.tail.mkString
206-
else
207-
finalStat.text
208-
}
196+
"",
197+
if statLines.sizeIs > 1 then statLines.tail.mkString else finalStat.text
209198
).mkString(System.lineSeparator())
210199
newScriptCode = finalStat.applyTo(newScriptCode, fenced)
211-
case None =>
212-
()
200+
case None => ()
213201
}
214202

215203
newScriptCode = objectData.parent.applyTo(
@@ -219,12 +207,10 @@ object CodeGen {
219207
s"object `package` in ${scriptPath.relativeTo(millTopLevelProjectRoot)} " +
220208
s"must extend a subclass of `$expectedModuleMsg`"
221209
)
222-
} else if (objectData.parent.text == expectedParent) newParent
223-
else newParent + " with " + objectData.parent.text
210+
} else newParent + " with " + objectData.parent.text
224211
)
225212

226213
newScriptCode = objectData.name.applyTo(newScriptCode, wrapperObjectName)
227-
228214
newScriptCode = objectData.obj.applyTo(newScriptCode, "abstract class")
229215

230216
s"""$headerCode
@@ -233,14 +219,8 @@ object CodeGen {
233219
|""".stripMargin
234220

235221
case None =>
236-
val extendsClause =
237-
if (segments.nonEmpty) s"extends _root_.mill.main.SubfolderModule(build.millDiscover) "
238-
else if (millTopLevelProjectRoot == scriptFolderPath)
239-
s"extends _root_.mill.main.MainRootModule "
240-
else s"extends _root_.mill.runner.meta.MillBuildRootModule() "
241-
242222
s"""$headerCode
243-
|abstract class $wrapperObjectName $extendsClause { this: $wrapperObjectName.type =>
223+
|abstract class $wrapperObjectName extends $newParent { this: $wrapperObjectName.type =>
244224
|$markerComment
245225
|$scriptCode
246226
|}""".stripMargin
@@ -252,8 +232,7 @@ object CodeGen {
252232
scriptFolderPath: os.Path,
253233
segments: Seq[String]
254234
): String = {
255-
s"""object MillMiscInfo
256-
|extends mill.main.SubfolderModule.Info(
235+
s"""object MillMiscInfo extends mill.main.SubfolderModule.Info(
257236
| os.Path(${literalize(scriptFolderPath.toString)}),
258237
| _root_.scala.Seq(${segments.map(pprint.Util.literalize(_)).mkString(", ")})
259238
|)
@@ -272,10 +251,9 @@ object CodeGen {
272251
scriptFolderPath: os.Path,
273252
compilerWorkerClasspath: Seq[os.Path],
274253
millTopLevelProjectRoot: os.Path,
275-
output: os.Path,
276-
isMetaBuild: Boolean
254+
output: os.Path
277255
): String = {
278-
s"""${if (isMetaBuild) "import _root_.mill.runner.meta.MillBuildRootModule" else ""}
256+
s"""
279257
|@_root_.scala.annotation.nowarn
280258
|object MillMiscInfo extends mill.define.RootModule0.Info(
281259
| ${compilerWorkerClasspath.map(p => literalize(p.toString))},

runner/meta/src/mill/runner/meta/MillBuildRootModule.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import scala.jdk.CollectionConverters.ListHasAsScala
2222
* calls within the scripts.
2323
*/
2424
@internal
25-
class MillBuildRootModule()(implicit
25+
trait MillBuildRootModule()(implicit
2626
rootModuleInfo: RootModule0.Info,
2727
scalaCompilerResolver: ScalaCompilerWorker.Resolver
28-
) extends mill.main.MainRootModule() with ScalaModule {
28+
) extends ScalaModule {
2929
override def bspDisplayName0: String = rootModuleInfo
3030
.projectRoot
3131
.relativeTo(rootModuleInfo.topLevelProjectRoot)
@@ -296,7 +296,7 @@ object MillBuildRootModule {
296296
class BootstrapModule()(implicit
297297
rootModuleInfo: RootModule0.Info,
298298
scalaCompilerResolver: ScalaCompilerWorker.Resolver
299-
) extends MillBuildRootModule() {
299+
) extends mill.main.MainRootModule() with MillBuildRootModule() {
300300
override lazy val millDiscover = Discover[this.type]
301301
}
302302

0 commit comments

Comments
 (0)