From 50696398a100ba878b25e337af22fc3b059790de Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 17 Jul 2014 23:32:29 -0400 Subject: [PATCH] Minor cleanups and fix Eval tests to work correctly. --- .../src/main/scala/sbt/compiler/Eval.scala | 16 ++++------------ .../main/scala/sbt/EvaluateConfigurations.scala | 4 +++- main/src/main/scala/sbt/Main.scala | 6 +++--- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/main/actions/src/main/scala/sbt/compiler/Eval.scala b/main/actions/src/main/scala/sbt/compiler/Eval.scala index 1267a0038..e533ac5a2 100644 --- a/main/actions/src/main/scala/sbt/compiler/Eval.scala +++ b/main/actions/src/main/scala/sbt/compiler/Eval.scala @@ -88,7 +88,7 @@ final class Eval(optionsNoncp: Seq[String], classpath: Seq[File], mkReporter: Se val value = (cl: ClassLoader) => getValue[Any](i.enclosingModule, i.loader(cl)) new EvalResult(i.extra, value, i.generated, i.enclosingModule) } - def evalDefinitions(definitions: Seq[(String, scala.Range)], imports: EvalImports, srcName: String): EvalDefinitions = + def evalDefinitions(definitions: Seq[(String, scala.Range)], imports: EvalImports, srcName: String, valTypes: Seq[String]): EvalDefinitions = { require(definitions.nonEmpty, "Definitions to evaluate cannot be empty.") val ev = new EvalType[Seq[String]] { @@ -101,7 +101,7 @@ final class Eval(optionsNoncp: Seq[String], classpath: Seq[File], mkReporter: Se syntheticModule(fullParser, importTrees, trees.toList, moduleName) } def extra(run: Run, unit: CompilationUnit) = { - atPhase(run.typerPhase.next) { (new ValExtractor()).getVals(unit.body) } + atPhase(run.typerPhase.next) { (new ValExtractor(valTypes.toSet)).getVals(unit.body) } } def read(file: File) = IO.readLines(file) def write(value: Seq[String], file: File) = IO.writeLines(file, value) @@ -214,23 +214,15 @@ final class Eval(optionsNoncp: Seq[String], classpath: Seq[File], mkReporter: Se } } /** Tree traverser that obtains the names of vals in a top-level module whose type is a subtype of one of `types`.*/ - private[this] final class ValExtractor() extends Traverser { + private[this] final class ValExtractor(tpes: Set[String]) extends Traverser { private[this] var vals = List[String]() def getVals(t: Tree): List[String] = { vals = Nil; traverse(t); vals } def isAcceptableType(tpe: Type): Boolean = { tpe.baseClasses.exists { sym => - sym.fullName startsWith "sbt." + tpes.contains(sym.fullName) } } override def traverse(tree: Tree): Unit = tree match { - // TODO - We really need to clean this up so that we can filter by type and - // track which vals are projects vs. other vals. It's important so that we avoid - // instantiating values more than absolutely necessary on different classloaders. - // However, it's not terrible right now if we do, as most likely the values - // are used to instantiate each other i.e. a valuing in a build.sbt file is most likely - // used in something which is contained in a `Project` vaue, therefore it will be - // instantiated anyway. - // For now, we just check that the type case ValDef(_, n, actualTpe, _) if isTopLevelModule(tree.symbol.owner) && isAcceptableType(actualTpe.tpe) => vals ::= nme.localToGetter(n).encoded case _ => super.traverse(tree) diff --git a/main/src/main/scala/sbt/EvaluateConfigurations.scala b/main/src/main/scala/sbt/EvaluateConfigurations.scala index f586a76eb..a035fbd50 100644 --- a/main/src/main/scala/sbt/EvaluateConfigurations.scala +++ b/main/src/main/scala/sbt/EvaluateConfigurations.scala @@ -235,10 +235,12 @@ object EvaluateConfigurations { val trimmed = line.trim DefinitionKeywords.exists(trimmed startsWith _) } + private[this] def extractedValTypes: Seq[String] = + Seq(classOf[Project], classOf[InputKey[_]], classOf[TaskKey[_]], classOf[SettingKey[_]]).map(_.getName) private[this] def evaluateDefinitions(eval: Eval, name: String, imports: Seq[(String, Int)], definitions: Seq[(String, LineRange)]): compiler.EvalDefinitions = { val convertedRanges = definitions.map { case (s, r) => (s, r.start to r.end) } - eval.evalDefinitions(convertedRanges, new EvalImports(imports, name), name) + eval.evalDefinitions(convertedRanges, new EvalImports(imports, name), name, extractedValTypes) } } object Index { diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 67ee0d41c..d7d364472 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -235,9 +235,9 @@ object BuiltinCommands { val extracted = Project extract s import extracted._ val dslVals = extracted.currentUnit.unit.definitions.dslDefinitions - // TODO - This is horribly inefficient. We should try to only attach the - // classloader + imports NEEDED to compile the set command. - System.err.println(s"DSL imports: ${dslVals.imports mkString "\n"}") + // TODO - This is possibly inefficient (or stupid). We should try to only attach the + // classloader + imports NEEDED to compile the set command, rather than + // just ALL of them. val ims = (imports(extracted) ++ dslVals.imports.map(i => (i, -1))) val cl = dslVals.classloader(currentLoader) val settings = EvaluateConfigurations.evaluateSetting(