blob: 5b8e4c3d920d175d98905c61733843045481c58b (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
/* NSC -- new Scala compiler
* Copyright 2005-2012 LAMP/EPFL
* @author Paul Phillips
*/
package scala.tools.nsc
package interpreter
import language.implicitConversions
import scala.reflect.base.{Universe => BaseUniverse}
import scala.reflect.runtime.{universe => ru}
/** A class which the repl utilizes to expose predefined objects.
* The base implementation is empty; the standard repl implementation
* is StdReplVals.
*/
abstract class ReplVals { }
class StdReplVals(final val r: ILoop) extends ReplVals {
final lazy val repl = r
final lazy val intp = r.intp
final lazy val power = r.power
final lazy val reader = r.in
final lazy val vals = this
final lazy val global: intp.global.type = intp.global
final lazy val isettings = intp.isettings
final lazy val completion = reader.completion
final lazy val history = reader.history
final lazy val phased = power.phased
final lazy val analyzer = global.analyzer
object treedsl extends { val global: intp.global.type = intp.global } with ast.TreeDSL { }
final lazy val typer = analyzer.newTyper(
analyzer.rootContext(
power.unit("").asInstanceOf[analyzer.global.CompilationUnit]
)
)
def lastRequest = intp.lastRequest
class ReplImplicits extends power.Implicits2 {
import intp.global._
private val tagFn = ReplVals.mkCompilerTypeFromTag[intp.global.type](global)
implicit def mkCompilerTypeFromTag(sym: Symbol) = tagFn(sym)
}
final lazy val replImplicits = new ReplImplicits
def typed[T <: analyzer.global.Tree](tree: T): T = typer.typed(tree).asInstanceOf[T]
}
object ReplVals {
/** Latest attempt to work around the challenge of foo.global.Type
* not being seen as the same type as bar.global.Type even though
* the globals are the same. Dependent method types to the rescue.
*/
def mkCompilerTypeFromTag[T <: Global](global: T) = {
import global._
import definitions._
/** We can't use definitions.compilerTypeFromTag directly because we're passing
* it to map and the compiler refuses to perform eta expansion on a method
* with a dependent return type. (Can this be relaxed?) To get around this
* I have this forwarder which widens the type and then cast the result back
* to the dependent type.
*/
def compilerTypeFromTag(t: BaseUniverse # AbsTypeTag[_]): Global#Type =
definitions.compilerTypeFromTag(t)
class AppliedTypeFromTags(sym: Symbol) {
def apply[M](implicit m1: ru.TypeTag[M]): Type =
if (sym eq NoSymbol) NoType
else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type])
def apply[M1, M2](implicit m1: ru.TypeTag[M1], m2: ru.TypeTag[M2]): Type =
if (sym eq NoSymbol) NoType
else appliedType(sym, compilerTypeFromTag(m1).asInstanceOf[Type], compilerTypeFromTag(m2).asInstanceOf[Type])
}
(sym: Symbol) => new AppliedTypeFromTags(sym)
}
}
|