From f0bcc011d7592db9b6e2fc19648c8fb3c7dd3c9d Mon Sep 17 00:00:00 2001 From: Alexandra Dima Date: Tue, 23 Jul 2019 17:56:38 +0200 Subject: Addressed code review feedback. --- .gitignore | 3 +- contrib/bsp/readme.md | 38 ++++++++ .../bsp/src/mill/contrib/MainMillBuildServer.scala | 94 ++++-------------- .../src/mill/contrib/bsp/BspLoggedReporter.scala | 29 +----- .../bsp/src/mill/contrib/bsp/BspTestReporter.scala | 51 +++++----- .../bsp/src/mill/contrib/bsp/MillBspLogger.scala | 22 +++-- .../bsp/src/mill/contrib/bsp/MillBuildServer.scala | 40 +++----- contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala | 108 ++++++++++----------- info.txt | 1 + main/api/src/mill/api/BspCompileArguments.scala | 4 - main/core/src/eval/Evaluator.scala | 4 +- scratch/.bsp/mill-bsp.json | 1 - .../src/main/scala/BenchmarkSource.scala | 2 + scratch/bsp/src/test/scala/BspTests.scala | 6 +- scratch/build.sc | 2 +- 15 files changed, 178 insertions(+), 227 deletions(-) create mode 100644 contrib/bsp/readme.md create mode 100644 info.txt delete mode 100644 scratch/.bsp/mill-bsp.json diff --git a/.gitignore b/.gitignore index b5fa3ece..53cea62c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ out/ /.metals/ contrib/bsp/mill-external-bs contrib/bsp/mill-out-bs -mill.iml -./bsp \ No newline at end of file +mill.iml \ No newline at end of file diff --git a/contrib/bsp/readme.md b/contrib/bsp/readme.md new file mode 100644 index 00000000..c3846f66 --- /dev/null +++ b/contrib/bsp/readme.md @@ -0,0 +1,38 @@ +# Build Server Protocol support for mill + +The contrib.bsp module was created in order to integrate the Mill build tool +with IntelliJ IDEA via the Build Server Protocol (BSP). It implements most of +the server side functionality described in BSP, and can therefore connect to a +BSP client, including the one behind IntelliJ IDEA. This allows a lot of mill +tasks to be executed from the IDE. + +# Importing an existing mill project in IntelliJ via BSP + +1) Following the mill installation instructions +2) Add the following import statement in the build.sc +of your project: + + `import $ivy.com.lihaoyi::mill-contrib-bsp:$MILL_VERSION` + +3) Run the following command in the working directory of your project: + + `mill -i mill.contrib.BSP/install` + This should create a `.bsp/` directory inside your working directory, + containing a BSP connection file that clients can use to start the + BSP server for Mill. + + This command should be ran whenever you chnage the version of mill that + you use. + +4) Now you can use IntelliJ to import your project from existing sources +via bsp ( currently available in the nightly release ). Note: It might +take a few minutes to import a project the very first time. + +## Known Issues: + +- Sometimes build from IntelliJ might fail due to a NoClassDefFoundException +being thrown during the evaluation of tasks, a bug not easy to reproduce. +In this case it is recommended to refresh the bsp project. + +- Currently it's not possible ro run scala classes from intelliJ, but this +issue is being investigated diff --git a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala index 5e9f7c42..b5b9748a 100644 --- a/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala +++ b/contrib/bsp/src/mill/contrib/MainMillBuildServer.scala @@ -1,28 +1,19 @@ package mill.contrib -import java.io.{BufferedReader, File, InputStream, InputStreamReader, OutputStream} - import play.api.libs.json._ import java.nio.file.FileAlreadyExistsException -import java.util.concurrent.{CancellationException, CompletableFuture, ExecutorService, Executors, Future} +import java.util.concurrent.Executors import upickle.default._ -import ch.epfl.scala.bsp4j.{BspConnectionDetails, BuildClient, BuildTargetIdentifier, CleanCacheParams, CompileParams, CompileTask, DidChangeBuildTarget, LogMessageParams, PublishDiagnosticsParams, ScalaTestClassesParams, ScalacOptionsParams, ShowMessageParams, SourcesParams, TaskFinishParams, TaskProgressParams, TaskStartParams, TestParams, WorkspaceBuildTargetsResult} +import ch.epfl.scala.bsp4j._ import mill._ -import mill.api.Result.{Aborted, Skipped} -import mill.api.{BspContext, Result, Strict} -import mill.contrib.bsp.{BspLoggedReporter, MillBspLogger, MillBuildServer, ModuleUtils, TaskParameters} -import mill.define.{Command, Discover, ExternalModule, Target, Task} +import mill.contrib.bsp.ModuleUtils +import mill.define.{Command, Discover, ExternalModule} import mill.eval.Evaluator -import mill.scalalib._ -import mill.util.DummyLogger -import org.eclipse.lsp4j.jsonrpc.{CompletableFutures, Launcher} -import requests.Compress.None -import sbt.testing.Event -import upickle.default +import mill.scalalib.JavaModule +import org.eclipse.lsp4j.jsonrpc.Launcher import scala.collection.JavaConverters._ -import scala.io.Source object BSP extends ExternalModule { @@ -31,13 +22,11 @@ object BSP extends ExternalModule { lazy val millDiscover: Discover[BSP.this.type] = Discover[this.type] val version = "1.0.0" - val bspVersion = "2.0.0-M4" + val bspVersion = "2.0.0" val languages = List("scala", "java") - // returns the mill installation path in the user's system - def whichMill(): String = { - import sys.process._ - "which mill"!! + def whichJava: String = { + if (scala.sys.props.contains("JAVA_HOME")) scala.sys.props("JAVA_HOME") else "java" } // creates a Json with the BSP connection details @@ -52,12 +41,13 @@ object BSP extends ExternalModule { "languages" -> new JsArray(connection.getLanguages.asScala.map(string => JsString(string)).toIndexedSeq) ) } - val millPath = whichMill().replaceAll("\n", "") + val millPath = scala.sys.props("MILL_CLASSPATH") Json.toJson(new BspConnectionDetails("mill-bsp", - List("java","-DMILL_CLASSPATH=" + millPath, - "-DMILL_VERSION=0.4.0", "-Djna.nosys=true", "-cp", + List(whichJava,"-DMILL_CLASSPATH=" + millPath, + s"-DMILL_VERSION=${scala.sys.props("MILL_VERSION")}", + "-Djna.nosys=true", "-cp", millPath, - "mill.MillMain mill.contrib.BSP/start").asJava, + "mill.MillMain", "mill.contrib.BSP/start").asJava, version, bspVersion, languages.asJava)) @@ -80,16 +70,14 @@ object BSP extends ExternalModule { */ def install(ev: Evaluator): Command[Unit] = T.command{ val bspDirectory = os.pwd / ".bsp" - + if (! os.exists(bspDirectory)) os.makeDir.all(bspDirectory) try { - os.makeDir(bspDirectory) - os.write(bspDirectory / "mill-bsp.json", Json.stringify(createBspConnectionJson())) + os.write(bspDirectory / "mill.json", Json.stringify(createBspConnectionJson())) } catch { case e: FileAlreadyExistsException => println("The bsp connection json file probably exists already - will be overwritten") - os.remove.all(bspDirectory) - install(ev) - () + os.remove(bspDirectory / "mill.json") + os.write(bspDirectory / "mill.json", Json.stringify(createBspConnectionJson())) //TODO: Do I want to catch this or throw the exception? case e: Exception => println("An exception occurred while installing mill-bsp: " + e.getMessage + " " + e.getStackTrace.toString) @@ -132,7 +120,7 @@ object BSP extends ExternalModule { System.err.println("Cause: " + e.getCause) System.err.println("Message: " + e.getMessage) System.err.println("Exception class: " + e.getClass) - e.printStackTrace() + System.err.println("Stack Trace: " + e.getStackTrace) } finally { System.err.println("Shutting down executor") executor.shutdown() @@ -143,48 +131,8 @@ object BSP extends ExternalModule { val eval = new Evaluator(ev.home, ev.outPath, ev.externalOutPath, ev.rootModule, ev.log, ev.classLoaderSig, ev.workerCache, ev.env, false) val millServer = new mill.contrib.bsp.MillBuildServer(eval, bspVersion, version, languages) - val client = new BuildClient { - var diagnostics = List.empty[PublishDiagnosticsParams] - override def onBuildShowMessage(params: ShowMessageParams): Unit = { - - } - override def onBuildLogMessage(params: LogMessageParams): Unit = { - - } - override def onBuildTaskStart(params: TaskStartParams): Unit = { - - } - override def onBuildTaskProgress(params: TaskProgressParams): Unit = { - - } - override def onBuildTaskFinish(params: TaskFinishParams): Unit = { - //println("Task Finish: " + params) - } - override def onBuildPublishDiagnostics( - params: PublishDiagnosticsParams - ): Unit = { - println("Diagnostics: " + params) - } - override def onBuildTargetDidChange(params: DidChangeBuildTarget): Unit = - ??? - } - millServer.client = client - } - } - /** - * Allows minimal testing and installing the build server - * from the command line. - * @param args: can be - exp: executes code in the experiment - * method, helps with testing the server - * - install: installs the mill-bsp server in the - * working directory. - */ - def main(args: Array[String]) { - args(0) match { - case e: String => println("Wrong command, you can only use:\n " + - "install - creates the bsp connection json file\n") + millServer.initialized = true + println(millServer.workspaceBuildTargets().get) } - - } } \ No newline at end of file diff --git a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala index b4647fed..06c45b79 100644 --- a/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala +++ b/contrib/bsp/src/mill/contrib/bsp/BspLoggedReporter.scala @@ -4,12 +4,9 @@ import java.io.File import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.{ConcurrentHashMap, ConcurrentMap} -import ch.epfl.scala.bsp4j.{BuildServer, BuildTargetIdentifier, CompileReport, Diagnostic, InverseSourcesParams, ScalaBuildServer, StatusCode, TaskFinishParams, TaskId, TextDocumentIdentifier} +import ch.epfl.scala.bsp4j._ import ch.epfl.scala.{bsp4j => bsp} -import mill.api.BspContext -import org.eclipse.lsp4j.PublishDiagnosticsParams import sbt.internal.inc.ManagedLoggedReporter -import sbt.internal.inc.schema.Position import sbt.internal.util.ManagedLogger import xsbti.{Problem, Severity} @@ -38,13 +35,13 @@ class BspLoggedReporter(client: bsp.BuildClient, } override def logInfo(problem: Problem): Unit = { - client.onBuildPublishDiagnostics(getDiagnostics(problem, targetId, compilationOriginId)) + client.onBuildPublishDiagnostics(getDiagnostics(problem, targetId, compilationOriginId)) infos.incrementAndGet() super.logInfo(problem) } override def logWarning(problem: Problem): Unit = { - client.onBuildPublishDiagnostics(getDiagnostics(problem, targetId, compilationOriginId)) + client.onBuildPublishDiagnostics(getDiagnostics(problem, targetId, compilationOriginId)) warnings.incrementAndGet() super.logWarning(problem) } @@ -76,8 +73,8 @@ class BspLoggedReporter(client: bsp.BuildClient, }) val params = new bsp.PublishDiagnosticsParams(textDocument, targetId, - appendDiagnostics(textDocument, diagnostic).asJava - , true) + appendDiagnostics(textDocument, diagnostic).asJava, + true) if (originId.nonEmpty) { params.setOriginId(originId.get) } diagnosticMap.put(textDocument, params) @@ -116,20 +113,4 @@ class BspLoggedReporter(client: bsp.BuildClient, ) diagnostic } - - private[this] def getErrorCode(file: Option[File], start: bsp.Position, end: bsp.Position, position: xsbti.Position): String = { - file match { - case None => position.lineContent - case f: Option[File] => - val source = Source.fromFile(f.get) - source.close() - val lines = source.getLines.toSeq - val code = lines(start.getLine).substring(start.getCharacter) + - lines.take(start.getLine - 1).takeRight(lines.length - end.getLine - 1).mkString("\n") + - lines(end.getLine).substring(0, end.getCharacter + 1) - code - } - - } - } diff --git a/contrib/bsp/src/mill/contrib/bsp/BspTestReporter.scala b/contrib/bsp/src/mill/contrib/bsp/BspTestReporter.scala index 4027cea9..69471675 100644 --- a/contrib/bsp/src/mill/contrib/bsp/BspTestReporter.scala +++ b/contrib/bsp/src/mill/contrib/bsp/BspTestReporter.scala @@ -27,7 +27,6 @@ class BspTestReporter( taskStartParams.setData(new TestStart(getDisplayName(event))) taskStartParams.setMessage("Starting running: " + getDisplayName(event)) client.onBuildTaskStart(taskStartParams) - println("Logged start") } override def logFinish(event: Event): Unit = { @@ -39,31 +38,30 @@ class BspTestReporter( case default => StatusCode.OK }) taskFinishParams.setDataKind("test-finished") - val testFinish = new TestFinish( - getDisplayName(event), - event.status match { - case sbt.testing.Status.Success => - passed += 1 - TestStatus.PASSED - case sbt.testing.Status.Canceled => - cancelled += 1 - TestStatus.CANCELLED - case sbt.testing.Status.Error => - failed += 1 - TestStatus.FAILED - case sbt.testing.Status.Failure => - failed += 1 - TestStatus.FAILED - case sbt.testing.Status.Ignored => - ignored += 1 - TestStatus.IGNORED - case sbt.testing.Status.Skipped => - skipped += 1 - TestStatus.SKIPPED - case sbt.testing.Status.Pending => - skipped += 1 - TestStatus.SKIPPED //TODO: what to do here - }) + val status = event.status match { + case sbt.testing.Status.Success => + passed += 1 + TestStatus.PASSED + case sbt.testing.Status.Canceled => + cancelled += 1 + TestStatus.CANCELLED + case sbt.testing.Status.Error => + failed += 1 + TestStatus.FAILED + case sbt.testing.Status.Failure => + failed += 1 + TestStatus.FAILED + case sbt.testing.Status.Ignored => + ignored += 1 + TestStatus.IGNORED + case sbt.testing.Status.Skipped => + skipped += 1 + TestStatus.SKIPPED + case sbt.testing.Status.Pending => + skipped += 1 + TestStatus.SKIPPED //TODO: what to do here + } + val testFinish = new TestFinish(getDisplayName(event), status) taskFinishParams.setData(testFinish) taskFinishParams.setEventTime(System.currentTimeMillis()) taskFinishParams.setMessage("Finished running: " + getDisplayName(event)) @@ -76,7 +74,6 @@ class BspTestReporter( exception.getClass.toString)) } client.onBuildTaskFinish(taskFinishParams) - println("Logged finish") } def getDisplayName(e: Event): String = { diff --git a/contrib/bsp/src/mill/contrib/bsp/MillBspLogger.scala b/contrib/bsp/src/mill/contrib/bsp/MillBspLogger.scala index d7dd62b1..811c898c 100644 --- a/contrib/bsp/src/mill/contrib/bsp/MillBspLogger.scala +++ b/contrib/bsp/src/mill/contrib/bsp/MillBspLogger.scala @@ -9,15 +9,19 @@ import mill.util.ProxyLogger class MillBspLogger(client: BuildClient, taskId: Int, logger: Logger) extends ProxyLogger(logger) { override def ticker(s: String): Unit = { - val progressString = s.split(" ")(0) - val progress = progressString.substring(1, progressString.length - 1).split("/") - val params = new TaskProgressParams(new TaskId(taskId.toString)) - params.setEventTime(System.currentTimeMillis()) - params.setMessage(s) - params.setUnit(s.split(" ")(1)) - params.setProgress(progress(0).toLong) - params.setTotal(progress(1).toLong) - client.onBuildTaskProgress(params) + try { + val progressString = s.split(" ")(0) + val progress = progressString.substring(1, progressString.length - 1).split("/") + val params = new TaskProgressParams(new TaskId(taskId.toString)) + params.setEventTime(System.currentTimeMillis()) + params.setMessage(s) + params.setUnit(s.split(" ")(1)) + params.setProgress(progress(0).toLong) + params.setTotal(progress(1).toLong) + client.onBuildTaskProgress(params) + } catch { + case e: Exception => + } } } diff --git a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala index e5319b77..b5ebf83e 100644 --- a/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala +++ b/contrib/bsp/src/mill/contrib/bsp/MillBuildServer.scala @@ -1,11 +1,11 @@ package mill.contrib.bsp + import java.io.File import sbt.testing._ -import java.util.{Calendar, Collections} +import java.util.Collections import java.util.concurrent.CompletableFuture -import scala.compat.java8.OptionConverters._ import mill.scalalib.Lib.discoverTests import ch.epfl.scala.bsp4j._ import mill.{scalalib, _} @@ -13,19 +13,13 @@ import mill.api.{BspContext, Loose, Result, Strict} import mill.contrib.bsp.ModuleUtils._ import mill.eval.Evaluator import mill.scalalib._ -import mill.scalalib.api.{CompilationResult, ZincWorkerApi} +import mill.scalalib.api.CompilationResult import sbt.internal.inc._ -import xsbti.{Position, Problem, Severity} -import xsbti.compile.{AnalysisContents, AnalysisStore, FileAnalysisStore} -import xsbti.compile.analysis.SourceInfo -import mill.api.Result.{Failing, Failure, Success} import scala.collection.JavaConverters._ import mill.modules.Jvm -import mill.util.{Ctx, PrintLogger} -import mill.define.{Discover, ExternalModule, Target, Task} -import org.eclipse.lsp4j.InitializeError -import org.eclipse.lsp4j.jsonrpc.messages.{ResponseError, ResponseErrorCode} +import mill.util.Ctx +import mill.define.{Discover, ExternalModule} import sbt.internal.util.{ConsoleOut, MainAppender, ManagedLogger} import sbt.util.LogExchange @@ -43,7 +37,7 @@ class MillBuildServer(evaluator: Evaluator, val supportedLanguages: List[String] = languages val millServerVersion: String = serverVersion var cancelator: () => Unit = () => () - var millEvaluator: Evaluator = evaluator + val millEvaluator: Evaluator = evaluator var rootModule: JavaModule = ModuleUtils.getRootJavaModule(evaluator.rootModule) var millModules: Seq[JavaModule] = getMillModules(millEvaluator) var client: BuildClient = _ @@ -55,7 +49,7 @@ class MillBuildServer(evaluator: Evaluator, var moduleToTarget: Predef.Map[JavaModule, BuildTarget] = ModuleUtils.millModulesToBspTargets(millModules, rootModule, evaluator, List("scala", "java")) var moduleCodeToTargetId: Predef.Map[Int, BuildTargetIdentifier] = - for ( (targetId, module) <- targetIdToModule ) yield (targetId, module.hashCode()).swap + for ( (targetId, module) <- targetIdToModule ) yield (module.hashCode(), targetId) var initialized = false var clientInitialized = false @@ -156,15 +150,12 @@ class MillBuildServer(evaluator: Evaluator, def getInverseSourcesResult: InverseSourcesResult = { val textDocument = inverseSourcesParams.getTextDocument - - val targets = (for (targetId <- targetIdToModule.keys - if buildTargetSources(new SourcesParams(Collections.singletonList(targetId))). - get.getItems.asScala.head.getSources.asScala. - exists( - item => os.list(os.Path(item.getUri)). - map(dir => dir.toIO.toURI.toString).contains(textDocument.getUri))) - yield targetId).toList.asJava - new InverseSourcesResult(targets) + val targets = millModules.filter(m => ModuleUtils.evaluateInformativeTask( + millEvaluator, m.allSourceFiles, Seq.empty[PathRef]). + map(pathRef => pathRef.path.toIO.toURI.toString). + contains(textDocument.getUri)). + map(m => moduleToTargetId(m)) + new InverseSourcesResult(targets.asJava) } handleExceptions[String, InverseSourcesResult]((in) => getInverseSourcesResult, "") } @@ -313,7 +304,7 @@ class MillBuildServer(evaluator: Evaluator, } private[this] def getStatusCode(results: Evaluator.Results): StatusCode = { - System.err.println("Results: " + results.rawValues) + if (results.failing.keyCount > 0) { StatusCode.ERROR } @@ -340,7 +331,6 @@ class MillBuildServer(evaluator: Evaluator, val module = targetIdToModule(targetId) module match { case m: TestModule => val testModule = m.asInstanceOf[TestModule] - println("Arguments: " + argsMap(targetId)) val testTask = testModule.testLocal(argsMap(targetId):_*) // notifying the client that the testing of this build target started @@ -356,8 +346,6 @@ class MillBuildServer(evaluator: Evaluator, new TaskId(testTask.hashCode().toString), Seq.empty[String]) - println("BspContext: " + bspContext) - val results = millEvaluator.evaluate( Strict.Agg(testTask), getBspLoggedReporterPool(params, (t) => s"Started compiling target: $t", diff --git a/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala b/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala index d593bceb..c5f203b5 100644 --- a/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala +++ b/contrib/bsp/src/mill/contrib/bsp/ModuleUtils.scala @@ -21,55 +21,16 @@ import os.Path object ModuleUtils { - object dummyModule extends mill.define.ExternalModule { - lazy val millDiscover: Discover[dummyModule.this.type] = Discover[this.type] - } - - val dummyEvalautor: Evaluator = new Evaluator(os.pwd / "contrib" / "bsp" / "mill-bs", - os.pwd / "contrib" / "bsp" / "mill-out-bs", - os.pwd / "contrib" / "bsp" / "mill-external-bs", - dummyModule, DummyLogger) - def millModulesToBspTargets(modules: Seq[JavaModule], rootModule: JavaModule, evaluator: Evaluator, supportedLanguages: List[String]): Predef.Map[JavaModule, BuildTarget] = { val moduleIdMap = getModuleTargetIdMap(modules, evaluator) - var moduleToTarget = Map.empty[JavaModule, BuildTarget] - - for ( module <- modules ) { - if (module == rootModule) { - moduleToTarget ++= Map(module -> getRootTarget(module, evaluator, moduleIdMap(module))) - } else { - val dataBuildTarget = computeScalaBuildTarget(module, evaluator) - val capabilities = getModuleCapabilities(module, evaluator) - val buildTargetTag: List[String] = module match { - case m: TestModule => List(BuildTargetTag.TEST) - case m: JavaModule => List(BuildTargetTag.LIBRARY, BuildTargetTag.APPLICATION) - } - - val dependencies = module match { - case m: JavaModule => m.moduleDeps.map(dep => moduleIdMap(dep)).toList.asJava - } - - val buildTarget = new BuildTarget(moduleIdMap(module), - buildTargetTag.asJava, - supportedLanguages.asJava, - dependencies, - capabilities) - if (module.isInstanceOf[ScalaModule]) { - buildTarget.setDataKind("scala") - } - buildTarget.setData(dataBuildTarget) - buildTarget.setDisplayName(moduleName(module.millModuleSegments)) - buildTarget.setBaseDirectory(module.intellijModulePath.toNIO.toAbsolutePath.toUri.toString) - - if (!moduleToTarget.contains(module)) moduleToTarget ++= Map(module -> buildTarget) - } - } - moduleToTarget + (for ( module <- modules ) + yield (module, getTarget(rootModule, module, evaluator, moduleIdMap))).toMap + } def getRootJavaModule(rootBaseModule: BaseModule): JavaModule = { @@ -87,10 +48,13 @@ object ModuleUtils { } } - def getRootTarget(rootModule: JavaModule, evaluator: Evaluator, targetId: BuildTargetIdentifier): BuildTarget = { + def getRootTarget( + rootModule: JavaModule, + evaluator: Evaluator, + moduleIdMap: Map[JavaModule, BuildTargetIdentifier]): BuildTarget = { val rootTarget = new BuildTarget( - targetId, + moduleIdMap(rootModule), List.empty[String].asJava, List.empty[String].asJava, List.empty[BuildTargetIdentifier].asJava, @@ -98,7 +62,7 @@ object ModuleUtils { rootTarget.setBaseDirectory(rootModule.millSourcePath.toNIO.toAbsolutePath.toUri.toString) rootTarget.setDataKind("scala") rootTarget.setTags(List(BuildTargetTag.LIBRARY, BuildTargetTag.APPLICATION).asJava) - rootTarget.setData(computeScalaBuildTarget(rootModule, evaluator)) + rootTarget.setData(computeBuildTargetData(rootModule, evaluator)) val basePath = rootModule.millSourcePath.toIO.toPath if (basePath.getNameCount >= 1) rootTarget.setDisplayName(basePath.getName(basePath.getNameCount - 1) + "-root") @@ -106,6 +70,46 @@ object ModuleUtils { rootTarget } + def getRegularTarget( + module: JavaModule, + evaluator: Evaluator, + moduleIdMap: Map[JavaModule, BuildTargetIdentifier]): BuildTarget = { + val dataBuildTarget = computeBuildTargetData(module, evaluator) + val capabilities = getModuleCapabilities(module, evaluator) + val buildTargetTag: List[String] = module match { + case m: TestModule => List(BuildTargetTag.TEST) + case m: JavaModule => List(BuildTargetTag.LIBRARY, BuildTargetTag.APPLICATION) + } + + val dependencies = module match { + case m: JavaModule => m.moduleDeps.map(dep => moduleIdMap(dep)).toList.asJava + } + + val buildTarget = new BuildTarget(moduleIdMap(module), + buildTargetTag.asJava, + List("scala", "java").asJava, + dependencies, + capabilities) + if (module.isInstanceOf[ScalaModule]) { + buildTarget.setDataKind("scala") + } + buildTarget.setData(dataBuildTarget) + buildTarget.setDisplayName(moduleName(module.millModuleSegments)) + buildTarget.setBaseDirectory(module.intellijModulePath.toNIO.toAbsolutePath.toUri.toString) + buildTarget + } + + def getTarget( rootModule: JavaModule, + module: JavaModule, + evaluator: Evaluator, + moduleIdMap: Map[JavaModule, BuildTargetIdentifier] + ): BuildTarget = { + if (module == rootModule) + getRootTarget(module, evaluator, moduleIdMap) + else + getRegularTarget(module, evaluator, moduleIdMap) + } + def getModuleCapabilities(module: JavaModule, evaluator: Evaluator): BuildTargetCapabilities = { val canTest = module match { case module: TestModule => true @@ -116,7 +120,7 @@ object ModuleUtils { } //TODO: Fix the data field for JavaModule when the bsp specification is updated - def computeScalaBuildTarget(module: JavaModule, evaluator: Evaluator): ScalaBuildTarget = { + def computeBuildTargetData(module: JavaModule, evaluator: Evaluator): ScalaBuildTarget = { module match { case m: ScalaModule => val scalaVersion = evaluateInformativeTask(evaluator, m.scalaVersion, "") @@ -170,17 +174,11 @@ object ModuleUtils { } def getModuleTargetIdMap(modules: Seq[JavaModule], evaluator:Evaluator): Predef.Map[JavaModule, BuildTargetIdentifier] = { - var moduleToTarget = Map[JavaModule, BuildTargetIdentifier]() - - for ( module <- modules ) { - moduleToTarget ++= Map(module -> new BuildTargetIdentifier( + (for ( module <- modules ) + yield (module, new BuildTargetIdentifier( (module.millOuterCtx.millSourcePath / os.RelPath(moduleName(module.millModuleSegments))). - toNIO.toAbsolutePath.toUri.toString - )) - } - - moduleToTarget + toNIO.toAbsolutePath.toUri.toString))).toMap } // this is taken from mill.scalalib GenIdeaImpl diff --git a/info.txt b/info.txt new file mode 100644 index 00000000..86fe32d4 --- /dev/null +++ b/info.txt @@ -0,0 +1 @@ +Build 2 diff --git a/main/api/src/mill/api/BspCompileArguments.scala b/main/api/src/mill/api/BspCompileArguments.scala index 9cfdd500..1af45a61 100644 --- a/main/api/src/mill/api/BspCompileArguments.scala +++ b/main/api/src/mill/api/BspCompileArguments.scala @@ -6,8 +6,4 @@ class BspCompileArguments { def args: Seq[String] = { arguments } - - def setArgs(args: Seq[String]): Unit = { - arguments = args - } } diff --git a/main/core/src/eval/Evaluator.scala b/main/core/src/eval/Evaluator.scala index c6a1f52a..75103398 100644 --- a/main/core/src/eval/Evaluator.scala +++ b/main/core/src/eval/Evaluator.scala @@ -29,8 +29,6 @@ case class Labelled[T](task: NamedTask[T], case t: Target[T] => Some(t.readWrite.asInstanceOf[upickle.default.ReadWriter[T]]) case _ => None } - -// override def hashCode(): Int = task.hashCode() } case class Evaluator(home: os.Path, @@ -344,7 +342,7 @@ case class Evaluator(home: os.Path, home, env, reporter, - bspContext //new ManagedLoggedReporter(10, logger) + bspContext ) val out = System.out diff --git a/scratch/.bsp/mill-bsp.json b/scratch/.bsp/mill-bsp.json deleted file mode 100644 index 39d2d592..00000000 --- a/scratch/.bsp/mill-bsp.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"mill-bsp","argv":["../out/dev/launcher/dest/run", "-i", "mill.contrib.MainMillBuildServer/startServer"],"version":"1.0.0","bspVersion":"2.0.0-M4","languages":["scala","java"]} diff --git a/scratch/benchmarks/src/main/scala/BenchmarkSource.scala b/scratch/benchmarks/src/main/scala/BenchmarkSource.scala index b690179c..fa3633a4 100644 --- a/scratch/benchmarks/src/main/scala/BenchmarkSource.scala +++ b/scratch/benchmarks/src/main/scala/BenchmarkSource.scala @@ -7,7 +7,9 @@ import java.io.File object BenchmarkSource { //val reader = new InputReader() + def main(args: Array[String]): Unit = { + val unusedValue = 3 val file = FileUtils.getFile("/home/alexandra/test_build1/build.sc") println(file) } diff --git a/scratch/bsp/src/test/scala/BspTests.scala b/scratch/bsp/src/test/scala/BspTests.scala index 21ba4bfe..f565217f 100644 --- a/scratch/bsp/src/test/scala/BspTests.scala +++ b/scratch/bsp/src/test/scala/BspTests.scala @@ -1,8 +1,10 @@ package tests import org.scalatest.FunSuite +import org.apache.commons.io.FileUtils -object BspTests extends FunSuite { +class BspTests extends FunSuite { + val wrongVal: String = 3 test("test 1") { - assert(new CoreTests().coreValue > 0) + assert(CoreTests().coreValue > 0) } } diff --git a/scratch/build.sc b/scratch/build.sc index 98bdca27..bdc731d3 100644 --- a/scratch/build.sc +++ b/scratch/build.sc @@ -1,5 +1,5 @@ import mill.scalalib.{SbtModule, Dep, DepSyntax} -//import $ivy.`com.lihaoyi::mill-contrib-bsp:0.5.0-28-53df48-DIRTYf21142f7` +//import $ivy.`com.lihaoyi::mill-contrib-bsp:0.5.0-40-278984-DIRTY7f118075` trait BetterFilesModule extends SbtModule{ def scalaVersion = "2.12.4" -- cgit v1.2.3