diff options
author | Paul Phillips <paulp@improving.org> | 2011-05-29 21:30:29 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-05-29 21:30:29 +0000 |
commit | a8926ae0b28d606e240f409adca69f1d91f45990 (patch) | |
tree | d33af8c263ca170a4440d3f4005f69f0916b5b14 /src | |
parent | 4c7d23b470b71e730024d1f7797f742dc97207fa (diff) | |
download | scala-a8926ae0b28d606e240f409adca69f1d91f45990.tar.gz scala-a8926ae0b28d606e240f409adca69f1d91f45990.tar.bz2 scala-a8926ae0b28d606e240f409adca69f1d91f45990.zip |
Now :t types declarations as well as expression...
Now :t types declarations as well as expressions, and cleans up the
output the same way the repl does so stray unsolved type constraints
don't befuddle anyone. Closes #4391, no review.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/ILoop.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/IMain.scala | 55 |
2 files changed, 42 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index d83076f0be..dc2a653c83 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -419,13 +419,11 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) try newJavap() catch { case _: Exception => null } - // TODO: unsolved types shouldn't make it out of this alive. - // - // scala> :t Some(Set(1)) getOrElse Set("abc") - // scala.collection.immutable.Set[_ >: ? <: ?] + // Still todo: modules. private def typeCommand(line: String): Result = { - intp.typeOfExpression(line, false) match { - case Some(tp) => tp.toString + if (line.trim == "") ":type <expression>" + else intp.typeOfExpression(line, false) match { + case Some(tp) => intp.afterTyper(tp.toString) case _ => "" // the error message was already printed } } diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 3f91f3c0d6..2594df90d1 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -510,6 +510,19 @@ class IMain(val settings: Settings, protected val out: PrintWriter) extends Impo Right(buildRequest(line, trees)) } + def typeCleanser(sym: Symbol, memberName: Name): Type = { + // the types are all =>T; remove the => + val tp1 = afterTyper(sym.info.nonPrivateDecl(memberName).tpe match { + case NullaryMethodType(tp) => tp + case tp => tp + }) + // normalize non-public types so we don't see protected aliases like Self + afterTyper(tp1 match { + case TypeRef(_, sym, _) if !sym.isPublic => tp1.normalize + case tp => tp + }) + } + /** * Interpret one line of input. All feedback, including parse errors * and evaluation results, are printed via the supplied compiler's @@ -817,25 +830,13 @@ class IMain(val settings: Settings, protected val out: PrintWriter) extends Impo def lookupTypeOf(name: Name) = typeOf.getOrElse(name, typeOf(global.encode(name.toString))) def simpleNameOfType(name: TypeName) = (compilerTypeOf get name) map (_.typeSymbol.simpleName) - private def typeMap[T](f: Type => T): Map[Name, T] = { - def toType(name: Name): T = { - // the types are all =>T; remove the => - val tp1 = lineAfterTyper(resultSymbol.info.nonPrivateDecl(name).tpe match { - case NullaryMethodType(tp) => tp - case tp => tp - }) - // normalize non-public types so we don't see protected aliases like Self - lineAfterTyper(tp1 match { - case TypeRef(_, sym, _) if !sym.isPublic => f(tp1.normalize) - case tp => f(tp) - }) - } - termNames ++ typeNames map (x => x -> toType(x)) toMap - } + private def typeMap[T](f: Type => T): Map[Name, T] = + termNames ++ typeNames map (x => x -> f(typeCleanser(resultSymbol, x))) toMap + /** Types of variables defined by this request. */ lazy val compilerTypeOf = typeMap[Type](x => x) /** String representations of same. */ - lazy val typeOf = typeMap[String](_.toString) + lazy val typeOf = typeMap[String](tp => afterTyper(tp.toString)) // lazy val definedTypes: Map[Name, Type] = { // typeNames map (x => x -> afterTyper(resultSymbol.info.nonPrivateDecl(x).tpe)) toMap @@ -973,6 +974,26 @@ class IMain(val settings: Settings, protected val out: PrintWriter) extends Impo } } + // Since people will be giving us ":t def foo = 5" even though that is not an + // expression, we have a means of typing declarations too. + private def typeOfDeclaration(code: String): Option[Type] = { + repldbg("typeOfDeclaration(" + code + ")") + val obname = freshInternalVarName() + + interpret("object " + obname + " {\n" + code + "\n}\n", true) match { + case IR.Success => + val sym = symbolOfTerm(obname) + if (sym == NoSymbol) None else { + // TODO: bitmap$n is not marked synthetic. + val decls = sym.tpe.decls.toList filterNot (x => x.isConstructor || x.isPrivate || (x.name.toString contains "$")) + repldbg("decls: " + decls) + decls.lastOption map (decl => typeCleanser(sym, decl.name)) + } + case _ => + None + } + } + // XXX literals. // 1) Identifiers defined in the repl. // 2) A path loadable via getModule. @@ -1011,7 +1032,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) extends Impo // while letting errors through, so it is first trying it silently: if there // is an error, and errors are desired, then it re-evaluates non-silently // to induce the error message. - beSilentDuring(evaluate()) orElse { + beSilentDuring(evaluate()) orElse beSilentDuring(typeOfDeclaration(expr)) orElse { if (!silent) evaluate() |