From 2c654b2d903c92fcf7dd746cd1ff15ec7b6aa81f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 20 Mar 2014 21:15:40 -0400 Subject: [PATCH 1/3] Unifies AutoPlugin and AutoImport. Fixes #1188 * AutoImport trait is subsumed by def autoImport method under AutoPlugin class. * When def autoImport is overridden by a lazy val or a val, *.sbt automatically imports autoImport._. --- main/src/main/scala/sbt/BuildStructure.scala | 14 ++++++++++---- main/src/main/scala/sbt/Keys.scala | 2 +- main/src/main/scala/sbt/Main.scala | 2 +- main/src/main/scala/sbt/PluginDiscovery.scala | 16 ++++++++-------- main/src/main/scala/sbt/Plugins.scala | 19 ++++++++++++++++--- main/src/main/scala/sbt/PluginsDebug.scala | 2 +- .../sbt-test/project/auto-plugins/build.sbt | 2 ++ .../project/auto-plugins/project/Q.scala | 11 +++++++++-- .../binary-plugin/changes/define/A.scala | 14 ++++++++++---- 9 files changed, 58 insertions(+), 24 deletions(-) diff --git a/main/src/main/scala/sbt/BuildStructure.scala b/main/src/main/scala/sbt/BuildStructure.scala index 615a80771..dcc0e0b58 100644 --- a/main/src/main/scala/sbt/BuildStructure.scala +++ b/main/src/main/scala/sbt/BuildStructure.scala @@ -89,16 +89,22 @@ final class DetectedModules[T](val modules: Seq[(String, T)]) def values: Seq[T] = modules.map(_._2) } +/** Auto-detected auto plugin. */ +case class DetectedAutoPlugin(val name: String, val value: AutoPlugin, val hasStableAutoImport: Boolean) + /** Auto-discovered modules for the build definition project. These include modules defined in build definition sources * as well as modules in binary dependencies. * * @param builds The [[Build]]s detected in the build definition. This does not include the default [[Build]] that sbt creates if none is defined. */ -final class DetectedPlugins(val plugins: DetectedModules[Plugin], val autoImports: DetectedModules[AutoImport], val autoPlugins: DetectedModules[AutoPlugin], val builds: DetectedModules[Build]) +final class DetectedPlugins(val plugins: DetectedModules[Plugin], val autoPlugins: Seq[DetectedAutoPlugin], val builds: DetectedModules[Build]) { /** Sequence of import expressions for the build definition. This includes the names of the [[Plugin]], [[Build]], and [[AutoImport]] modules, but not the [[AutoPlugin]] modules. */ - lazy val imports: Seq[String] = BuildUtil.getImports(plugins.names ++ builds.names ++ autoImports.names) - + lazy val imports: Seq[String] = BuildUtil.getImports(plugins.names ++ builds.names ++ + (autoPlugins flatMap { case DetectedAutoPlugin(name, ap, hasAutoImport) => + if (hasAutoImport) Some(name + ".autoImport") + else None + })) /** A function to select the right [[AutoPlugin]]s from [[autoPlugins]] for a [[Project]]. */ lazy val deducePlugins: (Plugins, Logger) => Seq[AutoPlugin] = Plugins.deducer(autoPlugins.values.toList) } @@ -115,7 +121,7 @@ final class LoadedPlugins(val base: File, val pluginData: PluginData, val loader @deprecated("Use the primary constructor.", "0.13.2") def this(base: File, pluginData: PluginData, loader: ClassLoader, plugins: Seq[Plugin], pluginNames: Seq[String]) = this(base, pluginData, loader, - new DetectedPlugins(new DetectedModules(pluginNames zip plugins), new DetectedModules(Nil), new DetectedModules(Nil), new DetectedModules(Nil)) + new DetectedPlugins(new DetectedModules(pluginNames zip plugins), Nil, new DetectedModules(Nil)) ) @deprecated("Use detected.plugins.values.", "0.13.2") diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index ceb7813ed..53ccdfc97 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -131,7 +131,7 @@ object Keys val crossVersion = SettingKey[CrossVersion]("cross-version", "Configures handling of the Scala version when cross-building.", CSetting) val classpathOptions = SettingKey[ClasspathOptions]("classpath-options", "Configures handling of Scala classpaths.", DSetting) val definedSbtPlugins = TaskKey[Set[String]]("defined-sbt-plugins", "The set of names of Plugin implementations defined by this project.", CTask) - val discoveredSbtPlugins = TaskKey[PluginDiscovery.DiscoveredNames]("discovered-sbt-plugins", "The names of sbt plugin-related modules (modules that extend Build, Plugin, AutoImport, AutoPlugin) defined by this project.", CTask) + val discoveredSbtPlugins = TaskKey[PluginDiscovery.DiscoveredNames]("discovered-sbt-plugins", "The names of sbt plugin-related modules (modules that extend Build, Plugin, AutoPlugin) defined by this project.", CTask) val sbtPlugin = SettingKey[Boolean]("sbt-plugin", "If true, enables adding sbt as a dependency and auto-generation of the plugin descriptor file.", BMinusSetting) val printWarnings = TaskKey[Unit]("print-warnings", "Shows warnings from compilation, including ones that weren't printed initially.", BPlusTask) val fileInputOptions = SettingKey[Seq[String]]("file-input-options", "Options that take file input, which may invalidate the cache.", CSetting) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index c44bd5a1b..7cd85867d 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -125,7 +125,7 @@ object BuiltinCommands def aboutPlugins(e: Extracted): String = { - def list(b: BuildUnit) = b.plugins.detected.autoPlugins.values.map(_.label) ++ b.plugins.detected.plugins.names + def list(b: BuildUnit) = b.plugins.detected.autoPlugins.map(_.value.label) ++ b.plugins.detected.plugins.names val allPluginNames = e.structure.units.values.flatMap(u => list(u.unit)).toSeq.distinct if(allPluginNames.isEmpty) "" else allPluginNames.mkString("Available Plugins: ", ", ", "") } diff --git a/main/src/main/scala/sbt/PluginDiscovery.scala b/main/src/main/scala/sbt/PluginDiscovery.scala index ae945f78a..b28fed112 100644 --- a/main/src/main/scala/sbt/PluginDiscovery.scala +++ b/main/src/main/scala/sbt/PluginDiscovery.scala @@ -15,12 +15,11 @@ object PluginDiscovery final val AutoPlugins = "sbt/sbt.autoplugins" final val Plugins = "sbt/sbt.plugins" final val Builds = "sbt/sbt.builds" - final val AutoImports = "sbt/sbt.autoimports" } - /** Names of top-level modules that subclass sbt plugin-related classes: [[Plugin]], [[AutoImport]], [[AutoPlugin]], and [[Build]]. */ - final class DiscoveredNames(val plugins: Seq[String], val autoImports: Seq[String], val autoPlugins: Seq[String], val builds: Seq[String]) + /** Names of top-level modules that subclass sbt plugin-related classes: [[Plugin]], [[AutoPlugin]], and [[Build]]. */ + final class DiscoveredNames(val plugins: Seq[String], val autoPlugins: Seq[String], val builds: Seq[String]) - def emptyDiscoveredNames: DiscoveredNames = new DiscoveredNames(Nil, Nil, Nil, Nil) + def emptyDiscoveredNames: DiscoveredNames = new DiscoveredNames(Nil, Nil, Nil) /** Discovers and loads the sbt-plugin-related top-level modules from the classpath and source analysis in `data` and using the provided class `loader`. */ def discoverAll(data: PluginData, loader: ClassLoader): DetectedPlugins = @@ -35,8 +34,10 @@ object PluginDiscovery "sbt.plugins.GlobalModule" -> sbt.plugins.GlobalModule ) val detectedAutoPugins = discover[AutoPlugin](AutoPlugins) - val allAutoPlugins = new DetectedModules(defaultAutoPlugins ++ detectedAutoPugins.modules) - new DetectedPlugins(discover[Plugin](Plugins), discover[AutoImport](AutoImports), allAutoPlugins, discover[Build](Builds)) + val allAutoPlugins = (defaultAutoPlugins ++ detectedAutoPugins.modules) map { case (name, value) => + DetectedAutoPlugin(name, value, sbt.Plugins.hasStableAutoImport(value, loader)) + } + new DetectedPlugins(discover[Plugin](Plugins), allAutoPlugins, discover[Build](Builds)) } /** Discovers the sbt-plugin-related top-level modules from the provided source `analysis`. */ @@ -44,7 +45,7 @@ object PluginDiscovery { def discover[T](implicit mf: reflect.ClassManifest[T]): Seq[String] = sourceModuleNames(analysis, mf.erasure.getName) - new DiscoveredNames(discover[Plugin], discover[AutoImport], discover[AutoPlugin], discover[Build]) + new DiscoveredNames(discover[Plugin], discover[AutoPlugin], discover[Build]) } // TODO: for 0.14.0, consider consolidating into a single file, which would make the classpath search 4x faster @@ -56,7 +57,6 @@ object PluginDiscovery writeDescriptor(names.plugins, dir, Plugins) :: writeDescriptor(names.autoPlugins, dir, AutoPlugins) :: writeDescriptor(names.builds, dir, Builds) :: - writeDescriptor(names.autoImports, dir, AutoImports) :: Nil files.flatMap(_.toList) } diff --git a/main/src/main/scala/sbt/Plugins.scala b/main/src/main/scala/sbt/Plugins.scala index 925fb6916..3da012b1e 100644 --- a/main/src/main/scala/sbt/Plugins.scala +++ b/main/src/main/scala/sbt/Plugins.scala @@ -11,9 +11,6 @@ TODO: import Plugins._ import annotation.tailrec -/** Marks a top-level object so that sbt will wildcard import it for .sbt files, `consoleProject`, and `set`. */ -trait AutoImport - /** An AutoPlugin defines a group of settings and the conditions where the settings are automatically added to a build (called "activation"). The `requires` and `trigger` methods together define the conditions, and a method like `projectSettings` defines the settings to add. @@ -66,6 +63,10 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions override def toString: String = label + /** When this method is overridden with a val or a lazy val, `autoImport._` is automatically + * imported to *.sbt scripts. */ + def autoImport: Any = () + /** The [[Configuration]]s to add to each project that activates this AutoPlugin.*/ def projectConfigurations: Seq[Configuration] = Nil @@ -307,4 +308,16 @@ ${listConflicts(conflicting)}""") case Exclude(a) => !model(a) case ap: AutoPlugin => model(ap) } + + private[sbt] def hasStableAutoImport(ap: AutoPlugin, loader: ClassLoader): Boolean = { + import reflect.runtime.{universe => ru} + import util.control.Exception.catching + val m = ru.runtimeMirror(loader) + val im = m.reflect(ap) + val fmOpt = catching(classOf[ScalaReflectionException]) opt { + val autoImportSym = im.symbol.asType.toType.declaration(ru.newTermName("autoImport")).asTerm + im.reflectField(autoImportSym) + } + fmOpt.isDefined + } } \ No newline at end of file diff --git a/main/src/main/scala/sbt/PluginsDebug.scala b/main/src/main/scala/sbt/PluginsDebug.scala index 7d9b2670a..bace7b52b 100644 --- a/main/src/main/scala/sbt/PluginsDebug.scala +++ b/main/src/main/scala/sbt/PluginsDebug.scala @@ -108,7 +108,7 @@ private[sbt] object PluginsDebug structure.units.values.toList.flatMap(availableAutoPlugins).map(plugin => (plugin.label, plugin)).toMap } private[this] def availableAutoPlugins(build: LoadedBuildUnit): Seq[AutoPlugin] = - build.unit.plugins.detected.autoPlugins.values + build.unit.plugins.detected.autoPlugins map {_.value} def help(plugin: AutoPlugin, s: State): String = { diff --git a/sbt/src/sbt-test/project/auto-plugins/build.sbt b/sbt/src/sbt-test/project/auto-plugins/build.sbt index 7039ed235..dbb06d44c 100644 --- a/sbt/src/sbt-test/project/auto-plugins/build.sbt +++ b/sbt/src/sbt-test/project/auto-plugins/build.sbt @@ -1,3 +1,5 @@ +import sbttest.{Q} + // disablePlugins(Q) will prevent R from being auto-added lazy val projA = project.addPlugins(A, B).disablePlugins(Q) diff --git a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala index 74d8b5f6d..bb190091e 100644 --- a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala +++ b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala @@ -1,8 +1,10 @@ +package sbttest // you need package http://stackoverflow.com/questions/9822008/ + import sbt._ import sbt.Keys.{name, resolvedScoped} import java.util.concurrent.atomic.{AtomicInteger => AInt} -object AI extends AutoImport +object Imports { trait EmptyAutoPlugin extends AutoPlugin { def requires = empty @@ -21,7 +23,12 @@ object AI extends AutoImport lazy val check = settingKey[Unit]("Verifies settings are as they should be.") } - import AI._ +object X extends AutoPlugin { + override lazy val autoImport = Imports + def select = Plugins.empty +} + + import Imports._ object D extends AutoPlugin { def requires: Plugins = E diff --git a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala index 99cd6d527..88065f085 100644 --- a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala +++ b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala @@ -1,16 +1,22 @@ +package sbttest // you need package http://stackoverflow.com/questions/9822008/ + import sbt._ import Keys._ - -object C extends AutoImport { +object Imports { object bN extends AutoPlugin { def requires = empty def trigger = allRequirements } - lazy val check = taskKey[Unit]("Checks that the AutoPlugin and Build are automatically added.") + lazy val check = taskKey[Unit]("Checks that the AutoPlugin and Build are automatically added.") } - import C._ +object C extends AutoPlugin { + override lazy val autoImport = Imports + def select = Plugins.empty +} + + import Imports._ object A extends AutoPlugin { def requires = bN From cc80d216ab42584d1115582252e4c6b73a45d1f9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Mar 2014 19:25:17 -0400 Subject: [PATCH 2/3] Adjusting to 0.13 changes --- main/src/main/scala/sbt/BuildStructure.scala | 2 +- sbt/src/sbt-test/project/auto-plugins/build.sbt | 2 +- sbt/src/sbt-test/project/auto-plugins/project/Q.scala | 3 ++- sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala | 3 ++- src/main/conscript/sbt/launchconfig | 2 +- src/main/conscript/scalas/launchconfig | 2 +- src/main/conscript/screpl/launchconfig | 2 +- 7 files changed, 9 insertions(+), 7 deletions(-) diff --git a/main/src/main/scala/sbt/BuildStructure.scala b/main/src/main/scala/sbt/BuildStructure.scala index dcc0e0b58..f5c3200c7 100644 --- a/main/src/main/scala/sbt/BuildStructure.scala +++ b/main/src/main/scala/sbt/BuildStructure.scala @@ -106,7 +106,7 @@ final class DetectedPlugins(val plugins: DetectedModules[Plugin], val autoPlugin else None })) /** A function to select the right [[AutoPlugin]]s from [[autoPlugins]] for a [[Project]]. */ - lazy val deducePlugins: (Plugins, Logger) => Seq[AutoPlugin] = Plugins.deducer(autoPlugins.values.toList) + lazy val deducePlugins: (Plugins, Logger) => Seq[AutoPlugin] = Plugins.deducer(autoPlugins.toList map {_.value}) } /** The built and loaded build definition project. diff --git a/sbt/src/sbt-test/project/auto-plugins/build.sbt b/sbt/src/sbt-test/project/auto-plugins/build.sbt index dbb06d44c..de4f386e3 100644 --- a/sbt/src/sbt-test/project/auto-plugins/build.sbt +++ b/sbt/src/sbt-test/project/auto-plugins/build.sbt @@ -1,4 +1,4 @@ -import sbttest.{Q} +import sbttest.{Q, S} // disablePlugins(Q) will prevent R from being auto-added lazy val projA = project.addPlugins(A, B).disablePlugins(Q) diff --git a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala index bb190091e..044d7ab4d 100644 --- a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala +++ b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala @@ -25,7 +25,8 @@ object Imports object X extends AutoPlugin { override lazy val autoImport = Imports - def select = Plugins.empty + def requires = Plugins.empty + def trigger = noTrigger } import Imports._ diff --git a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala index 88065f085..b33a8e8d2 100644 --- a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala +++ b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala @@ -13,7 +13,8 @@ object Imports { object C extends AutoPlugin { override lazy val autoImport = Imports - def select = Plugins.empty + def requires = empty + def trigger = noTrigger } import Imports._ diff --git a/src/main/conscript/sbt/launchconfig b/src/main/conscript/sbt/launchconfig index 788738650..754d63c95 100644 --- a/src/main/conscript/sbt/launchconfig +++ b/src/main/conscript/sbt/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[0.13.2-SNAPSHOT]} + version: ${sbt.version-read(sbt.version)[0.13.3-SNAPSHOT]} class: sbt.xMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/scalas/launchconfig b/src/main/conscript/scalas/launchconfig index 75c4138ed..5710eac15 100644 --- a/src/main/conscript/scalas/launchconfig +++ b/src/main/conscript/scalas/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[0.13.2-SNAPSHOT]} + version: ${sbt.version-read(sbt.version)[0.13.3-SNAPSHOT]} class: sbt.ScriptMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/screpl/launchconfig b/src/main/conscript/screpl/launchconfig index 18fbfa911..c0e1d473a 100644 --- a/src/main/conscript/screpl/launchconfig +++ b/src/main/conscript/screpl/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[0.13.2-SNAPSHOT]} + version: ${sbt.version-read(sbt.version)[0.13.3-SNAPSHOT]} class: sbt.ConsoleMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} From ff77d0b0f2794b4b1f4e095a5f6b6037b2aedcca Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Mar 2014 23:04:22 -0400 Subject: [PATCH 3/3] Remove def autoImport: Any from AutoPlugin. --- main/src/main/scala/sbt/BuildStructure.scala | 3 ++- main/src/main/scala/sbt/PluginDiscovery.scala | 2 +- main/src/main/scala/sbt/Plugins.scala | 26 +++++++++++-------- .../project/auto-plugins/project/Q.scala | 2 +- .../binary-plugin/changes/define/A.scala | 18 ++++++------- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/main/src/main/scala/sbt/BuildStructure.scala b/main/src/main/scala/sbt/BuildStructure.scala index f5c3200c7..da24a2444 100644 --- a/main/src/main/scala/sbt/BuildStructure.scala +++ b/main/src/main/scala/sbt/BuildStructure.scala @@ -90,7 +90,7 @@ final class DetectedModules[T](val modules: Seq[(String, T)]) } /** Auto-detected auto plugin. */ -case class DetectedAutoPlugin(val name: String, val value: AutoPlugin, val hasStableAutoImport: Boolean) +case class DetectedAutoPlugin(val name: String, val value: AutoPlugin, val hasAutoImport: Boolean) /** Auto-discovered modules for the build definition project. These include modules defined in build definition sources * as well as modules in binary dependencies. @@ -105,6 +105,7 @@ final class DetectedPlugins(val plugins: DetectedModules[Plugin], val autoPlugin if (hasAutoImport) Some(name + ".autoImport") else None })) + /** A function to select the right [[AutoPlugin]]s from [[autoPlugins]] for a [[Project]]. */ lazy val deducePlugins: (Plugins, Logger) => Seq[AutoPlugin] = Plugins.deducer(autoPlugins.toList map {_.value}) } diff --git a/main/src/main/scala/sbt/PluginDiscovery.scala b/main/src/main/scala/sbt/PluginDiscovery.scala index b28fed112..54939d6b9 100644 --- a/main/src/main/scala/sbt/PluginDiscovery.scala +++ b/main/src/main/scala/sbt/PluginDiscovery.scala @@ -35,7 +35,7 @@ object PluginDiscovery ) val detectedAutoPugins = discover[AutoPlugin](AutoPlugins) val allAutoPlugins = (defaultAutoPlugins ++ detectedAutoPugins.modules) map { case (name, value) => - DetectedAutoPlugin(name, value, sbt.Plugins.hasStableAutoImport(value, loader)) + DetectedAutoPlugin(name, value, sbt.Plugins.hasAutoImportGetter(value, loader)) } new DetectedPlugins(discover[Plugin](Plugins), allAutoPlugins, discover[Build](Builds)) } diff --git a/main/src/main/scala/sbt/Plugins.scala b/main/src/main/scala/sbt/Plugins.scala index 3da012b1e..9451940c3 100644 --- a/main/src/main/scala/sbt/Plugins.scala +++ b/main/src/main/scala/sbt/Plugins.scala @@ -19,14 +19,19 @@ Steps for plugin authors: 1. Determine if the AutoPlugin should automatically be activated when all requirements are met, or should be opt-in. 2. Determine the [[AutoPlugins]]s that, when present (or absent), act as the requirements for the AutoPlugin. 3. Determine the settings/configurations to that the AutoPlugin injects when activated. +4. Determine the keys and other names to be automatically imported to *.sbt scripts. For example, the following will automatically add the settings in `projectSettings` to a project that has both the `Web` and `Javascript` plugins enabled. - object MyPlugin extends AutoPlugin { + object Plugin extends sbt.AutoPlugin { def requires = Web && Javascript def trigger = allRequirements override def projectSettings = Seq(...) + + object autoImport { + lazy val obfuscate = taskKey[Seq[File]]("Obfuscates the source.") + } } Steps for users: @@ -43,6 +48,7 @@ will activate `MyPlugin` defined above and have its settings automatically added .addPlugins( Web && Javascript ).disablePlugins(MyPlugin) then the `MyPlugin` settings (and anything that activates only when `MyPlugin` is activated) will not be added. + */ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions { @@ -63,10 +69,6 @@ abstract class AutoPlugin extends Plugins.Basic with PluginsFunctions override def toString: String = label - /** When this method is overridden with a val or a lazy val, `autoImport._` is automatically - * imported to *.sbt scripts. */ - def autoImport: Any = () - /** The [[Configuration]]s to add to each project that activates this AutoPlugin.*/ def projectConfigurations: Seq[Configuration] = Nil @@ -309,15 +311,17 @@ ${listConflicts(conflicting)}""") case ap: AutoPlugin => model(ap) } - private[sbt] def hasStableAutoImport(ap: AutoPlugin, loader: ClassLoader): Boolean = { + private[sbt] def hasAutoImportGetter(ap: AutoPlugin, loader: ClassLoader): Boolean = { import reflect.runtime.{universe => ru} import util.control.Exception.catching val m = ru.runtimeMirror(loader) val im = m.reflect(ap) - val fmOpt = catching(classOf[ScalaReflectionException]) opt { - val autoImportSym = im.symbol.asType.toType.declaration(ru.newTermName("autoImport")).asTerm - im.reflectField(autoImportSym) + val hasGetterOpt = catching(classOf[ScalaReflectionException]) opt { + im.symbol.asType.toType.declaration(ru.newTermName("autoImport")) match { + case ru.NoSymbol => false + case sym => sym.asTerm.isGetter + } } - fmOpt.isDefined + hasGetterOpt getOrElse false } -} \ No newline at end of file +} diff --git a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala index 044d7ab4d..5eb6f792c 100644 --- a/sbt/src/sbt-test/project/auto-plugins/project/Q.scala +++ b/sbt/src/sbt-test/project/auto-plugins/project/Q.scala @@ -24,7 +24,7 @@ object Imports } object X extends AutoPlugin { - override lazy val autoImport = Imports + val autoImport = Imports def requires = Plugins.empty def trigger = noTrigger } diff --git a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala index b33a8e8d2..7906da1f2 100644 --- a/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala +++ b/sbt/src/sbt-test/project/binary-plugin/changes/define/A.scala @@ -3,21 +3,19 @@ package sbttest // you need package http://stackoverflow.com/questions/9822008/ import sbt._ import Keys._ -object Imports { - object bN extends AutoPlugin { - def requires = empty - def trigger = allRequirements - } - lazy val check = taskKey[Unit]("Checks that the AutoPlugin and Build are automatically added.") -} - object C extends AutoPlugin { - override lazy val autoImport = Imports + object autoImport { + object bN extends AutoPlugin { + def requires = empty + def trigger = allRequirements + } + lazy val check = taskKey[Unit]("Checks that the AutoPlugin and Build are automatically added.") + } def requires = empty def trigger = noTrigger } - import Imports._ + import C.autoImport._ object A extends AutoPlugin { def requires = bN