From aa7e3359be92afbb6d3cc8dee2139a9872a03a57 Mon Sep 17 00:00:00 2001 From: Hao Xia Date: Tue, 9 Aug 2016 14:07:26 -0700 Subject: Fix ImportHandler's reporting of importedNames and importedSymbols --- .../scala/tools/nsc/interpreter/ExprTyper.scala | 14 ++++++--- .../tools/nsc/interpreter/MemberHandlers.scala | 33 ++++++++++++++-------- 2 files changed, 32 insertions(+), 15 deletions(-) (limited to 'src/repl') 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 -- cgit v1.2.3