Skip to content

Commit

Permalink
Simplify codegen prelude implicits (#3749)
Browse files Browse the repository at this point in the history
Removed `MillBuildRootModule.Info` and
`MillBuildRootModule.MillMiscInfo` and consolidated them into
`RootModule.Info` and `SubfolderModule.Info`. Shouldn't affect anything
semantically, just removes some unnecessary indirection that wasn't
doing anything but packing and unpacking the same few values
  • Loading branch information
lihaoyi authored Oct 15, 2024
1 parent 5f617f0 commit 46271c1
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ object RootModuleCompileErrorTests extends UtestIntegrationTestSuite {
)
assert(
res.err.replace('\\', '/').contains(
"""foo/package.mill:6:60: not found: type UnknownFooModule"""
"""foo/package.mill:6:65: not found: type UnknownFooModule"""
)
)
assert(
res.err.contains(
"""abstract class package_ extends RootModule.Subfolder with UnknownFooModule {"""
"""abstract class package_ extends mill.main.SubfolderModule with UnknownFooModule {"""
)
)

Expand Down
59 changes: 23 additions & 36 deletions main/src/mill/main/RootModule.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package mill.main

import mill.api.internal
import mill.define.{BaseModule, Ctx, Caller, Discover, Module, Segments}
import mill.define.{Caller, Discover}
import scala.annotation.compileTimeOnly

/**
Expand All @@ -18,7 +18,7 @@ abstract class RootModule()(implicit
millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
millFile0: sourcecode.File
) extends mill.define.BaseModule(baseModuleInfo.millSourcePath0)(
) extends mill.define.BaseModule(baseModuleInfo.projectRoot)(
millModuleEnclosing0,
millModuleLine0,
millFile0,
Expand All @@ -33,45 +33,32 @@ abstract class RootModule()(implicit

@internal
object RootModule {
case class Info(millSourcePath0: os.Path, discover: Discover)
class Info(
val enclosingClasspath: Seq[os.Path],
val projectRoot: os.Path,
val output: os.Path,
val topLevelProjectRoot: os.Path
) {
def this(
enclosingClasspath0: Seq[String],
projectRoot0: String,
output0: String,
topLevelProjectRoot0: String
) = this(
enclosingClasspath0.map(os.Path(_)),
os.Path(projectRoot0),
os.Path(output0),
os.Path(topLevelProjectRoot0)
)

implicit val millMiscInfo: Info = this
}

object Info {
// Dummy `RootModule.Info` available in implicit scope but never actually used.
// as it is provided by the codegen. Defined for IDEs to think that one is available
// and not show errors in build.mill/package.mill even though they can't see the codegen
@compileTimeOnly("RootModule can only be instantiated in a build.mill or package.mill file")
implicit def dummyInfo: Info = sys.error("implicit RootModule.Info must be provided")
}

case class SubFolderInfo(value: Seq[String])

abstract class Subfolder()(implicit
baseModuleInfo: RootModule.Info,
millModuleLine0: sourcecode.Line,
millFile0: sourcecode.File,
subFolderInfo: SubFolderInfo
) extends Module.BaseClass()(
Ctx.make(
millModuleEnclosing0 = subFolderInfo.value.mkString("."),
millModuleLine0 = millModuleLine0,
millModuleBasePath0 = Ctx.BasePath(baseModuleInfo.millSourcePath0 / os.up),
segments0 = Segments.labels(subFolderInfo.value.init: _*),
external0 = Ctx.External(false),
foreign0 = Ctx.Foreign(None),
fileName = millFile0,
enclosing = Caller(null)
)
) with Module {}

@deprecated
abstract class Foreign(foreign0: Option[Segments])(implicit
baseModuleInfo: RootModule.Info,
millModuleEnclosing0: sourcecode.Enclosing,
millModuleLine0: sourcecode.Line,
millFile0: sourcecode.File
) extends BaseModule(baseModuleInfo.millSourcePath0, foreign0 = foreign0)(
millModuleEnclosing0,
millModuleLine0,
millFile0,
Caller(null)
) with mill.main.MainModule
}
26 changes: 26 additions & 0 deletions main/src/mill/main/Subfolder.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package mill.main;
import mill._
import mill.define.{Caller, Ctx, Segments}

object SubfolderModule {
class Info(val millSourcePath0: os.Path, val segments: Seq[String]) {
implicit val subFolderInfo: Info = this
}
}

abstract class SubfolderModule()(implicit
millModuleLine0: sourcecode.Line,
millFile0: sourcecode.File,
subFolderInfo: SubfolderModule.Info
) extends mill.define.Module.BaseClass()(
Ctx.make(
millModuleEnclosing0 = subFolderInfo.segments.mkString("."),
millModuleLine0 = millModuleLine0,
millModuleBasePath0 = Ctx.BasePath(subFolderInfo.millSourcePath0 / os.up),
segments0 = Segments.labels(subFolderInfo.segments.init: _*),
external0 = Ctx.External(false),
foreign0 = Ctx.Foreign(None),
fileName = millFile0,
enclosing = Caller(null)
)
) with Module {}
40 changes: 20 additions & 20 deletions runner/src/mill/runner/CodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,9 @@ object CodeGen {
) = {
val segments = scriptFolderPath.relativeTo(projectRoot).segments

val prelude = topBuildPrelude(
segments,
scriptFolderPath,
enclosingClasspath,
millTopLevelProjectRoot,
output
)
val prelude =
if (segments.nonEmpty) subfolderBuildPrelude(scriptFolderPath, segments)
else topBuildPrelude(scriptFolderPath, enclosingClasspath, millTopLevelProjectRoot, output)

val instrument = new ObjectDataInstrument(scriptCode)
fastparse.parse(scriptCode, Parsers.CompilationUnit(_), instrument = instrument)
Expand All @@ -154,7 +150,7 @@ object CodeGen {
o.name.text == "`package`" && (o.parent.text == "RootModule" || o.parent.text == "MillBuildRootModule")
) match {
case Some(objectData) =>
val newParent = if (segments.isEmpty) expectedParent else s"RootModule.Subfolder"
val newParent = if (segments.isEmpty) expectedParent else s"mill.main.SubfolderModule"

var newScriptCode = scriptCode
newScriptCode = objectData.parent.applyTo(newScriptCode, newParent)
Expand Down Expand Up @@ -184,21 +180,29 @@ object CodeGen {
}
}

def subfolderBuildPrelude(scriptFolderPath: os.Path, segments: Seq[String]): String = {
s"""object MillMiscSubFolderInfo
|extends mill.main.SubfolderModule.Info(
| os.Path(${literalize(scriptFolderPath.toString)}),
| _root_.scala.Seq(${segments.map(pprint.Util.literalize(_)).mkString(", ")})
|)
|import MillMiscSubFolderInfo._
|""".stripMargin
}

def topBuildPrelude(
segments: Seq[String],
scriptFolderPath: os.Path,
enclosingClasspath: Seq[os.Path],
millTopLevelProjectRoot: os.Path,
output: os.Path
): String = {
s"""import _root_.mill.runner.MillBuildRootModule
|@_root_.scala.annotation.nowarn
|object MillMiscInfo extends MillBuildRootModule.MillMiscInfo(
|object MillMiscInfo extends mill.main.RootModule.Info(
| ${enclosingClasspath.map(p => literalize(p.toString))},
| ${literalize(scriptFolderPath.toString)},
| ${literalize(output.toString)},
| ${literalize(millTopLevelProjectRoot.toString)},
| _root_.scala.Seq(${segments.map(pprint.Util.literalize(_)).mkString(", ")})
| ${literalize(millTopLevelProjectRoot.toString)}
|)
|import MillMiscInfo._
|""".stripMargin
Expand All @@ -210,15 +214,11 @@ object CodeGen {
millTopLevelProjectRoot: os.Path,
childAliases: String
): String = {
val extendsClause = if (segments.isEmpty) {
if (millTopLevelProjectRoot == scriptFolderPath) {
val extendsClause =
if (segments.nonEmpty) s"extends _root_.mill.main.SubfolderModule "
else if (millTopLevelProjectRoot == scriptFolderPath)
s"extends _root_.mill.main.RootModule() "
} else {
s"extends _root_.mill.runner.MillBuildRootModule() "
}
} else {
s"extends _root_.mill.main.RootModule.Subfolder "
}
else s"extends _root_.mill.runner.MillBuildRootModule() "

val millDiscover = discoverSnippet(segments)

Expand Down
20 changes: 8 additions & 12 deletions runner/src/mill/runner/MillBuildBootstrap.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package mill.runner

import mill.util.{ColorLogger, PrefixLogger, Watchable}
import mill.main.BuildInfo
import mill.main.client.CodeGenConstants._
import mill.main.{BuildInfo, RootModule, RunScript}
import mill.main.client.CodeGenConstants.*
import mill.api.{PathRef, SystemStreams, Val, internal}
import mill.eval.Evaluator
import mill.main.RunScript
import mill.resolve.SelectMode
import mill.define.{BaseModule, Discover, Segments}
import mill.define.{BaseModule, Segments}
import mill.main.client.OutFiles.{millBuild, millRunnerState}

import java.net.URLClassLoader
Expand Down Expand Up @@ -111,15 +110,12 @@ class MillBuildBootstrap(
if (parsedScriptFiles.millImport) evaluateRec(depth + 1)
else {
val bootstrapModule =
new MillBuildRootModule.BootstrapModule(
projectRoot,
recRoot(projectRoot, depth),
output,
millBootClasspath
)(
mill.main.RootModule.Info(
new MillBuildRootModule.BootstrapModule()(
new RootModule.Info(
millBootClasspath,
recRoot(projectRoot, depth),
Discover[MillBuildRootModule.BootstrapModule]
output,
projectRoot
)
)
RunnerState(Some(bootstrapModule), Nil, None)
Expand Down
65 changes: 14 additions & 51 deletions runner/src/mill/runner/MillBuildRootModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,16 @@ import mill.define.Target
*/
@internal
abstract class MillBuildRootModule()(implicit
baseModuleInfo: RootModule.Info,
millBuildRootModuleInfo: MillBuildRootModule.Info
rootModuleInfo: RootModule.Info
) extends RootModule() with ScalaModule {
override def bspDisplayName0: String = millBuildRootModuleInfo
override def bspDisplayName0: String = rootModuleInfo
.projectRoot
.relativeTo(millBuildRootModuleInfo.topLevelProjectRoot)
.relativeTo(rootModuleInfo.topLevelProjectRoot)
.segments
.++(super.bspDisplayName0.split("/"))
.mkString("/")

override def millSourcePath: os.Path = millBuildRootModuleInfo.projectRoot / os.up / millBuild
override def millSourcePath: os.Path = rootModuleInfo.projectRoot / os.up / millBuild
override def intellijModulePath: os.Path = millSourcePath / os.up

override def scalaVersion: T[String] = BuildInfo.scalaVersion
Expand All @@ -45,15 +44,15 @@ abstract class MillBuildRootModule()(implicit
* @see [[generateScriptSources]]
*/
def scriptSources: Target[Seq[PathRef]] = Task.Sources {
MillBuildRootModule.parseBuildFiles(millBuildRootModuleInfo)
MillBuildRootModule.parseBuildFiles(rootModuleInfo)
.seenScripts
.keys.map(PathRef(_))
.toSeq
}

def parseBuildFiles: T[FileImportGraph] = Task {
scriptSources()
MillBuildRootModule.parseBuildFiles(millBuildRootModuleInfo)
MillBuildRootModule.parseBuildFiles(rootModuleInfo)
}

override def repositoriesTask: Task[Seq[Repository]] = {
Expand Down Expand Up @@ -116,13 +115,13 @@ abstract class MillBuildRootModule()(implicit
if (parsed.errors.nonEmpty) Result.Failure(parsed.errors.mkString("\n"))
else {
CodeGen.generateWrappedSources(
millBuildRootModuleInfo.projectRoot / os.up,
rootModuleInfo.projectRoot / os.up,
scriptSources(),
parsed.seenScripts,
T.dest,
millBuildRootModuleInfo.enclosingClasspath,
millBuildRootModuleInfo.topLevelProjectRoot,
millBuildRootModuleInfo.output
rootModuleInfo.enclosingClasspath,
rootModuleInfo.topLevelProjectRoot,
rootModuleInfo.output
)
Result.Success(Seq(PathRef(T.dest)))
}
Expand Down Expand Up @@ -212,7 +211,7 @@ abstract class MillBuildRootModule()(implicit
}

def enclosingClasspath: Target[Seq[PathRef]] = Task.Sources {
millBuildRootModuleInfo.enclosingClasspath.map(p => mill.api.PathRef(p, quick = true))
rootModuleInfo.enclosingClasspath.map(p => mill.api.PathRef(p, quick = true))
}

/**
Expand Down Expand Up @@ -266,22 +265,8 @@ abstract class MillBuildRootModule()(implicit

object MillBuildRootModule {

class BootstrapModule(
topLevelProjectRoot0: os.Path,
projectRoot: os.Path,
output: os.Path,
enclosingClasspath: Seq[os.Path]
)(implicit baseModuleInfo: RootModule.Info) extends MillBuildRootModule()(
implicitly,
MillBuildRootModule.Info(
enclosingClasspath,
projectRoot,
output,
topLevelProjectRoot0
)
) {

override lazy val millDiscover: Discover = baseModuleInfo.discover
class BootstrapModule()(implicit rootModuleInfo: RootModule.Info) extends MillBuildRootModule() {
override lazy val millDiscover: Discover = Discover[this.type]
}

case class Info(
Expand All @@ -291,33 +276,11 @@ object MillBuildRootModule {
topLevelProjectRoot: os.Path
)

def parseBuildFiles(millBuildRootModuleInfo: MillBuildRootModule.Info): FileImportGraph = {
def parseBuildFiles(millBuildRootModuleInfo: RootModule.Info): FileImportGraph = {
FileImportGraph.parseBuildFiles(
millBuildRootModuleInfo.topLevelProjectRoot,
millBuildRootModuleInfo.projectRoot / os.up,
millBuildRootModuleInfo.output
)
}

class MillMiscInfo(
enclosingClasspath: Seq[String],
projectRoot: String,
output: String,
topLevelProjectRoot: String,
segments: Seq[String]
) {
implicit lazy val millBuildRootModuleInfo: MillBuildRootModule.Info = MillBuildRootModule.Info(
enclosingClasspath.map(os.Path(_)),
os.Path(projectRoot),
os.Path(output),
os.Path(topLevelProjectRoot)
)
implicit lazy val millBaseModuleInfo: RootModule.Info = RootModule.Info(
millBuildRootModuleInfo.projectRoot,
null
)
implicit lazy val subfolderInfo: RootModule.SubFolderInfo = RootModule.SubFolderInfo(
segments
)
}
}

0 comments on commit 46271c1

Please sign in to comment.