diff --git a/main/Project.scala b/main/Project.scala index 523aacb26..bfa164961 100755 --- a/main/Project.scala +++ b/main/Project.scala @@ -210,21 +210,23 @@ object Project extends ProjectExtra val data = scopedKeyData(structure, scope, key) map {_.description} getOrElse {"No entry for key."} val description = key.description match { case Some(desc) => "Description:\n\t" + desc + "\n"; case None => "" } - val providedBy = structure.data.definingScope(scope, key) match { + val definingScope = structure.data.definingScope(scope, key) + val providedBy = definingScope match { case Some(sc) => "Provided by:\n\t" + Scope.display(sc, key.label) + "\n" case None => "" } + val definingScoped = definingScope match { case Some(sc) => ScopedKey(sc, key); case None => scoped } val comp = Def.compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal, display) - val definedAt = comp get scoped map { c => + val definedAt = comp get definingScoped map { c => def fmt(s: Setting[_]) = s.pos match { - case pos: FilePosition => Some(pos.path + ":" + pos.startLine) - case NoPosition => None + case pos: FilePosition => (pos.path + ":" + pos.startLine) :: Nil + case NoPosition => Nil } - val posDefined = c.settings.map(fmt).flatten + val posDefined = c.settings.flatMap(fmt) if (posDefined.size > 0) { val header = if (posDefined.size == c.settings.size) "Defined at:" else "Some of the defining occurrences:" - header + (posDefined mkString ("\n\t", "\n\t", "\n")) + header + (posDefined.distinct mkString ("\n\t", "\n\t", "\n")) } else "" } getOrElse "" diff --git a/main/settings/Structure.scala b/main/settings/Structure.scala index 1f839996e..2d360cda7 100644 --- a/main/settings/Structure.scala +++ b/main/settings/Structure.scala @@ -38,11 +38,11 @@ sealed abstract class SettingKey[T] extends ScopedTaskable[T] with KeyedInitiali final def := (v: T): Setting[T] = macro std.TaskMacro.settingAssignMacroImpl[T] final def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[T] = macro std.TaskMacro.settingAppend1Impl[T,U] final def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[T] = macro std.TaskMacro.settingAppendNImpl[T,U] - final def <+= [V](value: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] = make(value, NoPosition)(a.appendValue) - final def <++= [V](values: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] = make(values, NoPosition)(a.appendValues) + final def <+= [V](v: Initialize[V])(implicit a: Append.Value[T, V]): Setting[T] = macro std.TaskMacro.settingAppend1Position[T,V] + final def <++= [V](vs: Initialize[V])(implicit a: Append.Values[T, V]): Setting[T] = macro std.TaskMacro.settingAppendNPosition[T,V] - final def append1[V](value: Initialize[V], source: SourcePosition)(implicit a: Append.Value[T, V]): Setting[T] = make(value, source)(a.appendValue) - final def appendN[V](values: Initialize[V], source: SourcePosition)(implicit a: Append.Values[T, V]): Setting[T] = make(values, source)(a.appendValues) + final def append1[V](v: Initialize[V], source: SourcePosition)(implicit a: Append.Value[T, V]): Setting[T] = make(v, source)(a.appendValue) + final def appendN[V](vs: Initialize[V], source: SourcePosition)(implicit a: Append.Values[T, V]): Setting[T] = make(vs, source)(a.appendValues) protected[this] def make[S](other: Initialize[S], source: SourcePosition)(f: (T, S) => T): Setting[T] = this.set( (this, other)(f), source) } @@ -60,8 +60,8 @@ sealed abstract class TaskKey[T] extends ScopedTaskable[T] with KeyedInitialize[ def +=[U](v: U)(implicit a: Append.Value[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskAppend1Impl[T,U] def ++=[U](vs: U)(implicit a: Append.Values[T, U]): Setting[Task[T]] = macro std.TaskMacro.taskAppendNImpl[T,U] - def <+= [V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] = make(v, NoPosition)(a.appendValue) - def <++= [V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] = make(vs, NoPosition)(a.appendValues) + def <+= [V](v: Initialize[Task[V]])(implicit a: Append.Value[T, V]): Setting[Task[T]] = macro std.TaskMacro.taskAppend1Position[T,V] + def <++= [V](vs: Initialize[Task[V]])(implicit a: Append.Values[T, V]): Setting[Task[T]] = macro std.TaskMacro.taskAppendNPosition[T,V] def append1[V](v: Initialize[Task[V]], source: SourcePosition)(implicit a: Append.Value[T, V]): Setting[Task[T]] = make(v, source)(a.appendValue) def appendN[V](vs: Initialize[Task[V]], source: SourcePosition)(implicit a: Append.Values[T, V]): Setting[Task[T]] = make(vs, source)(a.appendValues) @@ -112,10 +112,11 @@ object Scoped { def scopedKey: ScopedKey[S] - private[sbt] final def :==(value: S): Setting[S] = setting(scopedKey, Def.valueStrict(value)) - final def ~= (f: S => S): Setting[S] = Def.update(scopedKey)(f) - final def <<= (app: Initialize[S]): Setting[S] = set(app, NoPosition) + private[sbt] final def :==(app: S): Setting[S] = macro std.TaskMacro.settingAssignPure[S] + final def ~= (f: S => S): Setting[S] = macro std.TaskMacro.settingTransformPosition[S] + final def <<= (app: Initialize[S]): Setting[S] = macro std.TaskMacro.settingAssignPosition[S] final def set (app: Initialize[S], source: SourcePosition): Setting[S] = setting(scopedKey, app, source) + final def transform(f: S => S, source: SourcePosition): Setting[S] = set( scopedKey(f), source ) final def get(settings: Settings[Scope]): Option[S] = settings.get(scopedKey.scope, scopedKey.key) final def ? : Initialize[Option[S]] = Def.optional(scopedKey)(idFun) final def or[T >: S](i: Initialize[T]): Initialize[T] = (this.?, i)(_ getOrElse _ ) @@ -129,14 +130,14 @@ object Scoped sealed trait DefinableTask[S] { self: TaskKey[S] => - private[sbt] def :==(v: S): Setting[Task[S]] = ::=(constant(v)) - private[sbt] def ::=(value: Task[S]): Setting[Task[S]] = Def.setting(scopedKey, Def.valueStrict( value )) - def := (v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S] //::=(mktask(value)) - private[sbt] def :== (v: SettingKey[S]): Setting[Task[S]] = <<=( v(constant)) - def ~= (f: S => S): Setting[Task[S]] = Def.update(scopedKey)( _ map f ) + private[sbt] def :==(app: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignPositionPure[S] + private[sbt] def ::=(app: Task[S]): Setting[Task[S]] = macro std.TaskMacro.taskAssignPositionT[S] + def := (v: S): Setting[Task[S]] = macro std.TaskMacro.taskAssignMacroImpl[S] + def ~= (f: S => S): Setting[Task[S]] = macro std.TaskMacro.taskTransformPosition[S] - def <<= (app: Initialize[Task[S]]): Setting[Task[S]] = set(app, NoPosition) + def <<= (app: Initialize[Task[S]]): Setting[Task[S]] = macro std.TaskMacro.itaskAssignPosition[S] def set(app: Initialize[Task[S]], source: SourcePosition): Setting[Task[S]] = Def.setting(scopedKey, app, source) + def transform(f: S => S, source: SourcePosition): Setting[Task[S]] = set( scopedKey(_ map f), source) def task: SettingKey[Task[S]] = scopedSetting(scope, key) def get(settings: Settings[Scope]): Option[Task[S]] = settings.get(scope, key) diff --git a/main/settings/TaskMacro.scala b/main/settings/TaskMacro.scala index dd7d3a5f3..2a91c3c41 100644 --- a/main/settings/TaskMacro.scala +++ b/main/settings/TaskMacro.scala @@ -67,6 +67,7 @@ object TaskMacro final val AssignInitName = "set" final val Append1InitName = "append1" final val AppendNInitName = "appendN" + final val TransformInitName = "transform" final val InputTaskCreateName = "create" def taskMacroImpl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[Initialize[Task[T]]] = @@ -89,6 +90,38 @@ object TaskMacro val assign = transformMacroImpl(c)( init.tree )( AssignInitName ) c.Expr[Setting[Task[T]]]( assign ) } + + /* Implementations of <<= macro variations for tasks and settings. These just get the source position of the call site.*/ + + def itaskAssignPosition[T: c.WeakTypeTag](c: Context)(app: c.Expr[Initialize[Task[T]]]): c.Expr[Setting[Task[T]]] = + settingAssignPosition(c)(app) + def taskAssignPositionT[T: c.WeakTypeTag](c: Context)(app: c.Expr[Task[T]]): c.Expr[Setting[Task[T]]] = + itaskAssignPosition(c)( c.universe.reify { Def.valueStrict(app.splice) }) + def taskAssignPositionPure[T: c.WeakTypeTag](c: Context)(app: c.Expr[T]): c.Expr[Setting[Task[T]]] = + taskAssignPositionT(c)( c.universe.reify { TaskExtra.constant(app.splice) }) + + def taskTransformPosition[S: c.WeakTypeTag](c: Context)(f: c.Expr[S => S]): c.Expr[Setting[Task[S]]] = + c.Expr[Setting[Task[S]]]( transformMacroImpl(c)( f.tree )( TransformInitName ) ) + def settingTransformPosition[S: c.WeakTypeTag](c: Context)(f: c.Expr[S => S]): c.Expr[Setting[S]] = + c.Expr[Setting[S]]( transformMacroImpl(c)( f.tree )( TransformInitName ) ) + + def taskAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(vs: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[Task[S]]] = + c.Expr[Setting[Task[S]]]( appendMacroImpl(c)( vs.tree, a.tree )( AppendNInitName ) ) + + def settingAppendNPosition[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(vs: c.Expr[Initialize[V]])(a: c.Expr[Append.Values[S, V]]): c.Expr[Setting[S]] = + c.Expr[Setting[S]]( appendMacroImpl(c)( vs.tree, a.tree )( AppendNInitName ) ) + + def taskAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(v: c.Expr[Initialize[Task[V]]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[Task[S]]] = + c.Expr[Setting[Task[S]]]( appendMacroImpl(c)( v.tree, a.tree )( Append1InitName ) ) + + def settingAppend1Position[S: c.WeakTypeTag, V: c.WeakTypeTag](c: Context)(v: c.Expr[Initialize[V]])(a: c.Expr[Append.Value[S, V]]): c.Expr[Setting[S]] = + c.Expr[Setting[S]]( appendMacroImpl(c)( v.tree, a.tree )( Append1InitName ) ) + + def settingAssignPure[T: c.WeakTypeTag](c: Context)(app: c.Expr[T]): c.Expr[Setting[T]] = + settingAssignPosition(c)( c.universe.reify { Def.valueStrict(app.splice) }) + def settingAssignPosition[T: c.WeakTypeTag](c: Context)(app: c.Expr[Initialize[T]]): c.Expr[Setting[T]] = + c.Expr[Setting[T]]( transformMacroImpl(c)( app.tree )( AssignInitName ) ) + /** Implementation of := macro for tasks. */ def inputTaskAssignMacroImpl[T: c.WeakTypeTag](c: Context)(v: c.Expr[T]): c.Expr[Setting[InputTask[T]]] = {