summaryrefslogtreecommitdiff
path: root/src/repl
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2017-02-20 14:27:50 -0800
committerGitHub <noreply@github.com>2017-02-20 14:27:50 -0800
commit13f7b2a975ee77520535598fd192376b4d4b235e (patch)
tree530d8aadd5824e76ff02f0e16ba8f490440cdc64 /src/repl
parent023a96afe30d04e6de771d0676b85b0889b89a37 (diff)
parentaa7e3359be92afbb6d3cc8dee2139a9872a03a57 (diff)
downloadscala-13f7b2a975ee77520535598fd192376b4d4b235e.tar.gz
scala-13f7b2a975ee77520535598fd192376b4d4b235e.tar.bz2
scala-13f7b2a975ee77520535598fd192376b4d4b235e.zip
Merge pull request #5640 from optimizely/repl-import-handler
SI-9881 Fix ImportHandler's reporting of importedNames and importedSymbols
Diffstat (limited to 'src/repl')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ExprTyper.scala14
-rw-r--r--src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala33
2 files changed, 32 insertions, 15 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
index 01e3a90950..f68705211f 100644
--- a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala
@@ -13,6 +13,12 @@ trait ExprTyper {
import global.{ reporter => _, Import => _, _ }
import naming.freshInternalVarName
+ private def doInterpret(code: String): IR.Result = {
+ // interpret/interpretSynthetic may change the phase, which would have unintended effects on types.
+ val savedPhase = phase
+ try interpretSynthetic(code) finally phase = savedPhase
+ }
+
def symbolOfLine(code: String): Symbol = {
def asExpr(): Symbol = {
val name = freshInternalVarName()
@@ -21,7 +27,7 @@ trait ExprTyper {
// behind a def and strip the NullaryMethodType which wraps the expr.
val line = "def " + name + " = " + code
- interpretSynthetic(line) match {
+ doInterpret(line) match {
case IR.Success =>
val sym0 = symbolOfTerm(name)
// drop NullaryMethodType
@@ -32,7 +38,7 @@ trait ExprTyper {
def asDefn(): Symbol = {
val old = repl.definedSymbolList.toSet
- interpretSynthetic(code) match {
+ doInterpret(code) match {
case IR.Success =>
repl.definedSymbolList filterNot old match {
case Nil => NoSymbol
@@ -43,7 +49,7 @@ trait ExprTyper {
}
}
def asError(): Symbol = {
- interpretSynthetic(code)
+ doInterpret(code)
NoSymbol
}
beSilentDuring(asExpr()) orElse beSilentDuring(asDefn()) orElse asError()
@@ -72,7 +78,7 @@ trait ExprTyper {
def asProperType(): Option[Type] = {
val name = freshInternalVarName()
val line = "def %s: %s = ???" format (name, typeString)
- interpretSynthetic(line) match {
+ doInterpret(line) match {
case IR.Success =>
val sym0 = symbolOfTerm(name)
Some(sym0.asMethod.returnType)
diff --git a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
index d6c0dafaf2..f455e71476 100644
--- a/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/repl/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -213,29 +213,40 @@ trait MemberHandlers {
class ImportHandler(imp: Import) extends MemberHandler(imp) {
val Import(expr, selectors) = imp
+
def targetType = intp.global.rootMirror.getModuleIfDefined("" + expr) match {
case NoSymbol => intp.typeOfExpression("" + expr)
- case sym => sym.thisType
+ case sym => sym.tpe
}
- private def importableTargetMembers = importableMembers(targetType).toList
- // wildcard imports, e.g. import foo._
- private def selectorWild = selectors filter (_.name == nme.USCOREkw)
- // renamed imports, e.g. import foo.{ bar => baz }
- private def selectorRenames = selectors map (_.rename) filterNot (_ == null)
+
+ private def isFlattenedSymbol(sym: Symbol) =
+ sym.owner.isPackageClass &&
+ sym.name.containsName(nme.NAME_JOIN_STRING) &&
+ sym.owner.info.member(sym.name.take(sym.name.indexOf(nme.NAME_JOIN_STRING))) != NoSymbol
+
+ private def importableTargetMembers =
+ importableMembers(exitingTyper(targetType)).filterNot(isFlattenedSymbol).toList
+
+ // non-wildcard imports
+ private def individualSelectors = selectors filter analyzer.isIndividualImport
/** Whether this import includes a wildcard import */
- val importsWildcard = selectorWild.nonEmpty
+ val importsWildcard = selectors exists analyzer.isWildcardImport
def implicitSymbols = importedSymbols filter (_.isImplicit)
def importedSymbols = individualSymbols ++ wildcardSymbols
- private val selectorNames = selectorRenames filterNot (_ == nme.USCOREkw) flatMap (_.bothNames) toSet
- lazy val individualSymbols: List[Symbol] = exitingTyper(importableTargetMembers filter (m => selectorNames(m.name)))
- lazy val wildcardSymbols: List[Symbol] = exitingTyper(if (importsWildcard) importableTargetMembers else Nil)
+ lazy val importableSymbolsWithRenames = {
+ val selectorRenameMap = individualSelectors.flatMap(x => x.name.bothNames zip x.rename.bothNames).toMap
+ importableTargetMembers flatMap (m => selectorRenameMap.get(m.name) map (m -> _))
+ }
+
+ lazy val individualSymbols: List[Symbol] = importableSymbolsWithRenames map (_._1)
+ lazy val wildcardSymbols: List[Symbol] = if (importsWildcard) importableTargetMembers else Nil
/** Complete list of names imported by a wildcard */
lazy val wildcardNames: List[Name] = wildcardSymbols map (_.name)
- lazy val individualNames: List[Name] = individualSymbols map (_.name)
+ lazy val individualNames: List[Name] = importableSymbolsWithRenames map (_._2)
/** The names imported by this statement */
override lazy val importedNames: List[Name] = wildcardNames ++ individualNames