From 6d2a516df521036c0fae52d803ae6718a3c735d0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jan 2021 14:16:35 -0500 Subject: [PATCH 1/5] Port XMainConfiguration to Java The bytecode generated by 2.13 compiler contains scala.runtime.BoxedUnit in the constant pool. To avoid referencing scala-library, port XMainConfiguration to Java. --- build.sbt | 6 +- .../java/sbt/internal/XMainConfiguration.java | 299 ++++++++++++++++++ .../sbt/internal/ClassLoaderWarmup.scala | 40 +++ .../sbt/internal/XMainConfiguration.scala | 186 ----------- 4 files changed, 344 insertions(+), 187 deletions(-) create mode 100644 main/src/main/java/sbt/internal/XMainConfiguration.java create mode 100644 main/src/main/scala/sbt/internal/ClassLoaderWarmup.scala delete mode 100644 main/src/main/scala/sbt/internal/XMainConfiguration.scala diff --git a/build.sbt b/build.sbt index 443a3661b..5793bf6d3 100644 --- a/build.sbt +++ b/build.sbt @@ -1029,7 +1029,11 @@ lazy val mainProj = (project in file("main")) // internal logging apis, exclude[IncompatibleSignatureProblem]("sbt.internal.LogManager*"), exclude[MissingTypesProblem]("sbt.internal.RelayAppender"), - exclude[MissingClassProblem]("sbt.internal.TaskProgress$ProgressThread") + exclude[MissingClassProblem]("sbt.internal.TaskProgress$ProgressThread"), + // internal implementation + exclude[MissingClassProblem]( + "sbt.internal.XMainConfiguration$ModifiedConfiguration$ModifiedAppProvider$ModifiedScalaProvider$" + ), ) ) .configure( diff --git a/main/src/main/java/sbt/internal/XMainConfiguration.java b/main/src/main/java/sbt/internal/XMainConfiguration.java new file mode 100644 index 000000000..9cebe23af --- /dev/null +++ b/main/src/main/java/sbt/internal/XMainConfiguration.java @@ -0,0 +1,299 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import xsbti.*; + +/** + * Generates a new app configuration and invokes xMainImpl.run. For AppConfigurations generated by + * recent launchers, it is unnecessary to modify the original configuration, but configurations + * generated by older launchers need to be modified to place the test interface jar higher in the + * class hierarchy. The methods this object are implemented without using the scala library so that + * we can avoid loading any classes from the old scala provider. + */ +public class XMainConfiguration { + public xsbti.MainResult run(String moduleName, xsbti.AppConfiguration configuration) { + try { + ClassLoader topLoader = configuration.provider().scalaProvider().launcher().topLoader(); + xsbti.AppConfiguration updatedConfiguration = null; + try { + Method method = topLoader.getClass().getMethod("getJLineJars"); + URL[] jars = (URL[]) method.invoke(topLoader); + boolean canReuseConfiguration = jars.length == 3; + int j = 0; + while (j < jars.length && canReuseConfiguration) { + String s = jars[j].toString(); + canReuseConfiguration = s.contains("jline") || s.contains("jansi"); + j += 1; + } + if (canReuseConfiguration && j == 3) { + updatedConfiguration = configuration; + } else { + updatedConfiguration = makeConfiguration(configuration); + } + } catch (NoSuchMethodException e) { + updatedConfiguration = makeConfiguration(configuration); + } + + ClassLoader loader = updatedConfiguration.provider().loader(); + Thread.currentThread().setContextClassLoader(loader); + Class clazz = loader.loadClass("sbt." + moduleName + "$"); + Object instance = clazz.getField("MODULE$").get(null); + Method runMethod = clazz.getMethod("run", xsbti.AppConfiguration.class); + try { + Class clw = loader.loadClass("sbt.internal.ClassLoaderWarmup$"); + clw.getMethod("warmup").invoke(clw.getField("MODULE$").get(null)); + return (xsbti.MainResult) runMethod.invoke(instance, updatedConfiguration); + } catch (InvocationTargetException e) { + // This propogates xsbti.FullReload to the launcher + throw (xsbti.FullReload) e.getCause(); + } + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + private xsbti.AppConfiguration makeConfiguration(xsbti.AppConfiguration configuration) { + try { + ClassLoader baseLoader = XMainConfiguration.class.getClassLoader(); + String className = "sbt/internal/XMainConfiguration.class"; + URL url = baseLoader.getResource(className); + String path = url.toString().replaceAll(className.concat("$"), ""); + URL[] urlArray = new URL[1]; + urlArray[0] = new URL(path); + ClassLoader topLoader = configuration.provider().scalaProvider().launcher().topLoader(); + // This loader doesn't have the scala library in it so it's critical that none of the code + // in this file use the scala library. + ClassLoader modifiedLoader = new XMainClassLoader(urlArray, topLoader); + Class xMainConfigurationClass = + modifiedLoader.loadClass("sbt.internal.XMainConfiguration"); + Object instance = (Object) xMainConfigurationClass.getConstructor().newInstance(); + Class metaBuildLoaderClass = modifiedLoader.loadClass("sbt.internal.MetaBuildLoader"); + Method method = metaBuildLoaderClass.getMethod("makeLoader", AppProvider.class); + + ClassLoader loader = (ClassLoader) method.invoke(null, configuration.provider()); + + Thread.currentThread().setContextClassLoader(loader); + Class modifiedConfigurationClass = + modifiedLoader.loadClass("sbt.internal.XMainConfiguration$ModifiedConfiguration"); + Constructor cons = modifiedConfigurationClass.getConstructors()[0]; + ClassLoaderClose.close(configuration.provider().loader()); + ScalaProvider scalaProvider = configuration.provider().scalaProvider(); + Class providerClass = scalaProvider.getClass(); + try { + Method method2 = providerClass.getMethod("loaderLibraryOnly"); + ClassLoaderClose.close((ClassLoader) method2.invoke(scalaProvider)); + } catch (NoSuchMethodException e) { + } + ClassLoaderClose.close(scalaProvider.loader()); + ClassLoaderClose.close(configuration.provider().loader()); + return (xsbti.AppConfiguration) cons.newInstance(instance, configuration, loader); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + + /* + * Replaces the AppProvider.loader method with a new loader that puts the sbt test interface + * jar ahead of the rest of the sbt classpath in the classloading hierarchy. + */ + public class ModifiedConfiguration implements xsbti.AppConfiguration { + private xsbti.AppConfiguration configuration; + private ClassLoader metaLoader; + + public ModifiedConfiguration(xsbti.AppConfiguration configuration, ClassLoader metaLoader) { + this.configuration = configuration; + this.metaLoader = metaLoader; + } + + public class ModifiedAppProvider implements AppProvider { + private AppProvider appProvider; + private ScalaProvider instance; + + public ModifiedAppProvider(AppProvider appProvider) throws ClassNotFoundException { + this.appProvider = appProvider; + ScalaProvider delegate = configuration.provider().scalaProvider(); + this.instance = + new ScalaProvider() { + public Launcher _launcher = + new Launcher() { + private Launcher delegateLauncher = delegate.launcher(); + private ClassLoader interfaceLoader = + metaLoader.loadClass("sbt.testing.Framework").getClassLoader(); + + @Override + public ScalaProvider getScala(String version) { + return getScala(version, ""); + } + + @Override + public ScalaProvider getScala(String version, String reason) { + return getScala(version, reason, "org.scala-lang"); + } + + @Override + public ScalaProvider getScala(String version, String reason, String scalaOrg) { + return delegateLauncher.getScala(version, reason, scalaOrg); + } + + @Override + public AppProvider app(xsbti.ApplicationID id, String version) { + return delegateLauncher.app(id, version); + } + + @Override + public ClassLoader topLoader() { + return interfaceLoader; + } + + @Override + public GlobalLock globalLock() { + return delegateLauncher.globalLock(); + } + + @Override + public File bootDirectory() { + return delegateLauncher.bootDirectory(); + } + + @Override + public xsbti.Repository[] ivyRepositories() { + return delegateLauncher.ivyRepositories(); + } + + @Override + public xsbti.Repository[] appRepositories() { + return delegateLauncher.appRepositories(); + } + + @Override + public boolean isOverrideRepositories() { + return delegateLauncher.isOverrideRepositories(); + } + + @Override + public File ivyHome() { + return delegateLauncher.ivyHome(); + } + + @Override + public String[] checksums() { + return delegateLauncher.checksums(); + } + }; + + @Override + public Launcher launcher() { + return this._launcher; + } + + @Override + public String version() { + return delegate.version(); + } + + @Override + public ClassLoader loader() { + return metaLoader.getParent(); + } + + @Override + public File[] jars() { + return delegate.jars(); + } + + @Override + @Deprecated() + public File libraryJar() { + return delegate.libraryJar(); + } + + @Override + @Deprecated() + public File compilerJar() { + return delegate.compilerJar(); + } + + @Override + public AppProvider app(xsbti.ApplicationID id) { + return delegate.app(id); + } + + private ClassLoader loaderLibraryOnly() { + return metaLoader.getParent().getParent(); + } + }; + } + + @Override + public ScalaProvider scalaProvider() { + return instance; + } + + @Override + public xsbti.ApplicationID id() { + return appProvider.id(); + } + + @Override + public ClassLoader loader() { + return metaLoader; + } + + @Override + @Deprecated() + public Class mainClass() { + return appProvider.mainClass(); + } + + @Override + public Class entryPoint() { + return appProvider.entryPoint(); + } + + @Override + public AppMain newMain() { + return appProvider.newMain(); + } + + @Override + public File[] mainClasspath() { + return appProvider.mainClasspath(); + } + + @Override + public ComponentProvider components() { + return appProvider.components(); + } + } + + @Override + public String[] arguments() { + return configuration.arguments(); + } + + @Override + public File baseDirectory() { + return configuration.baseDirectory(); + } + + @Override + public AppProvider provider() { + try { + return new ModifiedAppProvider(configuration.provider()); + } catch (Throwable e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/main/src/main/scala/sbt/internal/ClassLoaderWarmup.scala b/main/src/main/scala/sbt/internal/ClassLoaderWarmup.scala new file mode 100644 index 000000000..00159964e --- /dev/null +++ b/main/src/main/scala/sbt/internal/ClassLoaderWarmup.scala @@ -0,0 +1,40 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt.internal + +import java.util.concurrent.{ ExecutorService, Executors } +import sbt.plugins.{ CorePlugin, IvyPlugin, JvmPlugin } + +private[internal] object ClassLoaderWarmup { + def warmup(): Unit = { + if (Runtime.getRuntime.availableProcessors > 1) { + val executorService: ExecutorService = + Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors - 1) + def submit[R](f: => R): Unit = { + executorService.submit(new Runnable { + override def run(): Unit = { f; () } + }) + () + } + + submit(Class.forName("sbt.internal.parser.SbtParserInit").getConstructor().newInstance()) + submit(CorePlugin.projectSettings) + submit(IvyPlugin.projectSettings) + submit(JvmPlugin.projectSettings) + submit(() => { + try { + val clazz = Class.forName("scala.reflect.runtime.package$") + clazz.getMethod("universe").invoke(clazz.getField("MODULE$").get(null)) + } catch { + case _: Exception => + } + executorService.shutdown() + }) + } + } +} diff --git a/main/src/main/scala/sbt/internal/XMainConfiguration.scala b/main/src/main/scala/sbt/internal/XMainConfiguration.scala deleted file mode 100644 index 93dcb4e3b..000000000 --- a/main/src/main/scala/sbt/internal/XMainConfiguration.scala +++ /dev/null @@ -1,186 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2018, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under Apache License 2.0 (see LICENSE) - */ - -package sbt.internal - -import java.io.File -import java.lang.reflect.InvocationTargetException -import java.net.URL -import java.util.concurrent.{ ExecutorService, Executors } -import ClassLoaderClose.close - -import sbt.plugins.{ CorePlugin, IvyPlugin, JvmPlugin } -import xsbti._ - -private[internal] object ClassLoaderWarmup { - def warmup(): Unit = { - if (Runtime.getRuntime.availableProcessors > 1) { - val executorService: ExecutorService = - Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors - 1) - def submit[R](f: => R): Unit = { - executorService.submit(new Runnable { - override def run(): Unit = { f; () } - }) - () - } - - submit(Class.forName("sbt.internal.parser.SbtParserInit").getConstructor().newInstance()) - submit(CorePlugin.projectSettings) - submit(IvyPlugin.projectSettings) - submit(JvmPlugin.projectSettings) - submit(() => { - try { - val clazz = Class.forName("scala.reflect.runtime.package$") - clazz.getMethod("universe").invoke(clazz.getField("MODULE$").get(null)) - } catch { - case _: Exception => - } - executorService.shutdown() - }) - } - } -} - -/** - * Generates a new app configuration and invokes xMainImpl.run. For AppConfigurations generated - * by recent launchers, it is unnecessary to modify the original configuration, but configurations - * generated by older launchers need to be modified to place the test interface jar higher in - * the class hierarchy. The methods this object are implemented without using the scala library - * so that we can avoid loading any classes from the old scala provider. Verified as of - * sbt 1.3.0 that there are no references to the scala standard library in any of the methods - * in this file. - */ -private[sbt] class XMainConfiguration { - def run(moduleName: String, configuration: xsbti.AppConfiguration): xsbti.MainResult = { - val topLoader = configuration.provider.scalaProvider.launcher.topLoader - val updatedConfiguration = - try { - val method = topLoader.getClass.getMethod("getJLineJars") - val jars = method.invoke(topLoader).asInstanceOf[Array[URL]] - var canReuseConfiguration = jars.length == 3 - var j = 0 - while (j < jars.length && canReuseConfiguration) { - val s = jars(j).toString - canReuseConfiguration = s.contains("jline") || s.contains("jansi") - j += 1 - } - if (canReuseConfiguration && j == 3) configuration else makeConfiguration(configuration) - } catch { - case _: NoSuchMethodException => makeConfiguration(configuration) - } - val loader = updatedConfiguration.provider.loader - Thread.currentThread.setContextClassLoader(loader) - val clazz = loader.loadClass(s"sbt.$moduleName$$") - val instance = clazz.getField("MODULE$").get(null) - val runMethod = clazz.getMethod("run", classOf[xsbti.AppConfiguration]) - try { - val clw = loader.loadClass("sbt.internal.ClassLoaderWarmup$") - clw.getMethod("warmup").invoke(clw.getField("MODULE$").get(null)) - runMethod.invoke(instance, updatedConfiguration).asInstanceOf[xsbti.MainResult] - } catch { - case e: InvocationTargetException => - // This propogates xsbti.FullReload to the launcher - throw e.getCause - } - } - - private def makeConfiguration(configuration: xsbti.AppConfiguration): xsbti.AppConfiguration = { - val baseLoader = classOf[XMainConfiguration].getClassLoader - val className = "sbt/internal/XMainConfiguration.class" - val url = baseLoader.getResource(className) - val path = url.toString.replaceAll(s"$className$$", "") - val urlArray = new Array[URL](1) - urlArray(0) = new URL(path) - val topLoader = configuration.provider.scalaProvider.launcher.topLoader - // This loader doesn't have the scala library in it so it's critical that none of the code - // in this file use the scala library. - val modifiedLoader = new XMainClassLoader(urlArray, topLoader) - val xMainConfigurationClass = modifiedLoader.loadClass("sbt.internal.XMainConfiguration") - val instance: AnyRef = - xMainConfigurationClass.getConstructor().newInstance().asInstanceOf[AnyRef] - - val metaBuildLoaderClass = modifiedLoader.loadClass("sbt.internal.MetaBuildLoader") - val method = metaBuildLoaderClass.getMethod("makeLoader", classOf[AppProvider]) - - val loader = method.invoke(null, configuration.provider).asInstanceOf[ClassLoader] - - Thread.currentThread.setContextClassLoader(loader) - val modifiedConfigurationClass = - modifiedLoader.loadClass("sbt.internal.XMainConfiguration$ModifiedConfiguration") - val cons = modifiedConfigurationClass.getConstructors()(0) - close(configuration.provider.loader) - val scalaProvider = configuration.provider.scalaProvider - val providerClass = scalaProvider.getClass - val _ = try { - val method = providerClass.getMethod("loaderLibraryOnly") - close(method.invoke(scalaProvider).asInstanceOf[ClassLoader]) - 1 - } catch { case _: NoSuchMethodException => 1 } - close(scalaProvider.loader) - close(configuration.provider.loader) - cons.newInstance(instance, configuration, loader).asInstanceOf[xsbti.AppConfiguration] - } - - /* - * Replaces the AppProvider.loader method with a new loader that puts the sbt test interface - * jar ahead of the rest of the sbt classpath in the classloading hierarchy. - */ - private[sbt] class ModifiedConfiguration( - val configuration: xsbti.AppConfiguration, - val metaLoader: ClassLoader - ) extends xsbti.AppConfiguration { - - private class ModifiedAppProvider(val appProvider: AppProvider) extends AppProvider { - private val delegate = configuration.provider.scalaProvider - object ModifiedScalaProvider extends ScalaProvider { - override def launcher(): Launcher = new Launcher { - private val delegateLauncher = delegate.launcher - private val interfaceLoader = metaLoader.loadClass("sbt.testing.Framework").getClassLoader - override def getScala(version: String): ScalaProvider = getScala(version, "") - override def getScala(version: String, reason: String): ScalaProvider = - getScala(version, reason, "org.scala-lang") - override def getScala(version: String, reason: String, scalaOrg: String): ScalaProvider = - delegateLauncher.getScala(version, reason, scalaOrg) - override def app(id: xsbti.ApplicationID, version: String): AppProvider = - delegateLauncher.app(id, version) - override def topLoader(): ClassLoader = interfaceLoader - override def globalLock(): GlobalLock = delegateLauncher.globalLock() - override def bootDirectory(): File = delegateLauncher.bootDirectory() - override def ivyRepositories(): Array[xsbti.Repository] = - delegateLauncher.ivyRepositories() - override def appRepositories(): Array[xsbti.Repository] = - delegateLauncher.appRepositories() - override def isOverrideRepositories: Boolean = delegateLauncher.isOverrideRepositories - override def ivyHome(): File = delegateLauncher.ivyHome() - override def checksums(): Array[String] = delegateLauncher.checksums() - } - override def version(): String = delegate.version - override def loader(): ClassLoader = metaLoader.getParent - override def jars(): Array[File] = delegate.jars - @deprecated("Implements deprecated api", "1.3.0") - override def libraryJar(): File = delegate.libraryJar - @deprecated("Implements deprecated api", "1.3.0") - override def compilerJar(): File = delegate.compilerJar - override def app(id: xsbti.ApplicationID): AppProvider = delegate.app(id) - def loaderLibraryOnly(): ClassLoader = metaLoader.getParent.getParent - } - override def scalaProvider(): ModifiedScalaProvider.type = ModifiedScalaProvider - override def id(): xsbti.ApplicationID = appProvider.id() - override def loader(): ClassLoader = metaLoader - @deprecated("Implements deprecated api", "1.3.0") - override def mainClass(): Class[_ <: AppMain] = appProvider.mainClass() - override def entryPoint(): Class[_] = appProvider.entryPoint() - override def newMain(): AppMain = appProvider.newMain() - override def mainClasspath(): Array[File] = appProvider.mainClasspath() - override def components(): ComponentProvider = appProvider.components() - } - override def arguments(): Array[String] = configuration.arguments - override def baseDirectory(): File = configuration.baseDirectory - override def provider(): AppProvider = new ModifiedAppProvider(configuration.provider) - } - -} From dacffb509582d84d608a7f1b8feeb814918e2342 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jan 2021 14:18:22 -0500 Subject: [PATCH 2/5] sbt 1.4.6 and some Metals settings --- build.sbt | 2 ++ project/build.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5793bf6d3..bb1afaa3b 100644 --- a/build.sbt +++ b/build.sbt @@ -17,6 +17,7 @@ ThisBuild / Test / scalafmtOnCompile := !(Global / insideCI).value ThisBuild / turbo := true ThisBuild / usePipelining := false // !(Global / insideCI).value +Global / semanticdbEnabled := true val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys") Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty) Global / excludeLint += componentID @@ -1321,6 +1322,7 @@ def runNpm(command: String, base: File, log: sbt.internal.util.ManagedLogger) = lazy val vscodePlugin = (project in file("vscode-sbt-scala")) .settings( + bspEnabled := false, crossPaths := false, crossScalaVersions := Seq(baseScalaVersion), skip in publish := true, diff --git a/project/build.properties b/project/build.properties index 7de0a9382..d91c272d4 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.4 +sbt.version=1.4.6 From ab402543d33d1e610b202bc3c33d153cb9f7b2ee Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jan 2021 14:20:43 -0500 Subject: [PATCH 3/5] Replace the unicode arrows --- .../main/scala/sbt/internal/graph/backend/IvyReport.scala | 6 +++--- main/src/main/scala/sbt/internal/graph/rendering/DOT.scala | 4 ++-- .../main/scala/sbt/internal/graph/rendering/GraphML.scala | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala b/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala index 99270b939..07fb20312 100644 --- a/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala +++ b/main/src/main/scala/sbt/internal/graph/backend/IvyReport.scala @@ -20,13 +20,13 @@ object IvyReport { def fromReportXML(doc: Document): ModuleGraph = { def edgesForModule(id: GraphModuleId, revision: NodeSeq): Seq[Edge] = for { - caller ← revision \ "caller" + caller <- revision \ "caller" callerModule = moduleIdFromElement(caller, caller.attribute("callerrev").get.text) } yield (moduleIdFromElement(caller, caller.attribute("callerrev").get.text), id) val moduleEdges: Seq[(Module, Seq[Edge])] = for { - mod ← doc \ "dependencies" \ "module" - revision ← mod \ "revision" + mod <- doc \ "dependencies" \ "module" + revision <- mod \ "revision" rev = revision.attribute("name").get.text moduleId = moduleIdFromElement(mod, rev) module = Module( diff --git a/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala b/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala index 6c984f1ca..2c7c428fa 100644 --- a/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala +++ b/main/src/main/scala/sbt/internal/graph/rendering/DOT.scala @@ -20,7 +20,7 @@ object DOT { labelRendering: HTMLLabelRendering ): String = { val nodes = { - for (n ← graph.nodes) yield { + for (n <- graph.nodes) yield { val style = if (n.isEvicted) EvictedStyle else "" val label = nodeFormation(n.id.organization, n.id.name, n.id.version) """ "%s"[%s style="%s"]""".format( @@ -56,7 +56,7 @@ object DOT { .filterNot(e => originWasEvicted(e) || evictionTargetEdges(e)) ++ evictedByEdges val edges = { - for (e ← filteredEdges) yield { + for (e <- filteredEdges) yield { val extra = if (graph.module(e._1).isEvicted) s""" [label="Evicted By" style="$EvictedStyle"]""" diff --git a/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala b/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala index 024d3c6bd..9f61873dc 100644 --- a/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala +++ b/main/src/main/scala/sbt/internal/graph/rendering/GraphML.scala @@ -15,7 +15,7 @@ import scala.xml.XML object GraphML { def saveAsGraphML(graph: ModuleGraph, outputFile: String): Unit = { val nodesXml = - for (n ← graph.nodes) + for (n <- graph.nodes) yield {n.id.idString} @@ -23,7 +23,7 @@ object GraphML { val edgesXml = - for (e ← graph.edges) + for (e <- graph.edges) yield val xml = From a6d03c819c6c0c0dd583e6b73f91f48a53228d96 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jan 2021 14:21:50 -0500 Subject: [PATCH 4/5] Backtick the unicode letters in method --- .../src/main/scala/sbt/std/InputWrapper.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/main-settings/src/main/scala/sbt/std/InputWrapper.scala b/main-settings/src/main/scala/sbt/std/InputWrapper.scala index 64fe5508d..f0fc8fb62 100644 --- a/main-settings/src/main/scala/sbt/std/InputWrapper.scala +++ b/main-settings/src/main/scala/sbt/std/InputWrapper.scala @@ -33,32 +33,32 @@ object InputWrapper { @compileTimeOnly( "`value` can only be called on a task within a task definition macro, such as :=, +=, ++=, or Def.task." ) - def wrapTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError + def `wrapTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError @compileTimeOnly( "`value` can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting." ) - def wrapInit_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError + def `wrapInit_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError @compileTimeOnly( "`value` can only be called on a task within a task definition macro, such as :=, +=, ++=, or Def.task." ) - def wrapInitTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError + def `wrapInitTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError @compileTimeOnly( "`value` can only be called on an input task within a task definition macro, such as := or Def.inputTask." ) - def wrapInputTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError + def `wrapInputTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError @compileTimeOnly( "`value` can only be called on an input task within a task definition macro, such as := or Def.inputTask." ) - def wrapInitInputTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError + def `wrapInitInputTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError @compileTimeOnly( "`previous` can only be called on a task within a task or input task definition macro, such as :=, +=, ++=, Def.task, or Def.inputTask." ) - def wrapPrevious_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError + def `wrapPrevious_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError private[this] def implDetailError = sys.error("This method is an implementation detail and should not be referenced.") @@ -240,13 +240,13 @@ object ParserInput { @compileTimeOnly( "`parsed` can only be used within an input task macro, such as := or Def.inputTask." ) - def parser_\u2603\u2603[T](@deprecated("unused", "") i: Any): T = + def `parser_\u2603\u2603`[T](@deprecated("unused", "") i: Any): T = sys.error("This method is an implementation detail and should not be referenced.") @compileTimeOnly( "`parsed` can only be used within an input task macro, such as := or Def.inputTask." ) - def initParser_\u2603\u2603[T](@deprecated("unused", "") i: Any): T = + def `initParser_\u2603\u2603`[T](@deprecated("unused", "") i: Any): T = sys.error("This method is an implementation detail and should not be referenced.") private[std] def wrap[T: c.WeakTypeTag]( From 2f392ac264464333b3b0cdf76c14432eb352aebd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jan 2021 15:26:26 -0500 Subject: [PATCH 5/5] don't enable SemanticDB on CI Don't enable SemanticDB on CI for now since it doesn't support 2.10. --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index bb1afaa3b..df6dfe51e 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,7 @@ ThisBuild / Test / scalafmtOnCompile := !(Global / insideCI).value ThisBuild / turbo := true ThisBuild / usePipelining := false // !(Global / insideCI).value -Global / semanticdbEnabled := true +Global / semanticdbEnabled := !(Global / insideCI).value val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys") Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty) Global / excludeLint += componentID