diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index 2d8d591b6d8b..058999795793 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -852,7 +852,7 @@ trait ContextErrors { } catch { // the code above tries various tricks to detect the relevant portion of the stack trace // if these tricks fail, just fall back to uninformative, but better than nothing, getMessage - case NonFatal(ex) => // currently giving a spurious warning, see SI-6994 + case NonFatal(ex) => macroLogVerbose("got an exception when processing a macro generated exception\n" + "offender = " + stackTraceString(realex) + "\n" + "error = " + stackTraceString(ex)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index fde2f7bb0353..ea7a43d7f1aa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -29,7 +29,7 @@ trait Contexts { self: Analyzer => enclClass = this enclMethod = this - override val depth = 0 + override lazy val depth = 0 override def nextEnclosing(p: Context => Boolean): Context = this override def enclosingContextChain: List[Context] = Nil override def implicitss: List[List[ImplicitInfo]] = Nil @@ -223,15 +223,17 @@ trait Contexts { self: Analyzer => protected def outerDepth = if (outerIsNoContext) 0 else outer.depth - val depth: Int = { + lazy val depth: Int = { val increasesDepth = isRootImport || outerIsNoContext || (outer.scope != scope) ( if (increasesDepth) 1 else 0 ) + outerDepth } - /** The currently visible imports */ + /** The currently visible imports, from innermost to outermost. */ def imports: List[ImportInfo] = outer.imports /** Equivalent to `imports.headOption`, but more efficient */ def firstImport: Option[ImportInfo] = outer.firstImport + + /** A root import is never unused and always bumps context depth. (scala/Predef/java.lang and magic REPL imports) */ def isRootImport: Boolean = false /** Types for which implicit arguments are currently searched */ @@ -436,7 +438,7 @@ trait Contexts { self: Analyzer => * Construct a child context. The parent and child will share the report buffer. * Compare with `makeSilent`, in which the child has a fresh report buffer. * - * If `tree` is an `Import`, that import will be avaiable at the head of + * If `tree` is an `Import`, that import will be available at the head of * `Context#imports`. */ def make(tree: Tree = tree, owner: Symbol = owner, @@ -463,10 +465,11 @@ trait Contexts { self: Analyzer => else prefix // The blank canvas - val c = if (isImport) - new Context(tree, owner, scope, unit, this, reporter) with ImportContext - else - new Context(tree, owner, scope, unit, this, reporter) + val c = + if (isImport) + new Context(tree, owner, scope, unit, this, reporter) with ImportContext + else + new Context(tree, owner, scope, unit, this, reporter) // Fields that are directly propagated c.variance = variance @@ -985,7 +988,7 @@ trait Contexts { self: Analyzer => def isNameInScope(name: Name) = lookupSymbol(name, _ => true).isSuccess /** Find the symbol of a simple name starting from this context. - * All names are filtered through the "qualifies" predicate, + * All names are filtered through the "qualifies" predicate; * the search continuing as long as no qualifying name is found. */ def lookupSymbol(name: Name, qualifies: Symbol => Boolean): NameLookup = { @@ -996,20 +999,16 @@ trait Contexts { self: Analyzer => var cx: Context = this // the context under consideration var symbolDepth: Int = -1 // the depth of the directly found symbol - def finish(qual: Tree, sym: Symbol): NameLookup = ( - if (lookupError ne null) lookupError - else sym match { - case NoSymbol if inaccessible ne null => inaccessible - case NoSymbol => LookupNotFound - case _ => LookupSucceeded(qual, sym) - } - ) - def finishDefSym(sym: Symbol, pre0: Type): NameLookup = - if (requiresQualifier(sym)) - finish(gen.mkAttributedQualifier(pre0), sym) - else - finish(EmptyTree, sym) - + def finish(qual: Tree, sym: Symbol): NameLookup = sym match { + case _ if lookupError ne null => lookupError + case NoSymbol if inaccessible ne null => inaccessible + case NoSymbol => LookupNotFound + case _ => LookupSucceeded(qual, sym) + } + def finishDefSym(sym: Symbol, pre0: Type): NameLookup = { + val t = if (requiresQualifier(sym)) gen.mkAttributedQualifier(pre0) else EmptyTree + finish(t, sym) + } def isPackageOwnedInDifferentUnit(s: Symbol) = ( s.isDefinedInPackage && ( !currentRun.compiles(s) @@ -1028,16 +1027,6 @@ trait Contexts { self: Analyzer => } def accessibleInPrefix(s: Symbol) = isAccessible(s, pre, superAccess = false) - def searchPrefix = { - cx = cx.enclClass - val found0 = lookupInPrefix(name) - val found1 = found0 filter accessibleInPrefix - if (found0.exists && !found1.exists && inaccessible == null) - inaccessible = LookupInaccessible(found0, analyzer.lastAccessCheckDetails) - - found1 - } - def lookupInScope(scope: Scope) = (scope lookupUnshadowedEntries name filter (e => qualifies(e.sym))).toList @@ -1046,7 +1035,7 @@ trait Contexts { self: Analyzer => // Constructor lookup should only look in the decls of the enclosing class // not in the self-type, nor in the enclosing context, nor in imports (SI-4460, SI-6745) - if (name == nme.CONSTRUCTOR) return { + def lookupCtor: NameLookup = { val enclClassSym = cx.enclClass.owner val scope = cx.enclClass.prefix.baseType(enclClassSym).decls val constructorSym = lookupInScope(scope) match { @@ -1057,118 +1046,141 @@ trait Contexts { self: Analyzer => finishDefSym(constructorSym, cx.enclClass.prefix) } - // cx.scope eq null arises during FixInvalidSyms in Duplicators - while (defSym == NoSymbol && (cx ne NoContext) && (cx.scope ne null)) { - pre = cx.enclClass.prefix - defSym = lookupInScope(cx.scope) match { - case Nil => searchPrefix - case entries @ (hd :: tl) => - // we have a winner: record the symbol depth - symbolDepth = (cx.depth - cx.scope.nestingLevel) + hd.depth - if (tl.isEmpty) hd.sym - else newOverloaded(cx.owner, pre, entries) + // Handle name binding precedence. Get the name from enclosing scopes, then get + // the name as imported; then choose the higher precedence binding. + // The rule is actually: bindings have a given precedence (1-4). In a given scope, + // higher precedence wins and equal precedence is ambiguous. Otherwise, inner scoped + // name hides if equal or higher precedence. The precedence levels are: + // 1) defined here 2) specific import 3) wildcard import 4) defined elsewhere (package-defined in other unit) + def doLookup: NameLookup = { + def searchPrefix: Symbol = { + cx = cx.enclClass + val found0 = lookupInPrefix(name) + val found1 = found0 filter accessibleInPrefix + if (found0.exists && !found1.exists && inaccessible == null) + inaccessible = LookupInaccessible(found0, analyzer.lastAccessCheckDetails) + + found1 + } + // we have a winner: record the symbol depth + def setDepthAt(se: ScopeEntry): Unit = symbolDepth = (cx.depth - cx.scope.nestingLevel) + se.depth + + // search enclosing scopes + // cx.scope eq null arises during FixInvalidSyms in Duplicators + while (defSym == NoSymbol && (cx ne NoContext) && (cx.scope ne null)) { + pre = cx.enclClass.prefix + defSym = lookupInScope(cx.scope) match { + case Nil => searchPrefix + case se :: Nil => setDepthAt(se) ; se.sym + case entries @ (hd :: tl) => setDepthAt(hd) ; newOverloaded(cx.owner, pre, entries) + } + if (!defSym.exists) cx = cx.outer // push further outward + } + if (symbolDepth < 0) symbolDepth = cx.depth + + var impSym: Symbol = NoSymbol + var imports = Context.this.imports + def imp1 = imports.head + def imp2 = imports.tail.head + def sameDepth = imp1.depth == imp2.depth + def imp1Explicit = imp1 isExplicitImport name + def imp2Explicit = imp2 isExplicitImport name + + def lookupImport(imp: ImportInfo, requireExplicit: Boolean): Symbol = + importedAccessibleSymbol(imp, name, requireExplicit, record = true) filter qualifies + + def checkUpstreamImports(): Unit = { + // We continue walking down the imports as long as the tail is non-empty, which gives us: + // imports == imp1 :: imp2 :: _ + // And at least one of the following is true: + // - imp1 and imp2 are at the same depth + // - imp1 is a wildcard import, so all explicit imports from outer scopes must be checked + def keepLooking = ( + lookupError == null + && imports.tail.nonEmpty + && (sameDepth || !imp1Explicit) + ) + // If we find a competitor imp2 which imports the same name, possible outcomes are: + // + // - same depth, imp1 wild, imp2 explicit: imp2 wins, drop imp1 + // - same depth, imp1 wild, imp2 wild: ambiguity check + // - same depth, imp1 explicit, imp2 explicit: ambiguity check + // - differing depth, imp1 wild, imp2 explicit: ambiguity check + // - all others: imp1 wins, drop imp2 + // + // The ambiguity check is: if we can verify that both imports refer to the same + // symbol (e.g. import foo.X followed by import foo._) then we discard imp2 + // and proceed. If we cannot, issue an ambiguity error. + while (keepLooking) { + // If not at the same depth, limit the lookup to explicit imports. + // This is desirable from a performance standpoint (compare to + // filtering after the fact) but also necessary to keep the unused + // import check from being misled by symbol lookups which are not + // actually used. + val other = lookupImport(imp2, requireExplicit = !sameDepth) + def imp1wins() = { imports = imp1 :: imports.tail.tail } + def imp2wins() = { impSym = other ; imports = imports.tail } + + if (!other.exists) // imp1 wins; drop imp2 and continue. + imp1wins() + else if (sameDepth && !imp1Explicit && imp2Explicit) // imp2 wins; drop imp1 and continue. + imp2wins() + else resolveAmbiguousImport(name, imp1, imp2) match { + case Some(imp) => if (imp eq imp1) imp1wins() else imp2wins() + case _ => lookupError = ambiguousImports(imp1, imp2) + } + } } - if (!defSym.exists) - cx = cx.outer // push further outward - } - if (symbolDepth < 0) - symbolDepth = cx.depth - - var impSym: Symbol = NoSymbol - var imports = Context.this.imports - def imp1 = imports.head - def imp2 = imports.tail.head - def sameDepth = imp1.depth == imp2.depth - def imp1Explicit = imp1 isExplicitImport name - def imp2Explicit = imp2 isExplicitImport name - - def lookupImport(imp: ImportInfo, requireExplicit: Boolean) = - importedAccessibleSymbol(imp, name, requireExplicit, record = true) filter qualifies - - // Java: A single-type-import declaration d in a compilation unit c of package p - // that imports a type named n shadows, throughout c, the declarations of: - // - // 1) any top level type named n declared in another compilation unit of p - // - // A type-import-on-demand declaration never causes any other declaration to be shadowed. - // - // Scala: Bindings of different kinds have a precedence defined on them: - // - // 1) Definitions and declarations that are local, inherited, or made available by a - // package clause in the same compilation unit where the definition occurs have - // highest precedence. - // 2) Explicit imports have next highest precedence. - def depthOk(imp: ImportInfo) = ( - imp.depth > symbolDepth - || (unit.isJava && imp.isExplicitImport(name) && imp.depth == symbolDepth) - ) - - while (!impSym.exists && imports.nonEmpty && depthOk(imports.head)) { - impSym = lookupImport(imp1, requireExplicit = false) - if (!impSym.exists) - imports = imports.tail - } - - if (defSym.exists && impSym.exists) { - // imported symbols take precedence over package-owned symbols in different compilation units. - if (isPackageOwnedInDifferentUnit(defSym)) - defSym = NoSymbol - // Defined symbols take precedence over erroneous imports. - else if (impSym.isError || impSym.name == nme.CONSTRUCTOR) - impSym = NoSymbol - // Otherwise they are irreconcilably ambiguous - else - return ambiguousDefnAndImport(defSym.alternatives.head.owner, imp1) - } - // At this point only one or the other of defSym and impSym might be set. - if (defSym.exists) - finishDefSym(defSym, pre) - else if (impSym.exists) { - // We continue walking down the imports as long as the tail is non-empty, which gives us: - // imports == imp1 :: imp2 :: _ - // And at least one of the following is true: - // - imp1 and imp2 are at the same depth - // - imp1 is a wildcard import, so all explicit imports from outer scopes must be checked - def keepLooking = ( - lookupError == null - && imports.tail.nonEmpty - && (sameDepth || !imp1Explicit) - ) - // If we find a competitor imp2 which imports the same name, possible outcomes are: + // Java: A single-type-import declaration d in a compilation unit c of package p + // that imports a type named n shadows, throughout c, the declarations of: // - // - same depth, imp1 wild, imp2 explicit: imp2 wins, drop imp1 - // - same depth, imp1 wild, imp2 wild: ambiguity check - // - same depth, imp1 explicit, imp2 explicit: ambiguity check - // - differing depth, imp1 wild, imp2 explicit: ambiguity check - // - all others: imp1 wins, drop imp2 + // 1) any top level type named n declared in another compilation unit of p // - // The ambiguity check is: if we can verify that both imports refer to the same - // symbol (e.g. import foo.X followed by import foo._) then we discard imp2 - // and proceed. If we cannot, issue an ambiguity error. - while (keepLooking) { - // If not at the same depth, limit the lookup to explicit imports. - // This is desirable from a performance standpoint (compare to - // filtering after the fact) but also necessary to keep the unused - // import check from being misled by symbol lookups which are not - // actually used. - val other = lookupImport(imp2, requireExplicit = !sameDepth) - def imp1wins() = { imports = imp1 :: imports.tail.tail } - def imp2wins() = { impSym = other ; imports = imports.tail } - - if (!other.exists) // imp1 wins; drop imp2 and continue. - imp1wins() - else if (sameDepth && !imp1Explicit && imp2Explicit) // imp2 wins; drop imp1 and continue. - imp2wins() - else resolveAmbiguousImport(name, imp1, imp2) match { - case Some(imp) => if (imp eq imp1) imp1wins() else imp2wins() - case _ => lookupError = ambiguousImports(imp1, imp2) - } + // A type-import-on-demand declaration never causes any other declaration to be shadowed. + // + // Scala: Bindings of different kinds have a precedence defined on them: + // + // 1) Definitions and declarations that are local, inherited, or made available by a + // package clause in the same compilation unit where the definition occurs have + // highest precedence. + // 2) Explicit imports have next highest precedence. + def depthOk(imp: ImportInfo) = ( + imp.depth > symbolDepth + || (unit.isJava && imp.isExplicitImport(name) && imp.depth == symbolDepth) + ) + + // search imports + while (!impSym.exists && imports.nonEmpty && depthOk(imports.head)) { + impSym = lookupImport(imp1, requireExplicit = false) + if (!impSym.exists) imports = imports.tail + } + + // found both in enclosing scope and imported from elsewhere, so pick one + if (defSym.exists && impSym.exists) { + // imported symbols take precedence over package-owned symbols in different compilation units. + if (isPackageOwnedInDifferentUnit(defSym)) + defSym = NoSymbol + // Defined symbols take precedence over erroneous imports. + else if (impSym.isError || impSym.name == nme.CONSTRUCTOR) + impSym = NoSymbol + // Otherwise they are irreconcilably ambiguous + else + return ambiguousDefnAndImport(defSym.alternatives.head.owner, imp1) } - // optimization: don't write out package prefixes - finish(resetPos(imp1.qual.duplicate), impSym) + + // At this point only one or the other of defSym and impSym might be set. + if (defSym.exists) + finishDefSym(defSym, pre) + else if (impSym.exists) { + checkUpstreamImports() + // optimization: don't write out package prefixes + finish(resetPos(imp1.qual.duplicate), impSym) + } + else finish(EmptyTree, NoSymbol) } - else finish(EmptyTree, NoSymbol) + // ctor must be in enclosing class; anything else can be in enclosing contexts or imported + if (name == nme.CONSTRUCTOR) lookupCtor else doLookup } /** @@ -1217,16 +1229,23 @@ trait Contexts { self: Analyzer => /** A `Context` focussed on an `Import` tree */ trait ImportContext extends Context { - private val impInfo: ImportInfo = { + private[this] lazy val impInfo: ImportInfo = { val info = new ImportInfo(tree.asInstanceOf[Import], outerDepth) - if (settings.warnUnusedImport && !isRootImport) // excludes java.lang/scala/Predef imports - allImportInfos(unit) ::= info + if (settings.warnUnusedImport && !isRootImport) allImportInfos(unit) ::= info info } override final def imports = impInfo :: super.imports override final def firstImport = Some(impInfo) - override final def isRootImport = !tree.pos.isDefined - override final def toString = super.toString + " with " + s"ImportContext { $impInfo; outer.owner = ${outer.owner} }" + // must be a def for bootstrapping -- TODO: why? + override final lazy val isRootImport = !tree.pos.isDefined || { + val head = { + val all = impInfo.allImportedSymbols.iterator + if (all.hasNext) all.next else null + } + //definitions.Interpreter_iw == head + head != null && definitions.Interpreter_iw.fullName == head.fullName + } + override final def toString = s"${super.toString} with ImportContext { $impInfo; outer.owner = ${outer.owner} }" } /** A reporter for use during type checking. It has multiple modes for handling errors. @@ -1370,7 +1389,6 @@ trait Contexts { self: Analyzer => protected def handleError(pos: Position, msg: String): Unit = reporter.error(pos, msg) } - private[typechecker] class BufferingReporter(_errorBuffer: mutable.LinkedHashSet[AbsTypeError] = null, _warningBuffer: mutable.LinkedHashSet[(Position, String)] = null) extends ContextReporter(_errorBuffer, _warningBuffer) { override def isBuffering = true @@ -1408,7 +1426,7 @@ trait Contexts { self: Analyzer => def qual: Tree = tree.symbol.info match { case ImportType(expr) => expr case ErrorType => tree setType NoType // fix for #2870 - case _ => throw new FatalError("symbol " + tree.symbol + " has bad type: " + tree.symbol.info) //debug + case _ => throw new FatalError(s"symbol ${tree.symbol} has bad type: ${tree.symbol.info}") //debug } /** Is name imported explicitly, not via wildcard? */ diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 395bda234bb2..e44983793849 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -552,8 +552,10 @@ trait Namers extends MethodSynthesis { val Import(expr, selectors) = tree val base = expr.tpe - def checkNotRedundant(pos: Position, from: Name, to0: Name) { - def check(to: Name) = { + // warn proactively if specific import loses to definition in scope, + // since it may result in desired implicit not imported into scope. + def checkNotRedundant(pos: Position, from: Name, to0: Name): Unit = { + def check(to: Name): Unit = { val e = context.scope.lookupEntry(to) if (e != null && e.owner == context.scope && e.sym.exists) @@ -565,7 +567,8 @@ trait Namers extends MethodSynthesis { defSym andAlso (typer.permanentlyHiddenWarning(pos, to0, _)) } } - if (!tree.symbol.isSynthetic && expr.symbol != null && !expr.symbol.isInterpreterWrapper) { + def isReplMagic(importInfo: ImportInfo): Boolean = importInfo.isExplicitImport(Interpreter_iw.name) + if (!tree.symbol.isSynthetic && expr.symbol != null && !context.imports.exists(isReplMagic)) { if (base.member(from) != NoSymbol) check(to0) if (base.member(from.toTypeName) != NoSymbol) @@ -596,7 +599,6 @@ trait Namers extends MethodSynthesis { checkNotRedundant(tree.pos withPoint fromPos, from, to) } } - def noDuplicates(names: List[Name], check: DuplicatesErrorKinds.Value) { def loop(xs: List[Name]): Unit = xs match { case Nil => () @@ -606,6 +608,7 @@ trait Namers extends MethodSynthesis { } loop(names filterNot (x => x == null || x == nme.WILDCARD)) } + selectors foreach checkSelector // checks on the whole set @@ -1644,7 +1647,6 @@ trait Namers extends MethodSynthesis { } } - /** Given a case class * case class C[Ts] (ps: Us) * Add the following methods to toScope: diff --git a/src/partest-extras/scala/tools/partest/ReplTest.scala b/src/partest-extras/scala/tools/partest/ReplTest.scala index 9c95a718ca41..715d6e775468 100644 --- a/src/partest-extras/scala/tools/partest/ReplTest.scala +++ b/src/partest-extras/scala/tools/partest/ReplTest.scala @@ -31,20 +31,17 @@ abstract class ReplTest extends DirectTest { val s = settings log("eval(): settings = " + s) val lines = ILoop.runForTranscript(code, s, inSession = inSession).lines - (if (welcoming) { - val welcome = "(Welcome to Scala).*".r - //val welcome = Regex.quote(header.lines.next).r - //val version = "(.*version).*".r // version on separate line? - //var inHead = false - lines map { - //case s @ welcome() => inHead = true ; s - //case version(s) if inHead => inHead = false ; s - case welcome(s) => s - case s => s + val headless = + if (welcoming) { + val welcome = "(Welcome to Scala).*".r + lines map { + case welcome(s) => s + case s => s + } + } else { + lines drop header.lines.size } - } else { - lines drop header.lines.size - }) map normalize + headless.map(normalize) } def show() = eval() foreach println } @@ -54,6 +51,21 @@ trait Welcoming { this: ReplTest => override def welcoming = true } +/** Strip Any.toString's id@abcdef16 hashCodes. These are generally at end of result lines. */ +trait Hashless extends ReplTest { + import Hashless._ + override def normalize(s: String) = { + val n = super.normalize(s) + n match { + case hashless(prefix) => s"$prefix@XXXXXXXX" + case _ => n + } + } +} +object Hashless { + private val hashless = "(.*)@[a-fA-F0-9]+".r +} + /** Run a REPL test from a session transcript. * The `session` should be a triple-quoted String starting * with the `Type in expressions` message and ending diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 19460af27fe3..5ab3b9e63297 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -525,6 +525,8 @@ trait Definitions extends api.StandardDefinitions { def MacroContextTreeType = BlackboxContextClass.map(sym => getTypeMember(sym, tpnme.Tree)) lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] + lazy val Interpreter_iw = getModuleIfDefined("scala.tools.nsc.interpreter.$u007B$u007B") //{{ + lazy val StringContextClass = requiredClass[scala.StringContext] // SI-8392 a reflection universe on classpath may not have diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 15aa1a40fa05..927fc64ebdf9 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -323,8 +323,8 @@ trait StdNames { val EXCEPTION_RESULT_PREFIX = "exceptionResult" val EXPAND_SEPARATOR_STRING = "$$" val FRESH_TERM_NAME_PREFIX = "x$" - val INTERPRETER_IMPORT_WRAPPER = "$iw" val LOCALDUMMY_PREFIX = " final def isOverridableMember = !(isClass || isEffectivelyFinal) && safeOwner.isClass - /** Does this symbol denote a wrapper created by the repl? */ - final def isInterpreterWrapper = ( - (this hasFlag MODULE) - && isTopLevel - && nme.isReplWrapperName(name) - ) /** In our current architecture, symbols for top-level classes and modules * are created as dummies. Package symbols just call newClass(name) or newModule(name) and @@ -852,7 +846,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def skipConstructor: Symbol = if (isConstructor) owner else this /** Conditions where we omit the prefix when printing a symbol, to avoid - * unpleasantries like Predef.String, $iw.$iw.Foo and .Bippy. + * unpleasantries like Predef.String, $read.Foo and .Bippy. */ final def isOmittablePrefix = /*!settings.debug.value &&*/ ( UnqualifiedOwners(skipPackageObject) @@ -861,7 +855,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isEmptyPrefix = ( isEffectiveRoot // has no prefix for real, or || isAnonOrRefinementClass // has uninteresting or prefix - || nme.isReplWrapperName(name) // has ugly $iw. prefix (doesn't call isInterpreterWrapper due to nesting) + || nme.isReplWrapperName(name) // $read.Foo or $read.INSTANCE.Foo ) def isFBounded = info match { case TypeBounds(_, _) => info.baseTypeSeq exists (_ contains this) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 95d6662d1488..2321cf296bc1 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -316,6 +316,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.BlackboxContextClass definitions.WhiteboxContextClass definitions.MacroImplAnnotation + definitions.Interpreter_iw definitions.StringContextClass definitions.QuasiquoteClass definitions.QuasiquoteClass_api diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index f0683a5af297..d605de6b4999 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -7,7 +7,6 @@ package scala package tools.nsc package interpreter -import PartialFunction.cond import scala.language.implicitConversions import scala.beans.BeanProperty import scala.collection.mutable @@ -314,12 +313,12 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def originalPath(name: String): String = originalPath(TermName(name)) def originalPath(name: Name): String = translateOriginalPath(typerOp path name) def originalPath(sym: Symbol): String = translateOriginalPath(typerOp path sym) + /** For class based repl mode we use an .INSTANCE accessor. */ - val readInstanceName = if(isClassBased) ".INSTANCE" else "" - def translateOriginalPath(p: String): String = { - val readName = java.util.regex.Matcher.quoteReplacement(sessionNames.read) - p.replaceFirst(readName, readName + readInstanceName) - } + val readInstanceName = if (isClassBased) ".INSTANCE" else "" + def translateOriginalPath(p: String): String = + if (isClassBased) p.replace(sessionNames.read, sessionNames.read + readInstanceName) else p + def flatPath(sym: Symbol): String = flatOp shift sym.javaClassName def translatePath(path: String) = { @@ -329,7 +328,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** If path represents a class resource in the default package, * see if the corresponding symbol has a class file that is a REPL artifact - * residing at a different resource path. Translate X.class to $line3/$read$$iw$$iw$X.class. + * residing at a different resource path. Translate X.class to $line3/$read$X.class. */ def translateSimpleResource(path: String): Option[String] = { if (!(path contains '/') && (path endsWith ".class")) { @@ -701,12 +700,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends val unwrapped = unwrap(t) - // Example input: $line3.$read$$iw$$iw$ - val classNameRegex = (naming.lineRegex + ".*").r - def isWrapperInit(x: StackTraceElement) = cond(x.getClassName) { - case classNameRegex() if x.getMethodName == nme.CONSTRUCTOR.decoded => true - } - val stackTrace = unwrapped stackTracePrefixString (!isWrapperInit(_)) + def notWrapperInit(x: StackTraceElement) = !naming.isLineWrapperClassName(x.getClassName) || x.getMethodName != nme.CONSTRUCTOR.decoded + + val stackTrace = unwrapped.stackTracePrefixString(notWrapperInit _) withLastExceptionLock[String]({ directBind[Throwable]("lastException", unwrapped)(StdReplTags.tagOfThrowable, classTag[Throwable]) @@ -842,7 +838,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends * append to objectName to access anything bound by request. */ lazy val ComputedImports(headerPreamble, importsPreamble, importsTrailer, accessPath) = - exitingTyper(importsCode(referencedNames.toSet, ObjectSourceCode, definesClass, generousImports)) + exitingTyper(importsCode(referencedNames.toSet, definesClass, generousImports)) /** the line of code to compute */ def toCompute = line @@ -855,7 +851,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** generate the source code for the object that computes this request */ abstract class Wrapper extends IMain.CodeAssembler[MemberHandler] { - def path = originalPath("$intp") + //def path = originalPath("$intp") def envLines = { if (!isReplPower) Nil // power mode only for now else { @@ -876,37 +872,23 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** A format string with %s for $read, specifying the wrapper definition. */ def preambleHeader: String - /** Like preambleHeader for an import wrapper. */ - def prewrap: String = preambleHeader + "\n" - - /** Like postamble for an import wrapper. */ - def postwrap: String + def postamble = importsTrailer + "\n}" } class ObjectBasedWrapper extends Wrapper { def preambleHeader = "object %s {" - - def postamble = importsTrailer + "\n}" - - def postwrap = "}\n" } class ClassBasedWrapper extends Wrapper { def preambleHeader = "sealed class %s extends _root_.java.io.Serializable { " /** Adds an object that instantiates the outer wrapping class. */ - def postamble = s""" - |$importsTrailer - |} + override def postamble = s""" + |${super.postamble} |object ${lineRep.readName} { | val INSTANCE = new ${lineRep.readName}(); |} |""".stripMargin - - import nme.{ INTERPRETER_IMPORT_WRAPPER => iw } - - /** Adds a val that instantiates the wrapping class. */ - def postwrap = s"}\nval $iw = new $iw\n" } private[interpreter] lazy val ObjectSourceCode: Wrapper = @@ -969,14 +951,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } } - //lazy val resultSymbol = lineRep.resolvePathToSymbol(fullAccessPath) // the type symbol of the owner of the member that supplies the result value - lazy val resultSymbol = { - val sym = - lineRep.resolvePathToSymbol(fullAccessPath) - // plow through the INSTANCE member when -Yrepl-class-based - if (sym.isTerm && sym.nameString == "INSTANCE") sym.typeSignature.typeSymbol else sym - } + lazy val resultSymbol = lineRep.resolvePathToSymbol(fullAccessPath) def applyToResultMember[T](name: Name, f: Symbol => T) = exitingTyper(f(resultSymbol.info.nonPrivateDecl(name))) @@ -989,7 +965,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** Types of variables defined by this request. */ lazy val compilerTypeOf = typeMap[Type](x => x) withDefaultValue NoType /** String representations of same. */ - lazy val typeOf = typeMap[String](tp => exitingTyper(tp.toString)) + lazy val typeOf = typeMap[String](tp => exitingTyper { + val s = tp.toString + if (isClassBased) s.stripPrefix("INSTANCE.") else s + }) lazy val definedSymbols = ( termNames.map(x => x -> applyToResultMember(x, x => x)) ++ @@ -1207,12 +1186,6 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def withoutTruncating[A](body: => A): A = reporter withoutTruncating body def symbolDefString(sym: Symbol) = { - /* - val ds = exitingTyper(sym.defString) - val no = List(sym.owner.name + ".this.", sym.owner.fullName + ".") - val q = TypeStrings.quieter(ds, no: _*) - Console println ss"defstr of $ds excluding $no is $q" - */ TypeStrings.quieter( exitingTyper(sym.defString), sym.owner.name + ".this.", @@ -1220,11 +1193,13 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends ) } + /** Secret bookcase entrance for repl debuggers: end the line + * with "// show" and see what's going on. + */ + val showCodeBackDoor = raw".*//\s*show\s*".r + def showCodeIfDebugging(code: String) { - /** Secret bookcase entrance for repl debuggers: end the line - * with "// show" and see what's going on. - */ - def isShow = code.lines exists (_.trim endsWith "// show") + def isShow = code.lines exists { case showCodeBackDoor() => true case _ => false } if (isReplDebug || isShow) { beSilentDuring(parse(code)) match { case parse.Success(ts) => @@ -1254,6 +1229,7 @@ object IMain { // $line3.$read$$iw$$iw$Bippy@4a6a00ca private def removeLineWrapper(s: String) = s.replaceAll("""\$line\d+[./]\$(read|eval|print)[$.]""", "") private def removeIWPackages(s: String) = s.replaceAll("""\$(iw|read|eval|print)[$.]""", "") + @deprecated("Use intp.naming.unmangle.", "2.12.0-M5") def stripString(s: String) = removeIWPackages(removeLineWrapper(s)) trait CodeAssembler[T] { diff --git a/src/repl/scala/tools/nsc/interpreter/Imports.scala b/src/repl/scala/tools/nsc/interpreter/Imports.scala index 0cda9c4da3cb..7cf7916e3e2c 100644 --- a/src/repl/scala/tools/nsc/interpreter/Imports.scala +++ b/src/repl/scala/tools/nsc/interpreter/Imports.scala @@ -1,13 +1,33 @@ /* NSC -- new Scala compiler - * Copyright 2005-2013 LAMP/EPFL - * @author Paul Phillips + * Copyright 2005-2016 LAMP/EPFL + * @author Paul Phillips */ - package scala.tools.nsc package interpreter import scala.collection.mutable +/** A magic symbol that, when imported, bumps the effective nesting level + * of the typechecker. + * + * The REPL inserts this import to control scoping in code templates, + * without excessive lexical noise. + * + * {{{ + * import p.X + * import scala.tools.nsc.interpreter.`{{` + * import q.X + * X // q.X + * }}} + * + * Its name is chosen to suggest scoping by braces; the brace is doubled + * to avoid confusion in printed output, as the name will be visible to + * a REPL user inspecting generated code. + * + * There is no complementary symbol to restore the nesting level. + */ +object `{{` + trait Imports { self: IMain => @@ -27,34 +47,12 @@ trait Imports { } /** Symbols whose contents are language-defined to be imported. */ - def languageWildcardSyms: List[Symbol] = List(JavaLangPackage, ScalaPackage, PredefModule) + private def languageWildcardSyms: List[Symbol] = List(JavaLangPackage, ScalaPackage, PredefModule) def languageWildcardHandlers = languageWildcardSyms map makeWildcardImportHandler - def allImportedNames = importHandlers flatMap (_.importedNames) - - /** Types which have been wildcard imported, such as: - * val x = "abc" ; import x._ // type java.lang.String - * import java.lang.String._ // object java.lang.String - * - * Used by tab completion. - * - * XXX right now this gets import x._ and import java.lang.String._, - * but doesn't figure out import String._. There's a lot of ad hoc - * scope twiddling which should be swept away in favor of digging - * into the compiler scopes. - */ - def sessionWildcards: List[Type] = { - importHandlers filter (_.importsWildcard) map (_.targetType) distinct - } - - def languageSymbols = languageWildcardSyms flatMap membersAtPickler - def sessionImportedSymbols = importHandlers flatMap (_.importedSymbols) - def importedSymbols = languageSymbols ++ sessionImportedSymbols - def importedTermSymbols = importedSymbols collect { case x: TermSymbol => x } - /** Tuples of (source, imported symbols) in the order they were imported. */ - def importedSymbolsBySource: List[(Symbol, List[Symbol])] = { + private def importedSymbolsBySource: List[(Symbol, List[Symbol])] = { val lang = languageWildcardSyms map (sym => (sym, membersAtPickler(sym))) val session = importHandlers filter (_.targetType != NoType) map { mh => (mh.targetType.typeSymbol, mh.importedSymbols) @@ -96,7 +94,7 @@ trait Imports { */ case class ComputedImports(header: String, prepend: String, append: String, access: String) - protected def importsCode(wanted: Set[Name], wrapper: Request#Wrapper, definesClass: Boolean, generousImports: Boolean): ComputedImports = { + protected def importsCode(wanted: Set[Name], definesClass: Boolean, generousImports: Boolean): ComputedImports = { val header, code, trailingBraces, accessPath = new StringBuilder val currentImps = mutable.HashSet[Name]() var predefEscapes = false // only emit predef import header if name not resolved in history, loosely @@ -140,77 +138,64 @@ trait Imports { select(allReqAndHandlers reverseMap { case (r, h) => ReqAndHandler(r, h) }, wanted).reverse } - // add code for a new object to hold some imports - def addWrapper() { - import nme.{ INTERPRETER_IMPORT_WRAPPER => iw } - code append (wrapper.prewrap format iw) - trailingBraces append wrapper.postwrap - accessPath append s".$iw" - currentImps.clear() - } - - def maybeWrap(names: Name*) = if (names exists currentImps) addWrapper() - - def wrapBeforeAndAfter[T](op: => T): T = { - addWrapper() - try op finally addWrapper() - } - // imports from Predef are relocated to the template header to allow hiding. def checkHeader(h: ImportHandler) = h.referencedNames contains PredefModule.name // loop through previous requests, adding imports for each one - wrapBeforeAndAfter { - // Reusing a single temporary value when import from a line with multiple definitions. - val tempValLines = mutable.Set[Int]() - for (ReqAndHandler(req, handler) <- reqsToUse) { - val objName = req.lineRep.readPathInstance - if (isReplTrace) - code.append(ss"// $objName definedNames ${handler.definedNames}, curImps $currentImps\n") - handler match { - case h: ImportHandler if checkHeader(h) => - header.clear() - header append f"${h.member}%n" - // If the user entered an import, then just use it; add an import wrapping - // level if the import might conflict with some other import - case x: ImportHandler if x.importsWildcard => - wrapBeforeAndAfter(code append (x.member + "\n")) - case x: ImportHandler => - maybeWrap(x.importedNames: _*) - code append (x.member + "\n") - currentImps ++= x.importedNames - - case x if isClassBased => - for (sym <- x.definedSymbols) { - maybeWrap(sym.name) - x match { - case _: ClassHandler => - code.append(s"import ${objName}${req.accessPath}.`${sym.name}`\n") - case _ => - val valName = s"${req.lineRep.packageName}${req.lineRep.readName}" - if (!tempValLines.contains(req.lineRep.lineId)) { - code.append(s"val $valName: ${objName}.type = $objName\n") - tempValLines += req.lineRep.lineId - } - code.append(s"import ${valName}${req.accessPath}.`${sym.name}`\n") - } - currentImps += sym.name - } - // For other requests, import each defined name. - // import them explicitly instead of with _, so that - // ambiguity errors will not be generated. Also, quote - // the name of the variable, so that we don't need to - // handle quoting keywords separately. - case x => - for (sym <- x.definedSymbols) { - maybeWrap(sym.name) - code append s"import ${x.path}\n" - currentImps += sym.name + def addLevelChangingImport() = code.append("import _root_.scala.tools.nsc.interpreter.`{{`\n") + + // Reusing a single temporary value when import from a line with multiple definitions. + val tempValLines = mutable.Set[Int]() + addLevelChangingImport() + for (ReqAndHandler(req, handler) <- reqsToUse) { + val objName = req.lineRep.readPathInstance + handler match { + case h: ImportHandler if checkHeader(h) => + header.clear() + header append (h.member + "\n") + // If the user entered an import, then just use it; add an import wrapping + // level if the import might conflict with some other import + case x: ImportHandler if x.importsWildcard => + addLevelChangingImport() + code append (x.member + "\n") + case x: ImportHandler => + addLevelChangingImport() + code append (x.member + "\n") + currentImps ++= x.importedNames + + case x if isClassBased => + for (sym <- x.definedSymbols) { + addLevelChangingImport() + x match { + case _: ClassHandler => + code.append(s"import ${objName}${req.accessPath}.`${sym.name}`\n") + case _ => + val valName = s"${req.lineRep.packageName}${req.lineRep.readName}" + if (!tempValLines.contains(req.lineRep.lineId)) { + code.append(s"val $valName: ${objName}.type = $objName\n") + tempValLines += req.lineRep.lineId + } + code.append(s"import ${valName}${req.accessPath}.`${sym.name}`\n") } - } + currentImps += sym.name + } + // For other requests, import each defined name. + // import them explicitly instead of with _, so that + // ambiguity errors will not be generated. Also, quote + // the name of the variable, so that we don't need to + // handle quoting keywords separately. + case x => + for (sym <- x.definedSymbols) { + addLevelChangingImport() + code append s"import ${x.path}\n" + currentImps += sym.name + } } } + if (predefEscapes || code.nonEmpty) + addLevelChangingImport() + val computedHeader = if (predefEscapes) header.toString else "" ComputedImports(computedHeader, code.toString, trailingBraces.toString, accessPath.toString) } diff --git a/src/repl/scala/tools/nsc/interpreter/Naming.scala b/src/repl/scala/tools/nsc/interpreter/Naming.scala index e09c6f315e78..4671ab27f8da 100644 --- a/src/repl/scala/tools/nsc/interpreter/Naming.scala +++ b/src/repl/scala/tools/nsc/interpreter/Naming.scala @@ -16,7 +16,7 @@ import scala.util.matching.Regex trait Naming { def unmangle(str: String): String = { val ESC = '\u001b' - val cleaned = removeIWPackages(removeLineWrapper(str)) + val cleaned = str.replaceAll(lineRegex, "") // Looking to exclude binary data which hoses the terminal, but // let through the subset of it we need, like whitespace and also // for ansi codes. @@ -37,16 +37,17 @@ trait Naming { // The two name forms this is catching are the two sides of this assignment: // - // $line3.$read.$iw.$iw.Bippy = - // $line3.$read$$iw$$iw$Bippy@4a6a00ca - lazy val lineRegex = { + // $line3.$read.Bippy = + // $line3.$read$Bippy@4a6a00ca + private lazy val lineRegex = { val sn = sessionNames val members = List(sn.read, sn.eval, sn.print) map Regex.quote mkString ("(?:", "|", ")") debugging("lineRegex")(Regex.quote(sn.line) + """\d+[./]""" + members + """[$.]""") } - private def removeLineWrapper(s: String) = s.replaceAll(lineRegex, "") - private def removeIWPackages(s: String) = s.replaceAll("""\$iw[$.]""", "") + // Example input: $line3.$read$ + private lazy val classNameRegex = (lineRegex + ".*").r + def isLineWrapperClassName(name: String): Boolean = classNameRegex.findFirstIn(name).nonEmpty trait SessionNames { // All values are configurable by passing e.g. -Dscala.repl.name.read=XXX diff --git a/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala b/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala index a912ec9749f8..787710632542 100644 --- a/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala +++ b/src/repl/scala/tools/nsc/interpreter/PresentationCompilerCompleter.scala @@ -40,12 +40,22 @@ class PresentationCompilerCompleter(intp: IMain) extends Completion { val offset = result.preambleLength val pos1 = result.unit.source.position(offset).withEnd(offset + buf.length) import result.compiler._ - val tree = new Locator(pos1) locateIn result.unit.body match { - case Template(_, _, constructor :: (rest :+ last)) => if (rest.isEmpty) last else Block(rest, last) - case t => t + val (tree, tpe) = new Locator(pos1).locateIn(result.unit.body) match { + case Template(_, _, constructor :: last :: Nil) => (last, last.tpe) + case Template(_, _, constructor :: (rest :+ last)) if rest.nonEmpty => + val unimports = rest.dropWhile { + case Import(expr, _) => + /* selecting $iw or from history (trailing dot or dollar required) */ + expr.toString.startsWith("scala.tools.nsc.interpreter") || intp.naming.isLineWrapperClassName(expr.toString + "$") + case _ => false + } + val t = if (unimports.nonEmpty) Block(unimports, last) else last + (t, last.tpe) + case t => (t, t.tpe) } - val printed = showCode(tree) + " // : " + tree.tpe.safeToString - Candidates(cursor, "" :: printed :: Nil) + val printed = s"${showCode(tree)} // : ${ if (tpe != null) tpe.safeToString else "???" }" + //Candidates(cursor, "" :: printed :: Nil) + Candidates(cursor, "" :: printed.lines.toList) // avoid ctl-J in JLine? } def typeAt(result: Result, start: Int, end: Int) = { val tpString = result.compiler.exitingTyper(result.typedTreeAt(buf, start, end).tpe.toString) diff --git a/src/repl/scala/tools/nsc/interpreter/Scripted.scala b/src/repl/scala/tools/nsc/interpreter/Scripted.scala index 6aef486957d5..edf718feccfe 100644 --- a/src/repl/scala/tools/nsc/interpreter/Scripted.scala +++ b/src/repl/scala/tools/nsc/interpreter/Scripted.scala @@ -31,14 +31,14 @@ class Scripted(@BeanProperty val factory: ScriptEngineFactory, settings: Setting /* Modify the template to snag definitions from dynamic context. * So object $iw { x + 42 } becomes object $iw { def x = $ctx.x ; x + 42 } */ - override protected def importsCode(wanted: Set[Name], wrapper: Request#Wrapper, definesClass: Boolean, generousImports: Boolean) = { + override protected def importsCode(wanted: Set[Name], definesClass: Boolean, generousImports: Boolean) = { // cull references that can be satisfied from the current dynamic context val contextual = wanted & contextNames if (contextual.nonEmpty) { val neededContext = (wanted &~ contextual) + TermName(ctx) - val ComputedImports(header, preamble, trailer, path) = super.importsCode(neededContext, wrapper, definesClass, generousImports) + val ComputedImports(header, preamble, trailer, path) = super.importsCode(neededContext, definesClass, generousImports) val adjusted = contextual.map { n => val valname = n.decodedName s"""def `$valname` = $ctx.`$valname` @@ -46,7 +46,7 @@ class Scripted(@BeanProperty val factory: ScriptEngineFactory, settings: Setting }.mkString(preamble, "\n", "\n") ComputedImports(header, adjusted, trailer, path) } - else super.importsCode(wanted, wrapper, definesClass, generousImports) + else super.importsCode(wanted, definesClass, generousImports) } // names available in current dynamic context diff --git a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala index 8c646be9c676..6ed573d98c69 100644 --- a/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/DocFactory.scala @@ -78,16 +78,12 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor } ) - modelFactory.makeModel match { - case Some(madeModel) => - if (!settings.scaladocQuietRun) - println("model contains " + modelFactory.templatesCount + " documentable templates") - Some(madeModel) - case None => - if (!settings.scaladocQuietRun) - println("no documentable class found in compilation units") - None + val made = modelFactory.makeModel + if (!settings.scaladocQuietRun) { + if (made.isEmpty) println("no documentable class found in compilation units") + else println("model contains " + modelFactory.templatesCount + " documentable templates") } + made } object NoCompilerRunException extends ControlThrowable { } diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala index 8f58a7b84563..eacba054fbc5 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala @@ -75,6 +75,13 @@ class IndexScript(universe: doc.Universe) extends Page { ) } f(universe.rootPackage).sortBy(_.toString) +/* +======= + def allPackages = { + def unpack(parent: Package): List[Package] = parent.packages.flatMap(p => p :: unpack(p)) + unpack(universe.rootPackage).sortBy(_.toString) +>>>>>>> SI-6623 Avoid $iw wrappers in REPL +*/ } def allPackagesWithTemplates: Map[Package, List[DocTemplateEntity]] = { diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 72d8d39fd023..08fc347bc144 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -41,6 +41,9 @@ scala> trait PointlessTrait defined trait PointlessTrait scala> val (x,y) = (2,3) +:10: warning: imported `x' is permanently hidden by definition of value x +import x + ^ x: Int = 2 y: Int = 3 @@ -353,7 +356,7 @@ defined class Term scala> def f(e: Exp) = e match { // non-exhaustive warning here case _:Fact => 3 } -:18: warning: match may not be exhaustive. +:20: warning: match may not be exhaustive. It would fail on the following inputs: Exp(), Term() def f(e: Exp) = e match { // non-exhaustive warning here ^ @@ -363,6 +366,6 @@ scala> :quit plusOne: (x: Int)Int res0: Int = 6 res0: String = after reset -:12: error: not found: value plusOne +:11: error: not found: value plusOne plusOne(5) // should be undefined now ^ diff --git a/test/files/run/kind-repl-command.check b/test/files/run/kind-repl-command.check index 560529ba039c..e050fb4bc17d 100644 --- a/test/files/run/kind-repl-command.check +++ b/test/files/run/kind-repl-command.check @@ -19,7 +19,7 @@ scala> :k new { def empty = false } AnyRef{def empty: Boolean}'s kind is A scala> :k Nonexisting -:12: error: not found: value Nonexisting +:11: error: not found: value Nonexisting Nonexisting ^ diff --git a/test/files/run/reify-repl-fail-gracefully.check b/test/files/run/reify-repl-fail-gracefully.check index 32ed87635688..025d377a4325 100644 --- a/test/files/run/reify-repl-fail-gracefully.check +++ b/test/files/run/reify-repl-fail-gracefully.check @@ -8,7 +8,7 @@ import scala.reflect.runtime.universe._ scala> scala> reify -:16: error: too few argument lists for macro invocation +:15: error: too few argument lists for macro invocation reify ^ diff --git a/test/files/run/reify_newimpl_25.check b/test/files/run/reify_newimpl_25.check index 9104d8df0b2e..e512cfc52e63 100644 --- a/test/files/run/reify_newimpl_25.check +++ b/test/files/run/reify_newimpl_25.check @@ -5,7 +5,7 @@ scala> { val tt = implicitly[TypeTag[x.type]] println(tt) } -:15: free term: Ident(TermName("x")) defined by res0 in :14:14 +:14: free term: Ident(TermName("x")) defined by res0 in :13:14 val tt = implicitly[TypeTag[x.type]] ^ TypeTag[x.type] diff --git a/test/files/run/reify_newimpl_26.check b/test/files/run/reify_newimpl_26.check index cbb21854ba71..b203389db10c 100644 --- a/test/files/run/reify_newimpl_26.check +++ b/test/files/run/reify_newimpl_26.check @@ -4,7 +4,7 @@ scala> def foo[T]{ val tt = implicitly[WeakTypeTag[List[T]]] println(tt) } -:13: free type: Ident(TypeName("T")) defined by foo in :11:16 +:12: free type: Ident(TypeName("T")) defined by foo in :10:16 val tt = implicitly[WeakTypeTag[List[T]]] ^ foo: [T]=> Unit diff --git a/test/files/run/repl-classbased.check b/test/files/run/repl-classbased.check index e11fc170e5b8..9be4efd3f418 100644 --- a/test/files/run/repl-classbased.check +++ b/test/files/run/repl-classbased.check @@ -15,9 +15,17 @@ scala> implicitly[K] res0: K = K(OK?) scala> val k = 42 +:13: warning: imported `k' is permanently hidden by definition of value k +import c.k + ^ k: Int = 42 scala> k // was K(OK?) -res1: Int = 42 +:19: error: reference to k is ambiguous; +it is imported twice in the same scope by +import $line11$read.k +and import c.k + k // was K(OK?) + ^ scala> :quit diff --git a/test/files/run/repl-colon-type.check b/test/files/run/repl-colon-type.check index 1217e8d8c2d7..05e3fc72c33f 100644 --- a/test/files/run/repl-colon-type.check +++ b/test/files/run/repl-colon-type.check @@ -37,9 +37,9 @@ scala> :type protected lazy val f = 5 :5: error: lazy value f cannot be accessed in object $iw Access to protected lazy value f not permitted because enclosing object $eval in package $line13 is not a subclass of - object $iw where target is defined + object $read in package $line13 where target is defined lazy val $result = f - ^ + ^ scala> :type def f = 5 => Int diff --git a/test/files/run/repl-no-imports-no-predef.check b/test/files/run/repl-no-imports-no-predef.check index 7c4ee82c78bf..bacb19ac32dd 100644 --- a/test/files/run/repl-no-imports-no-predef.check +++ b/test/files/run/repl-no-imports-no-predef.check @@ -40,7 +40,7 @@ scala> { import scala.StringContext; s"answer: $answer" } res9: String = answer: 42 scala> s"answer: $answer" -:13: error: not found: value StringContext +:14: error: not found: value StringContext s"answer: $answer" ^ @@ -172,7 +172,7 @@ scala> 55 ; ((2 + 2)) ; (1, 2, 3) res29: (Int, Int, Int) = (1,2,3) scala> 55 ; (x: scala.Int) => x + 1 ; () => ((5)) -:12: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +:13: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses 55 ; (x: scala.Int) => x + 1 ;; ^ res30: () => Int = diff --git a/test/files/run/repl-out-dir.check b/test/files/run/repl-out-dir.check index 6fd85f5bbab2..2267bd48bfb4 100644 --- a/test/files/run/repl-out-dir.check +++ b/test/files/run/repl-out-dir.check @@ -13,31 +13,23 @@ repl-out-dir-run.obj $line2 $eval$.class $eval.class - $read$$iw$$iw$.class - $read$$iw$.class $read$.class $read.class $line3 $eval$.class $eval.class - $read$$iw$$iw$.class - $read$$iw$$iw$Bippy$.class - $read$$iw$$iw$Bippy.class - $read$$iw$.class $read$.class + $read$Bippy$.class + $read$Bippy.class $read.class $line4 $eval$.class $eval.class - $read$$iw$$iw$.class - $read$$iw$.class $read$.class $read.class $line5 $eval$.class $eval.class - $read$$iw$$iw$.class - $read$$iw$.class $read$.class $read.class $repl_$init.class diff --git a/test/files/run/repl-paste-2.check b/test/files/run/repl-paste-2.check index 4c589df41a58..4408babe5d8d 100644 --- a/test/files/run/repl-paste-2.check +++ b/test/files/run/repl-paste-2.check @@ -42,7 +42,7 @@ scala> res5 + res6 res1: Int = 690 scala> val x = dingus -:11: error: not found: value dingus +:10: error: not found: value dingus val x = dingus ^ diff --git a/test/files/run/repl-reset.check b/test/files/run/repl-reset.check index cf4d9a149e29..b0683fff79b5 100644 --- a/test/files/run/repl-reset.check +++ b/test/files/run/repl-reset.check @@ -28,13 +28,13 @@ Forgetting all expression results and named terms: $intp, BippyBungus, x1, x2, x Forgetting defined types: BippyBungus scala> x1 + x2 + x3 -:12: error: not found: value x1 +:11: error: not found: value x1 x1 + x2 + x3 ^ -:12: error: not found: value x2 +:11: error: not found: value x2 x1 + x2 + x3 ^ -:12: error: not found: value x3 +:11: error: not found: value x3 x1 + x2 + x3 ^ @@ -42,7 +42,7 @@ scala> val x1 = 4 x1: Int = 4 scala> new BippyBungus -:12: error: not found: type BippyBungus +:11: error: not found: type BippyBungus new BippyBungus ^ diff --git a/test/files/run/repl-serialization.scala b/test/files/run/repl-serialization.scala index 8bc0dd3a8b82..6597caa5dd32 100644 --- a/test/files/run/repl-serialization.scala +++ b/test/files/run/repl-serialization.scala @@ -6,63 +6,59 @@ import scala.tools.nsc.interpreter.IMain import scala.tools.nsc.util._ import scala.reflect.internal.util.AbstractFileClassLoader -object Test { - def main(args: Array[String]) { - run() +object Test extends App { + val settings = { + val ss = new Settings() + ss.Yreplclassbased.value = true + ss.usejavacp.value = true + ss } - def run(): Unit = { - val settings = new Settings() - settings.Yreplclassbased.value = true - settings.usejavacp.value = true + object extract extends ((AnyRef) => Unit) with Serializable { + var value: AnyRef = null - var imain: IMain = null - object extract extends ((AnyRef) => Unit) with Serializable { - var value: AnyRef = null - - def apply(a: AnyRef) = value = a - } + def apply(a: AnyRef) = value = a + } - val code = - """val x = {println(" evaluating x"); 0 } - |def getX() = x - |class U extends Serializable { println("constructing U"); val x = 0 ; override def toString = "U" } - |lazy val y = {println(" evaluating y"); 0 } - |class D; val z = {println(" evaluating z"); 0}; val zz = {println(" evaluating zz"); 0} - |object O extends Serializable { val apply = {println(" evaluating O"); 0} } - |class A(i: Int) { println(" constructing A") } - |type AA = A - |val u = new U() - |extract(() => new AA(x + getX() + y + z + zz + O.apply + u.x)) - """.stripMargin + val code = + """val x = {println(" evaluating x"); 0 } + |def getX() = x + |class U extends Serializable { println("constructing U"); val x = 0 ; override def toString = "U" } + |lazy val y = {println(" evaluating y"); 0 } + |class D; val z = {println(" evaluating z"); 0}; val zz = {println(" evaluating zz"); 0} + |object O extends Serializable { val apply = {println(" evaluating O"); 0} } + |class A(i: Int) { println(" constructing A") } + |type AA = A + |val u = new U() + |extract(() => new AA(x + getX() + y + z + zz + O.apply + u.x)) + """.stripMargin - imain = IMain(settings) - println("== evaluating lines") - imain.directBind("extract", "(AnyRef => Unit)", extract) - code.lines.foreach(imain.interpret) + val imain = IMain(settings) + println("== evaluating lines") + imain.directBind("extract", "(AnyRef => Unit)", extract) + code.lines.foreach(imain.interpret) - val virtualFile: AbstractFile = extract.value.getClass.getClassLoader.asInstanceOf[AbstractFileClassLoader].root - val newLoader = new AbstractFileClassLoader(virtualFile, getClass.getClassLoader) + val virtualFile: AbstractFile = extract.value.getClass.getClassLoader.asInstanceOf[AbstractFileClassLoader].root + val newLoader = new AbstractFileClassLoader(virtualFile, getClass.getClassLoader) - def deserializeInNewLoader(string: Array[Byte]): AnyRef = { - val bis = new ByteArrayInputStream(string) - val in = new ObjectInputStream(bis) { - override def resolveClass(desc: ObjectStreamClass) = Class.forName(desc.getName, false, newLoader) - } - in.readObject() + def deserializeInNewLoader(string: Array[Byte]): AnyRef = { + val bis = new ByteArrayInputStream(string) + val in = new ObjectInputStream(bis) { + override def resolveClass(desc: ObjectStreamClass) = Class.forName(desc.getName, false, newLoader) } - def serialize(o: AnyRef): Array[Byte] = { - val bos = new ByteArrayOutputStream() - val out = new ObjectOutputStream(bos) - out.writeObject(o) - out.close() - bos.toByteArray - } - println("== evaluating lambda") - extract.value.asInstanceOf[() => Any].apply() - println("== reconstituting into a fresh classloader") - val reconstituted = deserializeInNewLoader(serialize(extract.value)).asInstanceOf[() => Any] - println("== evaluating reconstituted lambda") - reconstituted.apply() // should not print("evaluating x") a second time + in.readObject() + } + def serialize(o: AnyRef): Array[Byte] = { + val bos = new ByteArrayOutputStream() + val out = new ObjectOutputStream(bos) + out.writeObject(o) + out.close() + bos.toByteArray } + println("== evaluating lambda") + extract.value.asInstanceOf[() => Any].apply() + println("== reconstituting into a fresh classloader") + val reconstituted = deserializeInNewLoader(serialize(extract.value)).asInstanceOf[() => Any] + println("== evaluating reconstituted lambda") + reconstituted.apply() // should not print("evaluating x") a second time } diff --git a/test/files/run/repl-trim-stack-trace.scala b/test/files/run/repl-trim-stack-trace.scala index c0814905f941..06c75014e739 100644 --- a/test/files/run/repl-trim-stack-trace.scala +++ b/test/files/run/repl-trim-stack-trace.scala @@ -35,8 +35,10 @@ scala> :quit""" // normalize the "elided" lines because the frame count depends on test context lazy val elided = """(\s+\.{3} )\d+( elided)""".r + lazy val frame = """(\s+\Qat .f(:\E)\d+(\))""".r override def normalize(line: String) = line match { case elided(ellipsis, suffix) => s"$ellipsis???$suffix" + case frame(prefix, suffix) => s"${prefix}XX${suffix}" case s => s } override def expected = super.expected map normalize diff --git a/test/files/run/t5256d.check b/test/files/run/t5256d.check index 3cdcb577b084..56c3a45258de 100644 --- a/test/files/run/t5256d.check +++ b/test/files/run/t5256d.check @@ -15,7 +15,7 @@ scala> println(c) class A scala> println(c.fullName) -$line8.$read.$iw.$iw.$iw.$iw.A +$line8.$read.A scala> println(c.info) scala.AnyRef { diff --git a/test/files/run/t5655.check b/test/files/run/t5655.check index 91919976249c..15c8435cbccd 100644 --- a/test/files/run/t5655.check +++ b/test/files/run/t5655.check @@ -1,24 +1,14 @@ -scala> object x { def x={} } +scala> object x { def x = () } defined object x scala> import x._ import x._ scala> x -:16: error: reference to x is ambiguous; -it is imported twice in the same scope by -import x._ -and import x - x - ^ +res0: x.type = x$@XXXXXXXX scala> x -:16: error: reference to x is ambiguous; -it is imported twice in the same scope by -import x._ -and import x - x - ^ +res1: x.type = x$@XXXXXXXX scala> :quit diff --git a/test/files/run/t5655.scala b/test/files/run/t5655.scala index b15feb788eee..62e5d6aedc53 100644 --- a/test/files/run/t5655.scala +++ b/test/files/run/t5655.scala @@ -1,8 +1,8 @@ -import scala.tools.partest.ReplTest +import scala.tools.partest.{ReplTest, Hashless} -object Test extends ReplTest { +object Test extends ReplTest with Hashless { def code = """ -object x { def x={} } +object x { def x = () } import x._ x x diff --git a/test/files/run/t7319.check b/test/files/run/t7319.check index 1dcb84c804b7..6b872684954b 100644 --- a/test/files/run/t7319.check +++ b/test/files/run/t7319.check @@ -15,21 +15,21 @@ warning: there was one feature warning; for details, enable `:setting -feature' convert: [F[X <: F[X]]](builder: F[_ <: F[_]])Int scala> convert(Some[Int](0)) -:15: error: no type parameters for method convert: (builder: F[_ <: F[_]])Int exist so that it can be applied to arguments (Some[Int]) +:17: error: no type parameters for method convert: (builder: F[_ <: F[_]])Int exist so that it can be applied to arguments (Some[Int]) --- because --- argument expression's type is not compatible with formal parameter type; found : Some[Int] required: ?F[_$1] forSome { type _$1 <: ?F[_$2] forSome { type _$2 } } convert(Some[Int](0)) ^ -:15: error: type mismatch; +:17: error: type mismatch; found : Some[Int] required: F[_ <: F[_]] convert(Some[Int](0)) ^ scala> Range(1,2).toArray: Seq[_] -:14: error: polymorphic expression cannot be instantiated to expected type; +:15: error: polymorphic expression cannot be instantiated to expected type; found : [B >: Int]Array[B] required: Seq[_] Range(1,2).toArray: Seq[_] diff --git a/test/files/run/t7747-repl.check b/test/files/run/t7747-repl.check index ab37da5722c8..2fbc5c288c83 100644 --- a/test/files/run/t7747-repl.check +++ b/test/files/run/t7747-repl.check @@ -110,7 +110,7 @@ scala> 55 ; ((2 + 2)) ; (1, 2, 3) res15: (Int, Int, Int) = (1,2,3) scala> 55 ; (x: Int) => x + 1 ; () => ((5)) -:13: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses +:14: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses 55 ; (x: Int) => x + 1 ;; ^ res16: () => Int = @@ -251,27 +251,21 @@ sealed class $read extends _root_.java.io.Serializable { super.; () }; - sealed class $iw extends _root_.java.io.Serializable { - def () = { - super.; - () - }; - import $line44.$read.INSTANCE.$iw.$iw.BippyBups; - import $line44.$read.INSTANCE.$iw.$iw.BippyBups; - import $line45.$read.INSTANCE.$iw.$iw.PuppyPups; - import $line45.$read.INSTANCE.$iw.$iw.PuppyPups; - import $line46.$read.INSTANCE.$iw.$iw.Bingo; - import $line46.$read.INSTANCE.$iw.$iw.Bingo; - sealed class $iw extends _root_.java.io.Serializable { - def () = { - super.; - () - }; - val res3 = List(BippyBups, PuppyPups, Bingo) - }; - val $iw = new $iw. - }; - val $iw = new $iw. + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import $line44.$read.INSTANCE.BippyBups; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import $line44.$read.INSTANCE.BippyBups; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import $line45.$read.INSTANCE.PuppyPups; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import $line45.$read.INSTANCE.PuppyPups; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import $line46.$read.INSTANCE.Bingo; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + import $line46.$read.INSTANCE.Bingo; + import _root_.scala.tools.nsc.interpreter.$u007B$u007B; + val res3 = List(BippyBups, PuppyPups, Bingo) } object $read extends scala.AnyRef { def () = { @@ -289,7 +283,7 @@ scala> val a = Sum("A", "B") a: Sum = Sum(A,B) scala> def b(a: Sum): String = a match { case Sum(_, _) => "Found Sum" } -b: (a: Sum)String +b: (a: INSTANCE.Sum)String scala> b(a) res4: String = Found Sum diff --git a/test/files/run/t8843-repl-xlat.scala b/test/files/run/t8843-repl-xlat.scala index 215dd970611b..f0fe7fcc52e2 100644 --- a/test/files/run/t8843-repl-xlat.scala +++ b/test/files/run/t8843-repl-xlat.scala @@ -12,10 +12,10 @@ scala> class Bippy defined class Bippy scala> $intp.classLoader getResource "Bippy.class" -res0: java.net.URL = memory:(memory)/$line4/$read$$iw$$iw$Bippy.class +res0: java.net.URL = memory:(memory)/$line4/$read$Bippy.class scala> ($intp.classLoader getResources "Bippy.class").nextElement -res1: java.net.URL = memory:(memory)/$line4/$read$$iw$$iw$Bippy.class +res1: java.net.URL = memory:(memory)/$line4/$read$Bippy.class scala> ($intp.classLoader classBytes "Bippy").nonEmpty res2: Boolean = true diff --git a/test/files/run/t9170.scala b/test/files/run/t9170.scala index 87471fb1294d..c2e188a1e83d 100644 --- a/test/files/run/t9170.scala +++ b/test/files/run/t9170.scala @@ -8,17 +8,17 @@ object Test extends SessionTest { def session = """ scala> object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 } -:11: error: double definition: -def f[A](a: => A): Int at line 11 and -def f[A](a: => Either[Exception,A]): Int at line 11 +:10: error: double definition: +def f[A](a: => A): Int at line 10 and +def f[A](a: => Either[Exception,A]): Int at line 10 have same type after erasure: (a: Function0)Int object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 } ^ scala> object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 } -:11: error: double definition: -def f[A](a: => A): Int at line 11 and -def f[A](a: => Either[Exception,A]): Int at line 11 +:10: error: double definition: +def f[A](a: => A): Int at line 10 and +def f[A](a: => Either[Exception,A]): Int at line 10 have same type after erasure: (a: Function0)Int object Y { def f[A](a: => A) = 1 ; def f[A](a: => Either[Exception, A]) = 2 } ^ @@ -27,9 +27,9 @@ scala> object Y { | def f[A](a: => A) = 1 | def f[A](a: => Either[Exception, A]) = 2 | } -:13: error: double definition: -def f[A](a: => A): Int at line 12 and -def f[A](a: => Either[Exception,A]): Int at line 13 +:12: error: double definition: +def f[A](a: => A): Int at line 11 and +def f[A](a: => Either[Exception,A]): Int at line 12 have same type after erasure: (a: Function0)Int def f[A](a: => Either[Exception, A]) = 2 ^ @@ -44,13 +44,12 @@ object Y { // Exiting paste mode, now interpreting. -:13: error: double definition: -def f[A](a: => A): Int at line 12 and -def f[A](a: => Either[Exception,A]): Int at line 13 +:12: error: double definition: +def f[A](a: => A): Int at line 11 and +def f[A](a: => Either[Exception,A]): Int at line 12 have same type after erasure: (a: Function0)Int def f[A](a: => Either[Exception, A]) = 2 ^ scala> :quit""" } - diff --git a/test/files/run/t9206.scala b/test/files/run/t9206.scala index 406798104ebb..7f8765d47a4f 100644 --- a/test/files/run/t9206.scala +++ b/test/files/run/t9206.scala @@ -2,36 +2,21 @@ import scala.tools.partest.SessionTest object Test extends SessionTest { - //override def prompt = "XXX> " -//Welcome to Scala version 2.11.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40). def session = s"""| |scala> val i: Int = "foo" - |:11: error: type mismatch; + |:10: error: type mismatch; | found : String("foo") | required: Int | val i: Int = "foo" | ^ | |scala> { val j = 42 ; val i: Int = "foo" + j } - |:12: error: type mismatch; + |:11: error: type mismatch; | found : String | required: Int | { val j = 42 ; val i: Int = "foo" + j } | ^ | |scala> :quit""" - /* - |XXX> XXX> def f = 42 - | - |// Detected repl transcript paste: ctrl-D to finish. - | - |// Replaying 1 commands from transcript. - | - |XXX> def f = 42 - |f: Int - | - |XXX> :quit""" - */ - } diff --git a/test/files/run/xMigration.check b/test/files/run/xMigration.check index b812d6a282f5..1ab2b623133a 100644 --- a/test/files/run/xMigration.check +++ b/test/files/run/xMigration.check @@ -10,7 +10,7 @@ res1: Iterable[String] = MapLike.DefaultValuesIterable(eis) scala> :setting -Xmigration:any scala> Map(1 -> "eis").values // warn -:12: warning: method values in trait MapLike has changed semantics in version 2.8.0: +:11: warning: method values in trait MapLike has changed semantics in version 2.8.0: `values` returns `Iterable[V]` rather than `Iterator[V]`. Map(1 -> "eis").values // warn ^ @@ -24,7 +24,7 @@ res3: Iterable[String] = MapLike.DefaultValuesIterable(eis) scala> :setting -Xmigration:2.7 scala> Map(1 -> "eis").values // warn -:12: warning: method values in trait MapLike has changed semantics in version 2.8.0: +:11: warning: method values in trait MapLike has changed semantics in version 2.8.0: `values` returns `Iterable[V]` rather than `Iterator[V]`. Map(1 -> "eis").values // warn ^ @@ -38,7 +38,7 @@ res5: Iterable[String] = MapLike.DefaultValuesIterable(eis) scala> :setting -Xmigration // same as :any scala> Map(1 -> "eis").values // warn -:12: warning: method values in trait MapLike has changed semantics in version 2.8.0: +:11: warning: method values in trait MapLike has changed semantics in version 2.8.0: `values` returns `Iterable[V]` rather than `Iterator[V]`. Map(1 -> "eis").values // warn ^ diff --git a/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala b/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala index 01d17110d698..e3887af9bc30 100644 --- a/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala +++ b/test/junit/scala/tools/nsc/interpreter/ScriptedTest.scala @@ -96,7 +96,7 @@ class ScriptedTest { } @Test def `on compile error`(): Unit = { val engine = scripted - val err = "not found: value foo in def f = foo at line number 11 at column number 16" + val err = "not found: value foo in def f = foo at line number 10 at column number 16" assertThrows[ScriptException](engine.compile("def f = foo"), _ == err) } } diff --git a/test/scalacheck/scala/tools/nsc/scaladoc/IndexScriptTest.scala b/test/scalacheck/scala/tools/nsc/scaladoc/IndexScriptTest.scala index fb4dc55c9832..cb9cd0cab994 100644 --- a/test/scalacheck/scala/tools/nsc/scaladoc/IndexScriptTest.scala +++ b/test/scalacheck/scala/tools/nsc/scaladoc/IndexScriptTest.scala @@ -21,7 +21,7 @@ object IndexScriptTest extends Properties("IndexScript") { } val docFactory = { - val settings = new doc.Settings({Console.err.println(_)}) + val settings = new doc.Settings(Console.err.println(_)) settings.scaladocQuietRun = true settings.nowarn.value = true settings.classpath.value = getClasspath @@ -31,7 +31,7 @@ object IndexScriptTest extends Properties("IndexScript") { val indexModelFactory = doc.model.IndexModelFactory - def createIndexScript(path: String) = + def createIndexScript(path: String): Option[IndexScript] = docFactory.makeUniverse(Left(List(path))) match { case Some(universe) => Some(new IndexScript(universe)) @@ -48,7 +48,8 @@ object IndexScriptTest extends Properties("IndexScript") { "scala.tools.nsc", "scala.tools.nsc.doc", "scala.tools.nsc.doc.html", - "scala.tools.nsc.doc.html.page" + "scala.tools.nsc.doc.html.page", + "scala.tools.nsc.interpreter" // incurred by Contexts.isRootImport ) case None => false