@@ -228,6 +228,60 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit
228
228
}
229
229
}
230
230
231
+ def loadAndSetValue (objectName : String , value : AnyRef ) = {
232
+ /** This terrible string is the wrapped class's full name inside the
233
+ * classloader:
234
+ * lineX$object$$iw$$iw$list$object$
235
+ */
236
+ val objName : String = List (
237
+ currentLineName + INTERPRETER_WRAPPER_SUFFIX ,
238
+ INTERPRETER_IMPORT_WRAPPER ,
239
+ INTERPRETER_IMPORT_WRAPPER ,
240
+ objectName
241
+ ).mkString(" $" )
242
+
243
+ val resObj : Class [_] = Class .forName(objName, true , classLoader)
244
+ val setMethod = resObj.getDeclaredMethods.find(_.getName == " set" )
245
+
246
+ setMethod.fold(false ) { method =>
247
+ method.invoke(resObj, value) == null
248
+ }
249
+ }
250
+
251
+ /** This bind is implemented by creating an object with a set method and a
252
+ * field `value`. The value is then set via Java reflection.
253
+ *
254
+ * Example: We want to bind a value `List(1,2,3)` to identifier `list` from
255
+ * SBT. The bind method accomplishes this by creating the following:
256
+ * {{{
257
+ * object ContainerObjectWithUniqueID {
258
+ * var value: List[Int] = _
259
+ * def set(x: Any) = value = x.asInstanceOf[List[Int]]
260
+ * }
261
+ * val list = ContainerObjectWithUniqueID.value
262
+ * }}}
263
+ *
264
+ * Between the object being created and the value being assigned, the value
265
+ * inside the object is set via reflection.
266
+ */
267
+ override def bind (id : String , boundType : String , value : AnyRef )(implicit ctx : Context ): Interpreter .Result =
268
+ interpret(
269
+ """
270
+ |object %s {
271
+ | var value: %s = _
272
+ | def set(x: Any) = value = x.asInstanceOf[%s]
273
+ |}
274
+ """ .stripMargin.format(id + INTERPRETER_WRAPPER_SUFFIX , boundType, boundType)
275
+ ) match {
276
+ case Interpreter .Success | Interpreter .Incomplete =>
277
+ loadAndSetValue(id + INTERPRETER_WRAPPER_SUFFIX , value.asInstanceOf [AnyRef ])
278
+ val line = " val %s = %s.value" .format(id, id + INTERPRETER_WRAPPER_SUFFIX )
279
+ interpret(line)
280
+ case Interpreter .Error =>
281
+ out.println(" Set failed in bind(%s, %s, %s)" .format(id, boundType, value))
282
+ Interpreter .Error
283
+ }
284
+
231
285
/** Trait collecting info about one of the statements of an interpreter request */
232
286
private trait StatementInfo {
233
287
/** The statement */
@@ -738,6 +792,10 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit
738
792
INTERPRETER_LINE_PREFIX + num
739
793
}
740
794
795
+ /** get the current line name */
796
+ private def currentLineName =
797
+ INTERPRETER_LINE_PREFIX + (nextLineNo - 1 )
798
+
741
799
/** next result variable number to use */
742
800
private var nextVarNameNo = 0
743
801
0 commit comments