From 99388a81d42cde0cb0e8ecd57f290f6df25b9bdd Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 26 Apr 2012 10:03:56 +0300 Subject: cleaning up macros, one step at a time --- .../scala/reflect/makro/runtime/Context.scala | 3 +- .../scala/reflect/makro/runtime/Traces.scala | 8 + .../scala/reflect/makro/runtime/Typers.scala | 17 +- src/compiler/scala/reflect/makro/util/Traces.scala | 18 ++ src/compiler/scala/reflect/reify/Errors.scala | 3 +- .../scala/reflect/reify/codegen/Types.scala | 2 +- .../scala/reflect/reify/codegen/Util.scala | 2 - src/compiler/scala/reflect/reify/package.scala | 10 +- .../scala/tools/nsc/settings/ScalaSettings.scala | 6 +- .../scala/tools/nsc/typechecker/Macros.scala | 201 +++++++++------------ src/library/scala/reflect/makro/Typers.scala | 2 +- 11 files changed, 135 insertions(+), 137 deletions(-) create mode 100644 src/compiler/scala/reflect/makro/runtime/Traces.scala create mode 100644 src/compiler/scala/reflect/makro/util/Traces.scala (limited to 'src') diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/makro/runtime/Context.scala index 15a4118b85..ca02822788 100644 --- a/src/compiler/scala/reflect/makro/runtime/Context.scala +++ b/src/compiler/scala/reflect/makro/runtime/Context.scala @@ -14,7 +14,8 @@ abstract class Context extends scala.reflect.makro.Context with Settings with Symbols with Typers - with Util { + with Util + with Traces { val mirror: Global diff --git a/src/compiler/scala/reflect/makro/runtime/Traces.scala b/src/compiler/scala/reflect/makro/runtime/Traces.scala new file mode 100644 index 0000000000..6b61842316 --- /dev/null +++ b/src/compiler/scala/reflect/makro/runtime/Traces.scala @@ -0,0 +1,8 @@ +package scala.reflect.makro +package runtime + +trait Traces extends util.Traces { + self: Context => + + def globalSettings = mirror.settings +} diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/makro/runtime/Typers.scala index 98dbd65b72..c61e492250 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/makro/runtime/Typers.scala @@ -9,8 +9,7 @@ trait Typers { def openImplicits: List[(Type, Tree)] = callsiteTyper.context.openImplicits def typeCheck(tree: Tree, pt: Type = mirror.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { - def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) - trace("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled)) + macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled)) val wrapper1 = if (!withImplicitViewsDisabled) (callsiteTyper.context.withImplicitsEnabled[Tree] _) else (callsiteTyper.context.withImplicitsDisabled[Tree] _) val wrapper2 = if (!withMacrosDisabled) (callsiteTyper.context.withMacrosEnabled[Tree] _) else (callsiteTyper.context.withMacrosDisabled[Tree] _) def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) @@ -21,25 +20,24 @@ trait Typers { // (also see reflect.runtime.ToolBoxes.typeCheckExpr for a workaround that might work for you) wrapper(callsiteTyper.silent(_.typed(tree, mirror.analyzer.EXPRmode, pt)) match { case mirror.analyzer.SilentResultValue(result) => - trace(result) + macroLogVerbose(result) result case error @ mirror.analyzer.SilentTypeError(_) => - trace(error.err.errMsg) + macroLogVerbose(error.err.errMsg) if (!silent) throw new mirror.TypeError(error.err.errPos, error.err.errMsg) mirror.EmptyTree }) } def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { - def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) - trace("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) + macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) import mirror.analyzer.SearchResult val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) wrapper(mirror.analyzer.inferImplicit(mirror.EmptyTree, pt, true, false, context, !silent, pos)) match { case failure if failure.tree.isEmpty => - trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") + macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits") if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) mirror.EmptyTree case success => @@ -48,8 +46,7 @@ trait Typers { } def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree = { - def trace(msg: Any) = if (mirror.settings.Ymacrodebug.value) println(msg) - trace("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) + macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) import mirror.analyzer.SearchResult val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) @@ -58,7 +55,7 @@ trait Typers { val viewTpe = mirror.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) wrapper(mirror.analyzer.inferImplicit(tree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { case failure if failure.tree.isEmpty => - trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits") + macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits") if (context.hasErrors) throw new mirror.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) mirror.EmptyTree case success => diff --git a/src/compiler/scala/reflect/makro/util/Traces.scala b/src/compiler/scala/reflect/makro/util/Traces.scala new file mode 100644 index 0000000000..2363cc4bac --- /dev/null +++ b/src/compiler/scala/reflect/makro/util/Traces.scala @@ -0,0 +1,18 @@ +package scala.reflect.makro +package util + +trait Traces { + def globalSettings: tools.nsc.Settings + + // [Eugene] lots of ways to log: + // 1) trace(...) + // 2) log(...) + // 3) if (foo) { doStuff(); includingSomeLogs(); } + // what is the conventional way of unifying this? + val macroDebugLite = globalSettings.YmacrodebugLite.value + val macroDebugVerbose = globalSettings.YmacrodebugVerbose.value + val macroTraceLite = scala.tools.nsc.util.trace when (macroDebugLite || macroDebugVerbose) + val macroTraceVerbose = scala.tools.nsc.util.trace when macroDebugVerbose + @inline final def macroLogLite(msg: => Any) { if (macroDebugLite || macroDebugVerbose) println(msg) } + @inline final def macroLogVerbose(msg: => Any) { if (macroDebugVerbose) println(msg) } +} \ No newline at end of file diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 1a881455f2..4466f281b8 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -10,8 +10,7 @@ trait Errors { import mirror._ import definitions._ - lazy val defaultErrorPosition: Position = - mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication.pos).getOrElse(NoPosition) + def defaultErrorPosition = analyzer.enclosingMacroPosition // expected errors: these can happen if the user casually writes whatever.reify(...) // hence we don't crash here, but nicely report a typechecking error and bail out asap diff --git a/src/compiler/scala/reflect/reify/codegen/Types.scala b/src/compiler/scala/reflect/reify/codegen/Types.scala index 8fa24c5b00..1f336f4b0f 100644 --- a/src/compiler/scala/reflect/reify/codegen/Types.scala +++ b/src/compiler/scala/reflect/reify/codegen/Types.scala @@ -99,7 +99,7 @@ trait Types { // if this fails, it might produce the dreaded "erroneous or inaccessible type" error // to find out the whereabouts of the error run scalac with -Ydebug if (reifyDebug) println("launching implicit search for %s.%s[%s]".format(prefix, tagClass.name, tpe)) - typer.resolveTypeTag(positionBearer.pos, prefix.tpe, tpe, concrete) match { + typer.resolveTypeTag(defaultErrorPosition, prefix.tpe, tpe, concrete) match { case failure if failure.isEmpty => if (reifyDebug) println("implicit search was fruitless") EmptyTree diff --git a/src/compiler/scala/reflect/reify/codegen/Util.scala b/src/compiler/scala/reflect/reify/codegen/Util.scala index 8d7cf39ff7..bb369a1adb 100644 --- a/src/compiler/scala/reflect/reify/codegen/Util.scala +++ b/src/compiler/scala/reflect/reify/codegen/Util.scala @@ -14,8 +14,6 @@ trait Util { object reifiedNodePrinters extends { val global: mirror.type = mirror } with tools.nsc.ast.NodePrinters with NodePrinters val reifiedNodeToString = reifiedNodePrinters.reifiedNodeToString - val positionBearer = mirror.analyzer.openMacros.find(c => c.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - def reifyList(xs: List[Any]): Tree = mkList(xs map reify) diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index fa11c6313d..3f9d6200cd 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -31,8 +31,12 @@ package object reify { def reifyErasure(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = { import global._ import definitions._ - val positionBearer = analyzer.openMacros.find(_.macroApplication.pos != NoPosition).map(_.macroApplication).getOrElse(EmptyTree).asInstanceOf[Tree] - val inScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(positionBearer.pos, tpe, concrete = concrete), typer0.resolveArrayTag(positionBearer.pos, tpe)) + import analyzer.enclosingMacroPosition + + def erasureTagInScope = typer0.context.withMacrosDisabled(typer0.resolveErasureTag(enclosingMacroPosition, tpe, concrete = concrete)) + def arrayTagInScope = typer0.context.withMacrosDisabled(typer0.resolveArrayTag(enclosingMacroPosition, tpe)) + val inScope = (erasureTagInScope, arrayTagInScope) + inScope match { case (success, _) if !success.isEmpty => Select(success, nme.erasure) @@ -44,7 +48,7 @@ package object reify { val componentErasure = reifyErasure(global)(typer0, componentTpe, concrete) gen.mkMethodCall(arrayClassMethod, List(componentErasure)) } else { - if (tpe.isSpliceable && concrete) throw new ReificationError(positionBearer.pos, "tpe %s is an unresolved spliceable type".format(tpe)) + if (tpe.isSpliceable && concrete) throw new ReificationError(enclosingMacroPosition, "tpe %s is an unresolved spliceable type".format(tpe)) var erasure = tpe.erasure if (tpe.typeSymbol.isDerivedValueClass && global.phase.id < global.currentRun.erasurePhase.id) erasure = tpe gen.mkNullaryCall(Predef_classOf, List(erasure)) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 6a5c4c92bc..91e31cae97 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -138,7 +138,7 @@ trait ScalaSettings extends AbsScalaSettings val termConflict = ChoiceSetting ("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error") val inline = BooleanSetting ("-Yinline", "Perform inlining when possible.") val inlineHandlers = BooleanSetting ("-Yinline-handlers", "Perform exception handler inlining when possible.") - val YinlinerWarnings= BooleanSetting ("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)") + val YinlinerWarnings= BooleanSetting ("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)") val Xlinearizer = ChoiceSetting ("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo") val log = PhasesSetting ("-Ylog", "Log operations during") val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.") @@ -172,7 +172,6 @@ trait ScalaSettings extends AbsScalaSettings val YrichExes = BooleanSetting ("-Yrich-exceptions", "Fancier exceptions. Set source search path with -D" + sys.SystemProperties.traceSourcePath.key) val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") - val Ymacrocopypaste = BooleanSetting ("-Ymacro-copypaste", "Dump macro expansions in copypasteable representation.") val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") @@ -193,7 +192,8 @@ trait ScalaSettings extends AbsScalaSettings val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.") val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.") val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.") - val Ymacrodebug = BooleanSetting("-Ymacro-debug", "Trace macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.") + val YmacrodebugLite = BooleanSetting("-Ymacro-debug-lite", "Trace essential macro-related activities.") + val YmacrodebugVerbose = BooleanSetting("-Ymacro-debug-verbose", "Trace all macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.") val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.") val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.") val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.") diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 14f09d9dc9..1b8a43bf27 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -10,6 +10,7 @@ import scala.compat.Platform.EOL import scala.reflect.makro.runtime.{Context => MacroContext} import scala.reflect.runtime.Mirror import util.Statistics._ +import scala.reflect.makro.util._ /** * Code to deal with macros, namely with: @@ -36,13 +37,12 @@ import util.Statistics._ * (Expr(elems)) * (TypeTag(Int)) */ -trait Macros { self: Analyzer => +trait Macros extends Traces { + self: Analyzer => + import global._ import definitions._ - - val macroDebug = settings.Ymacrodebug.value - val macroCopypaste = settings.Ymacrocopypaste.value - val macroTrace = scala.tools.nsc.util.trace when macroDebug + def globalSettings = global.settings val globalMacroCache = collection.mutable.Map[Any, Any]() val perRunMacroCache = perRunCaches.newMap[Symbol, collection.mutable.Map[Any, Any]] @@ -136,11 +136,11 @@ trait Macros { self: Analyzer => } import SigGenerator._ - macroTrace("generating macroImplSigs for: ")(macroDef) - macroTrace("tparams are: ")(tparams) - macroTrace("vparamss are: ")(vparamss) - macroTrace("retTpe is: ")(retTpe) - macroTrace("macroImplSigs are: ")(paramsss, implRetTpe) + macroTraceVerbose("generating macroImplSigs for: ")(macroDef) + macroTraceVerbose("tparams are: ")(tparams) + macroTraceVerbose("vparamss are: ")(vparamss) + macroTraceVerbose("retTpe is: ")(retTpe) + macroTraceVerbose("macroImplSigs are: ")(paramsss, implRetTpe) } private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Option[Symbol]): List[List[Symbol]] = { @@ -183,7 +183,7 @@ trait Macros { self: Analyzer => */ def typedMacroBody(typer: Typer, ddef: DefDef): Tree = { import typer.context - if (macroDebug) println("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) + macroLogVerbose("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos)) if (!typer.checkFeature(ddef.pos, MacrosFeature, immediate = true)) { ddef.symbol setFlag IS_ERROR @@ -267,7 +267,7 @@ trait Macros { self: Analyzer => val rhs = ddef.rhs validatePreTyper(rhs) - if (hasErrors) macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + if (hasErrors) macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) // we use typed1 instead of typed, because otherwise adapt is going to mess us up // if adapt sees ., it will want to perform eta-expansion and will fail @@ -284,12 +284,7 @@ trait Macros { self: Analyzer => case Success(expanded) => try { val typechecked = typer.typed1(expanded, EXPRmode, WildcardType) - if (macroDebug) { - println("typechecked1:") - println(typechecked) - println(showRaw(typechecked)) - } - + macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked))) typechecked } finally { openMacros = openMacros.tail @@ -312,7 +307,7 @@ trait Macros { self: Analyzer => var rhs1 = typecheckRhs(rhs) def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors hasErrors = hasErrors || typecheckedWithErrors - if (typecheckedWithErrors) macroTrace("body of a macro def failed to typecheck: ")(ddef) + if (typecheckedWithErrors) macroTraceVerbose("body of a macro def failed to typecheck: ")(ddef) val macroImpl = rhs1.symbol macroDef withAnnotation AnnotationInfo(MacroImplAnnotation.tpe, List(rhs1), Nil) @@ -330,7 +325,7 @@ trait Macros { self: Analyzer => validatePostTyper(rhs1) } if (hasErrors) - macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) } if (!hasErrors) { @@ -352,7 +347,7 @@ trait Macros { self: Analyzer => compatibilityError("number of parameter sections differ") def checkSubType(slot: String, reqtpe: Type, acttpe: Type): Unit = { - val ok = if (macroDebug) { + val ok = if (macroDebugVerbose) { if (reqtpe eq acttpe) println(reqtpe + " <: " + acttpe + "?" + EOL + "true") withTypesExplained(reqtpe <:< acttpe) } else reqtpe <:< acttpe @@ -437,7 +432,7 @@ trait Macros { self: Analyzer => val implicitParams = actparamss.flatten filter (_.isImplicit) if (implicitParams.length > 0) { reportError(implicitParams.head.pos, "macro implementations cannot have implicit parameters other than TypeTag evidences") - macroTrace("macro def failed to satisfy trivial preconditions: ")(macroDef) + macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef) } if (!hasErrors) { @@ -458,9 +453,9 @@ trait Macros { self: Analyzer => "\n found : "+showMeth(actparamss, actres, false)+ "\n"+addendum) - macroTrace("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name) + macroTraceVerbose("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name) val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres)) - if (macroDebug) (reqparamsss zip results) foreach { case (reqparamss, result) => + if (macroDebugVerbose) (reqparamsss zip results) foreach { case (reqparamss, result) => println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss)) result foreach (errorMsg => println(" " + errorMsg)) } @@ -472,7 +467,7 @@ trait Macros { self: Analyzer => compatibilityError(mostRelevantMessage) } else { assert((results filter (_.isEmpty)).length == 1, results) - if (macroDebug) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => + if (macroDebugVerbose) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) => println("typechecked macro impl as: " + reqparamss) } } @@ -596,11 +591,11 @@ trait Macros { self: Analyzer => val libraryClassLoader = { if (settings.XmacroPrimaryClasspath.value != "") { - if (macroDebug) println("primary macro mirror: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) + macroLogVerbose("primary macro mirror: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) val classpath = toURLs(settings.XmacroFallbackClasspath.value) ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) } else { - if (macroDebug) println("primary macro mirror: initializing from -cp: %s".format(global.classPath.asURLs)) + macroLogVerbose("primary macro mirror: initializing from -cp: %s".format(global.classPath.asURLs)) val classpath = global.classPath.asURLs var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) @@ -626,7 +621,7 @@ trait Macros { self: Analyzer => throw new UnsupportedOperationException("Scala reflection not available on this platform") val fallbackClassLoader = { - if (macroDebug) println("fallback macro mirror: initializing from -Xmacro-fallback-classpath: %s".format(settings.XmacroFallbackClasspath.value)) + macroLogVerbose("fallback macro mirror: initializing from -Xmacro-fallback-classpath: %s".format(settings.XmacroFallbackClasspath.value)) val classpath = toURLs(settings.XmacroFallbackClasspath.value) ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) } @@ -649,24 +644,24 @@ trait Macros { self: Analyzer => private def macroRuntime(macroDef: Symbol): Option[MacroRuntime] = macroRuntimesCache.getOrElseUpdate(macroDef, { val runtime = { - macroTrace("looking for macro implementation: ")(macroDef) - macroTrace("macroDef is annotated with: ")(macroDef.annotations) + macroTraceVerbose("looking for macro implementation: ")(macroDef) + macroTraceVerbose("macroDef is annotated with: ")(macroDef.annotations) val ann = macroDef.getAnnotation(MacroImplAnnotation) if (ann == None) { - macroTrace("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef) + macroTraceVerbose("@macroImpl annotation is missing (this means that macro definition failed to typecheck)")(macroDef) return None } val macroImpl = ann.get.args(0).symbol if (macroImpl == NoSymbol) { - macroTrace("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef) + macroTraceVerbose("@macroImpl annotation is malformed (this means that macro definition failed to typecheck)")(macroDef) return None } - if (macroDebug) println("resolved implementation %s at %s".format(macroImpl, macroImpl.pos)) + macroLogVerbose("resolved implementation %s at %s".format(macroImpl, macroImpl.pos)) if (macroImpl.isErroneous) { - macroTrace("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef) + macroTraceVerbose("macro implementation is erroneous (this means that either macro body or macro implementation signature failed to typecheck)")(macroDef) return None } @@ -680,14 +675,14 @@ trait Macros { self: Analyzer => // however, the code below doesn't account for these guys, because it'd take a look of time to get it right // for now I leave it as a todo and move along to more the important stuff - macroTrace("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) - macroTrace("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader")) + macroTraceVerbose("loading implementation class from %s: ".format(macroMirror))(macroImpl.owner.fullName) + macroTraceVerbose("classloader is: ")("%s of type %s".format(macroMirror.classLoader, if (macroMirror.classLoader != null) macroMirror.classLoader.getClass.toString else "primordial classloader")) def inferClasspath(cl: ClassLoader) = cl match { case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" case null => "[" + scala.tools.util.PathResolver.Environment.javaBootClassPath + "]" case _ => "" } - macroTrace("classpath is: ")(inferClasspath(macroMirror.classLoader)) + macroTraceVerbose("classpath is: ")(inferClasspath(macroMirror.classLoader)) // [Eugene] relies on the fact that macro implementations can only be defined in static classes // [Martin to Eugene] There's similar logic buried in Symbol#flatname. Maybe we can refactor? @@ -711,7 +706,7 @@ trait Macros { self: Analyzer => val implClassName = classfile(macroImpl.owner) val implClassSymbol: macroMirror.Symbol = macroMirror.symbolForName(implClassName) - if (macroDebug) { + if (macroDebugVerbose) { println("implClassSymbol is: " + implClassSymbol.fullNameString) if (implClassSymbol != macroMirror.NoSymbol) { @@ -723,7 +718,7 @@ trait Macros { self: Analyzer => } val implObjSymbol = implClassSymbol.companionModule - macroTrace("implObjSymbol is: ")(implObjSymbol.fullNameString) + macroTraceVerbose("implObjSymbol is: ")(implObjSymbol.fullNameString) if (implObjSymbol == macroMirror.NoSymbol) None else { @@ -733,29 +728,27 @@ trait Macros { self: Analyzer => val implObjClass = java.lang.Class.forName(implClassName, true, macroMirror.classLoader) implObjClass getField "MODULE$" get null } catch { - case ex: NoSuchFieldException => macroTrace("exception when loading implObj: ")(ex); null - case ex: NoClassDefFoundError => macroTrace("exception when loading implObj: ")(ex); null - case ex: ClassNotFoundException => macroTrace("exception when loading implObj: ")(ex); null + case ex: NoSuchFieldException => macroTraceVerbose("exception when loading implObj: ")(ex); null + case ex: NoClassDefFoundError => macroTraceVerbose("exception when loading implObj: ")(ex); null + case ex: ClassNotFoundException => macroTraceVerbose("exception when loading implObj: ")(ex); null } if (implObj == null) None else { val implMethSymbol = implObjSymbol.info.member(macroMirror.newTermName(macroImpl.name.toString)) - if (macroDebug) { - println("implMethSymbol is: " + implMethSymbol.fullNameString) - println("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) - } + macroLogVerbose("implMethSymbol is: " + implMethSymbol.fullNameString) + macroLogVerbose("jimplMethSymbol is: " + macroMirror.methodToJava(implMethSymbol)) if (implMethSymbol == macroMirror.NoSymbol) None else { - if (macroDebug) println("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) + macroLogVerbose("successfully loaded macro impl as (%s, %s)".format(implObj, implMethSymbol)) Some((implObj, implMethSymbol)) } } } } catch { case ex: ClassNotFoundException => - macroTrace("implementation class failed to load: ")(ex.toString) + macroTraceVerbose("implementation class failed to load: ")(ex.toString) None } } @@ -767,7 +760,7 @@ trait Macros { self: Analyzer => Some(runtime _) case None => if (settings.XmacroFallbackClasspath.value != "") { - if (macroDebug) println("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value)) + macroLogVerbose("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value)) val fallback = loadMacroImpl(fallbackMirror) fallback match { case Some((implObj, implMethSymbol)) => @@ -827,13 +820,13 @@ trait Macros { self: Analyzer => collectMacroArgs(expandee) val context = expandee.attachmentOpt[MacroAttachment].flatMap(_.macroContext).getOrElse(macroContext(typer, prefixTree, expandee)) var argss: List[List[Any]] = List(context) :: exprArgs.toList - macroTrace("argss: ")(argss) + macroTraceVerbose("argss: ")(argss) val ann = macroDef.getAnnotation(MacroImplAnnotation).getOrElse(throw new Error("assertion failed. %s: %s".format(macroDef, macroDef.annotations))) val macroImpl = ann.args(0).symbol var paramss = macroImpl.paramss val tparams = macroImpl.typeParams - macroTrace("paramss: ")(paramss) + macroTraceVerbose("paramss: ")(paramss) // we need to take care of all possible combos of nullary/empty-paramlist macro defs vs nullary/empty-arglist invocations // nullary def + nullary invocation => paramss and argss match, everything is okay @@ -845,7 +838,7 @@ trait Macros { self: Analyzer => val isEmptyParamlistDef = paramss_without_evidences.nonEmpty && paramss_without_evidences.last.isEmpty val isEmptyArglistInvocation = argss.nonEmpty && argss.last.isEmpty if (isEmptyParamlistDef && !isEmptyArglistInvocation) { - if (macroDebug) println("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") + macroLogVerbose("isEmptyParamlistDef && !isEmptyArglistInvocation: appending a List() to argss") argss = argss :+ Nil } @@ -890,7 +883,7 @@ trait Macros { self: Analyzer => macroDef.owner) } else implRefTarg.tpe - if (macroDebug) println("resolved tparam %s as %s".format(tparam, tpe)) + macroLogVerbose("resolved tparam %s as %s".format(tparam, tpe)) resolved(tparam) = tpe param.tpe.typeSymbol match { case definitions.TypeTagClass => @@ -919,7 +912,7 @@ trait Macros { self: Analyzer => else as } val rawArgs = rawArgss.flatten - macroTrace("rawArgs: ")(rawArgs) + macroTraceVerbose("rawArgs: ")(rawArgs) Some(rawArgs) } @@ -927,16 +920,7 @@ trait Macros { self: Analyzer => * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''. */ var openMacros = List[MacroContext]() - private def openMacroPos = openMacros map (_.expandee.pos) find (_ ne NoPosition) getOrElse NoPosition - - // !!! YOu should use a method like this which manages the stack. - // That you presently need to spread this logic out is a major - // design flaw. - private def pushMacroContext[T](mc: MacroContext)(body: => T): T = { - openMacros ::= mc - try body - finally openMacros = openMacros.tail - } + def enclosingMacroPosition = openMacros map (_.macroApplication.pos) find (_ ne NoPosition) getOrElse NoPosition /** Performs macro expansion: * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'') @@ -945,13 +929,13 @@ trait Macros { self: Analyzer => * 4) Checks that the result is a tree bound to this universe * 5) Typechecks the result against the return type of the macro definition * - * If -Ymacro-debug is enabled, you will get detailed log of how exactly this function + * If -Ymacro-debug-lite is enabled, you will get basic notifications about macro expansion + * along with macro expansions logged in the form that can be copy/pasted verbatim into REPL. + * + * If -Ymacro-debug-verbose is enabled, you will get detailed log of how exactly this function * performs class loading and method resolution in order to load the macro implementation. * The log will also include other non-trivial steps of macro expansion. * - * If -Ymacro-copypaste is enabled along with -Ymacro-debug, you will get macro expansions - * logged in the form that can be copy/pasted verbatim into REPL (useful for debugging!). - * * @return * the expansion result if the expansion has been successful, * the fallback method invocation if the expansion has been unsuccessful, but there is a fallback, @@ -963,7 +947,7 @@ trait Macros { self: Analyzer => def macroExpand(typer: Typer, expandee: Tree, mode: Int = EXPRmode, pt: Type = WildcardType): Tree = { def fail(what: String, tree: Tree): Tree = { val err = typer.context.errBuffer.head - this.fail(typer, tree, "failed to perform %s: %s at %s".format(what, err.errMsg, err.errPos)) + this.fail(typer, tree, "failed to %s: %s at %s".format(what, err.errMsg, err.errPos)) return expandee } val start = startTimer(macroExpandNanos) @@ -984,31 +968,23 @@ trait Macros { self: Analyzer => } if (isNullaryInvocation) expectedTpe match { case NullaryMethodType(restpe) => - macroTrace("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + macroTraceVerbose("nullary invocation of a nullary method. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) expectedTpe = restpe case MethodType(Nil, restpe) => - macroTrace("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) + macroTraceVerbose("nullary invocation of a method with an empty parameter list. unwrapping expectedTpe from " + expectedTpe + " to: ")(restpe) expectedTpe = restpe case _ => ; } - if (macroDebug) println("typechecking1 against %s: %s".format(expectedTpe, expanded)) + macroLogVerbose("typechecking1 against %s: %s".format(expectedTpe, expanded)) var typechecked = typer.context.withImplicitsEnabled(typer.typed(expanded, EXPRmode, expectedTpe)) - if (typer.context.hasErrors) fail("typecheck1", expanded) - if (macroDebug) { - println("typechecked1:") - println(typechecked) - println(showRaw(typechecked)) - } + if (typer.context.hasErrors) fail("typecheck against macro def return type", expanded) + macroLogVerbose("typechecked1:%n%s%n%s".format(typechecked, showRaw(typechecked))) - if (macroDebug) println("typechecking2 against %s: %s".format(pt, expanded)) + macroLogVerbose("typechecking2 against %s: %s".format(pt, expanded)) typechecked = typer.context.withImplicitsEnabled(typer.typed(typechecked, EXPRmode, pt)) - if (typer.context.hasErrors) fail("typecheck2", expanded) - if (macroDebug) { - println("typechecked2:") - println(typechecked) - println(showRaw(typechecked)) - } + if (typer.context.hasErrors) fail("typecheck against expected type", expanded) + macroLogVerbose("typechecked2:%n%s%n%s".format(typechecked, showRaw(typechecked))) typechecked } finally { @@ -1033,11 +1009,9 @@ trait Macros { self: Analyzer => private def Cancel(expandee: Tree) = Other(expandee) private def Failure(expandee: Tree) = Other(expandee) private def fail(typer: Typer, expandee: Tree, msg: String = null) = { - if (macroDebug || macroCopypaste) { - var msg1 = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg - if (macroDebug) println("macro expansion has failed: %s".format(msg1)) - } - val pos = if (expandee.pos != NoPosition) expandee.pos else openMacros.find(c => c.expandee.pos != NoPosition).map(_.expandee.pos).getOrElse(NoPosition) + def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg + macroLogVerbose("macro expansion has failed: %s".format(msgForLog)) + val pos = if (expandee.pos != NoPosition) expandee.pos else enclosingMacroPosition if (msg != null) typer.context.error(pos, msg) typer.infer.setError(expandee) Failure(expandee) @@ -1058,7 +1032,7 @@ trait Macros { self: Analyzer => // there is no sense to expand the macro itself => it will only make matters worse if (expandee.symbol.isErroneous || (expandee exists (_.isErroneous))) { val reason = if (expandee.symbol.isErroneous) "incompatible macro implementation" else "erroneous arguments" - macroTrace("cancelled macro expansion because of %s: ".format(reason))(expandee) + macroTraceVerbose("cancelled macro expansion because of %s: ".format(reason))(expandee) return Cancel(typer.infer.setError(expandee)) } @@ -1092,7 +1066,7 @@ trait Macros { self: Analyzer => val wasDelayed = isDelayed(expandee) val undetparams = calculateUndetparams(expandee) val nowDelayed = !typer.context.macrosEnabled || undetparams.nonEmpty - + def failExpansion(msg: String = null) = fail(typer, expandee, msg) def performExpansion(args: List[Any]): MacroExpansionResult = { val numErrors = reporter.ERROR.count @@ -1104,17 +1078,18 @@ trait Macros { self: Analyzer => failExpansion() // errors have been reported by the macro itself else expanded match { case expanded: Expr[_] => - if (macroDebug) println("original:") - macroDebugLog("" + expanded.tree + "\n" + showRaw(expanded.tree)) + macroLogVerbose("original:") + macroLogVerbose("" + expanded.tree + "\n" + showRaw(expanded.tree)) freeTerms(expanded.tree) foreach issueFreeError freeTypes(expanded.tree) foreach issueFreeError + if (hasNewErrors) failExpansion() + // inherit the position from the first position-ful expandee in macro callstack // this is essential for sane error messages // now macro expansion gets typechecked against the macro definition return type // however, this happens in macroExpand, not here in macroExpand1 - if (hasNewErrors) failExpansion() - else Success(atPos(openMacroPos.focus)(expanded.tree)) + else Success(atPos(enclosingMacroPosition.focus)(expanded.tree)) case _ => failExpansion( "macro must return a compiler-specific expr; returned value is " + ( @@ -1130,11 +1105,11 @@ trait Macros { self: Analyzer => else Skip(macroExpandAll(typer, expandee)) } else { - macroDebugLog("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + macroLogVerbose("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) { case args @ ((context: MacroContext) :: _) => if (nowDelayed) { - macroDebugLog("macro expansion is delayed: %s".format(expandee)) + macroLogVerbose("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams // need to save typer context for `macroExpandAll` // need to save macro context to preserve enclosures @@ -1144,7 +1119,9 @@ trait Macros { self: Analyzer => else { // adding stuff to openMacros is easy, but removing it is a nightmare // it needs to be sprinkled over several different code locations - openMacros ::= args.head.asInstanceOf[MacroContext] + // why? https://github.com/scala/scala/commit/bd3eacbae21f39b1ac7fe8ade4ed71fa98e1a28d#L2R1137 + // todo. will be improved + openMacros ::= context var isSuccess = false try performExpansion(args) match { case x: Success => isSuccess = true ; x @@ -1158,7 +1135,7 @@ trait Macros { self: Analyzer => } } } - + try macroExpandInternal catch { case ex => handleMacroExpansionException(typer, expandee, ex) } } @@ -1179,7 +1156,7 @@ trait Macros { self: Analyzer => case first :: _ => Some(Select(qual, name) setPos tree.pos setSymbol first) case _ => - macroTrace("macro is not overridden: ")(tree) + macroTraceVerbose("macro is not overridden: ")(tree) notFound() } case Apply(fn, args) => @@ -1193,33 +1170,29 @@ trait Macros { self: Analyzer => case _ => None } case _ => - macroTrace("unexpected tree in fallback: ")(tree) + macroTraceVerbose("unexpected tree in fallback: ")(tree) notFound() } } fallBackToOverridden(expandee) match { case Some(tree1) => - macroTrace("falling back to: ")(tree1) + macroTraceVerbose("falling back to: ")(tree1) currentRun.macroExpansionFailed = true Fallback(tree1) case None => fail(typer, expandee) } } - - @inline final def macroDebugLog(msg: => String) { - if (macroDebug || macroCopypaste) println(msg) - } - private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { + private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = { // [Eugene] any ideas about how to improve this one? val realex = ReflectionUtils.unwrapThrowable(ex) realex match { case realex: reflect.makro.runtime.AbortMacroException => - macroDebugLog("macro expansion has failed: %s".format(realex.msg)) + macroLogVerbose("macro expansion has failed: %s".format(realex.msg)) fail(typer, expandee) // error has been reported by abort case err: TypeError => - macroDebugLog("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + macroLogVerbose("macro expansion has failed: %s at %s".format(err.msg, err.pos)) throw err // error should be propagated, don't report case _ => val message = { @@ -1271,24 +1244,24 @@ trait Macros { self: Analyzer => if (sub.symbol != null) traverse(sub.symbol) if (sub.tpe != null) sub.tpe foreach (sub => traverse(sub.typeSymbol)) }) - if (macroDebug) println("calculateUndetparams: %s".format(calculated)) + macroLogVerbose("calculateUndetparams: %s".format(calculated)) calculated map (_.id) } private val undetparams = perRunCaches.newSet[Int] def notifyUndetparamsAdded(newUndets: List[Symbol]): Unit = { undetparams ++= newUndets map (_.id) - if (macroDebug) newUndets foreach (sym => println("undetParam added: %s".format(sym))) + if (macroDebugVerbose) newUndets foreach (sym => println("undetParam added: %s".format(sym))) } def notifyUndetparamsInferred(undetNoMore: List[Symbol], inferreds: List[Type]): Unit = { undetparams --= undetNoMore map (_.id) - if (macroDebug) (undetNoMore zip inferreds) foreach {case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} + if (macroDebugVerbose) (undetNoMore zip inferreds) foreach { case (sym, tpe) => println("undetParam inferred: %s as %s".format(sym, tpe))} if (!delayed.isEmpty) delayed.toList foreach { case (expandee, undetparams) if !undetparams.isEmpty => undetparams --= undetNoMore map (_.id) if (undetparams.isEmpty) { hasPendingMacroExpansions = true - macroTrace("macro expansion is pending: ")(expandee) + macroTraceVerbose("macro expansion is pending: ")(expandee) } case _ => // do nothing diff --git a/src/library/scala/reflect/makro/Typers.scala b/src/library/scala/reflect/makro/Typers.scala index 1ced2daccd..c62c5f254c 100644 --- a/src/library/scala/reflect/makro/Typers.scala +++ b/src/library/scala/reflect/makro/Typers.scala @@ -29,7 +29,7 @@ trait Typers { * * If ``silent'' is false, ``TypeError'' will be thrown in case of a typecheck error. * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. - * Such errors don't vanish and can be inspected by turning on -Ymacro-debug. + * Such errors don't vanish and can be inspected by turning on -Ymacro-debug-verbose. * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default. * * Typechecking can be steered with the following optional parameters: -- cgit v1.2.3 From efd1293df967a10211ca877130f97955be94dc30 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 26 Apr 2012 15:29:07 +0200 Subject: SI-5690: no-selector match in function yields function the implicit beta-reduction performed by typedFunction on a Function(.., Match(EmptyTree, ...)) must of course only be done when the selector actually is empty... (yes, typedMatchAnonFun needs to be cleaned up, I know) --- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 +- test/files/pos/virtpatmat_partialfun_nsdnho.scala | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/files/pos/virtpatmat_partialfun_nsdnho.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 934a7567d5..e4c3dcfa55 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2439,7 +2439,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser fun.body match { // later phase indicates scaladoc is calling (where shit is messed up, I tell you) // -- so fall back to old patmat, which is more forgiving - case Match(sel, cases) if doMatchTranslation => + case Match(sel, cases) if (sel ne EmptyTree) && doMatchTranslation => // go to outer context -- must discard the context that was created for the Function since we're discarding the function // thus, its symbol, which serves as the current context.owner, is not the right owner // you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner) diff --git a/test/files/pos/virtpatmat_partialfun_nsdnho.scala b/test/files/pos/virtpatmat_partialfun_nsdnho.scala new file mode 100644 index 0000000000..f79e82813c --- /dev/null +++ b/test/files/pos/virtpatmat_partialfun_nsdnho.scala @@ -0,0 +1,18 @@ +class Test { + // m.$minus(1) + // at scala.Predef$.assert(Predef.scala:185) + // at scala.tools.nsc.Global.assert(Global.scala:187) + // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.transform(SuperAccessors.scala:291) + val a: (Map[Int, Int] => (Any => Any)) = { m => { case _ => m - 1} } + + // patmat-crash.scala:9: error: erroneous or inaccessible type + val b: (Int => (Any => Any)) = { m => { case _ => m } } + + // no-symbol does not have an owner (this is a bug: scala version 2.10.0-20120420-170445-56c1f29250) + // at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:45) + // at scala.tools.nsc.Global.abort(Global.scala:202) + // at scala.reflect.internal.Symbols$NoSymbol.owner(Symbols.scala:3031) + // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.hostForAccessorOf(SuperAccessors.scala:474) + // at scala.tools.nsc.typechecker.SuperAccessors$SuperAccTransformer.needsProtectedAccessor(SuperAccessors.scala:457) + val c: (Int => (Any => Any)) = { m => { case _ => m.toInt } } +} \ No newline at end of file -- cgit v1.2.3 From 17165269e22f8e4b60483d1277eb841131c3686d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 26 Apr 2012 17:08:05 +0200 Subject: clean up typedMatchAnonFun --- .../scala/tools/nsc/typechecker/Typers.scala | 90 ++++++++++++---------- 1 file changed, 51 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e4c3dcfa55..6234c05258 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2249,43 +2249,35 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } } - def typedMatchAnonFun(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type, selOverride: Option[(List[ValDef], Tree)] = None) = { - val pt = deskolemizeGADTSkolems(pt0) - val targs = pt.normalize.typeArgs - val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right? - val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined + // synthesize and type check a (Partial)Function implementation based on a match specified by `cases` + // Match(EmptyTree, cases) ==> new Function { def apply(params) = `translateMatch('`(param1,...,paramN)` match { cases }')` } + // for fresh params, the selector of the match we'll translated simply gathers those in a tuple + class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Int, pt0: Type) { + private val pt = deskolemizeGADTSkolems(pt0) + private val targs = pt.normalize.typeArgs + private val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right? + private val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined - val isPartial = pt.typeSymbol == PartialFunctionClass - val anonClass = context.owner.newAnonymousFunctionClass(tree.pos) - val funThis = This(anonClass) - val serialVersionUIDAnnotation = AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List()) + private val isPartial = pt.typeSymbol == PartialFunctionClass + private val anonClass = context.owner.newAnonymousFunctionClass(tree.pos) + private val funThis = This(anonClass) - anonClass addAnnotation serialVersionUIDAnnotation + anonClass addAnnotation AnnotationInfo(SerialVersionUIDAttr.tpe, List(Literal(Constant(0))), List()) def deriveFormals = - selOverride match { - case None if targs.isEmpty => Nil - case None => targs.init // is there anything we can do if targs.isEmpty?? - case Some((vparams, _)) => - vparams map {p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe} - } + if (targs.isEmpty) Nil + else targs.init - def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = { - selOverride match { - case None if targs.isEmpty => MissingParameterTypeAnonMatchError(tree, pt); (Nil, EmptyTree) - case None => - val ps = methodSym newSyntheticValueParams formals // is there anything we can do if targs.isEmpty?? - val ids = ps map (p => Ident(p.name)) - val sel = atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) } - (ps, sel) - case Some((vparams, sel)) => - val newParamSyms = (vparams, formals).zipped map {(p, tp) => - methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp - } + def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = + if (formals.isEmpty) { MissingParameterTypeAnonMatchError(tree, pt); Nil } + else methodSym newSyntheticValueParams formals - (newParamSyms, sel.duplicate) + def mkSel(params: List[Symbol]) = + if (params.isEmpty) EmptyTree + else { + val ids = params map (p => Ident(p.name)) + atPos(tree.pos.focusStart) { if (arity == 1) ids.head else gen.mkTuple(ids) } } - } import CODE._ @@ -2298,7 +2290,8 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser // rig the show so we can get started typing the method body -- later we'll correct the infos... anonClass setInfo ClassInfoType(List(ObjectClass.tpe, pt, SerializableClass.tpe), newScope, anonClass) val methodSym = anonClass.newMethod(nme.apply, tree.pos, if(isPartial) (FINAL | OVERRIDE) else FINAL) - val (paramSyms, selector) = mkParams(methodSym) + val paramSyms = mkParams(methodSym) + val selector = mkSel(paramSyms) if (selector eq EmptyTree) EmptyTree else { @@ -2329,9 +2322,10 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser val methodSym = anonClass.newMethod(nme.applyOrElse, tree.pos, FINAL | OVERRIDE) // create the parameter that corresponds to the function's parameter - val List(argTp) = deriveFormals - val A1 = methodSym newTypeParameter(newTypeName("A1")) setInfo TypeBounds.upper(argTp) - val (List(x), selector) = mkParams(methodSym, List(A1.tpe)) + val List(argTp) = deriveFormals + val A1 = methodSym newTypeParameter(newTypeName("A1")) setInfo TypeBounds.upper(argTp) + val paramSyms@List(x) = mkParams(methodSym, List(A1.tpe)) + val selector = mkSel(paramSyms) if (selector eq EmptyTree) EmptyTree else { @@ -2362,7 +2356,9 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser def isDefinedAtMethod = { val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos, FINAL) - val (paramSyms, selector) = mkParams(methodSym) + val paramSyms = mkParams(methodSym) + val selector = mkSel(paramSyms) + if (selector eq EmptyTree) EmptyTree else { val methodBodyTyper = newTyper(context.makeNewScope(context.tree, methodSym)) // should use the DefDef for the context's tree, but it doesn't exist yet (we need the typer we're creating to create it) @@ -2382,8 +2378,23 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser else List(applyOrElseMethodDef, isDefinedAtMethod) } else List(applyMethod) - if (members.head eq EmptyTree) setError(tree) - else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt) + def translated = + if (members.head eq EmptyTree) setError(tree) + else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt) + } + + // Function(params, Match(sel, cases)) ==> new Function { def apply(params) = `translateMatch('sel match { cases }')` } + class MatchFunTyperBetaReduced(fun: Function, sel: Tree, cases: List[CaseDef], mode: Int, pt: Type) extends MatchFunTyper(fun, cases, mode, pt) { + override def deriveFormals = + fun.vparams map { p => if(p.tpt.tpe == null) typedType(p.tpt).tpe else p.tpt.tpe } + + // the only difference from the super class is that we must preserve the names of the parameters + override def mkParams(methodSym: Symbol, formals: List[Type] = deriveFormals) = + (fun.vparams, formals).zipped map { (p, tp) => + methodSym.newValueParameter(p.name, p.pos.focus, SYNTHETIC) setInfo tp + } + + override def mkSel(params: List[Symbol]) = sel.duplicate } /** @@ -2443,7 +2454,8 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser // go to outer context -- must discard the context that was created for the Function since we're discarding the function // thus, its symbol, which serves as the current context.owner, is not the right owner // you won't know you're using the wrong owner until lambda lift crashes (unless you know better than to use the wrong owner) - newTyper(context.outer).typedMatchAnonFun(fun, cases, mode, pt, Some((fun.vparams, sel))) + val outerTyper = newTyper(context.outer) + (new outerTyper.MatchFunTyperBetaReduced(fun, sel, cases, mode, pt)).translated case _ => val vparamSyms = fun.vparams map { vparam => enterSym(context, vparam) @@ -3835,7 +3847,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser if (selector ne EmptyTree) { val (selector1, selectorTp, casesAdapted, ownType, doTranslation) = typedMatch(selector, cases, mode, pt) typed(translatedMatch(selector1, selectorTp, casesAdapted, ownType, doTranslation), mode, pt) - } else typedMatchAnonFun(tree, cases, mode, pt) + } else (new MatchFunTyper(tree, cases, mode, pt)).translated } else if (selector == EmptyTree) { if (opt.virtPatmat) debugwarn("virtpatmat should not encounter empty-selector matches "+ tree) val arity = if (isFunctionType(pt)) pt.normalize.typeArgs.length - 1 else 1 -- cgit v1.2.3 From 2aa44c230c96b0ceb8e2b84c8095620a1be5a77f Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 26 Apr 2012 07:02:55 -0700 Subject: A brand new, fast classfile parser. Try it: ./tools/dump-class ./build/quick/classes The output is intended to be easy to filter on the command line. This is a starting point for lots of interesting bytecode analysis for which we have waited too long. Example. All generic signatures we produce. // almost 20K classfiles % find build/quick/classes -name '*.class' |wc -l 18519 // fully parsed in 6 seconds tools/dump-class build/quick/classes |grep "^ signature" | wc -l 50802 real 0m6.230s It's designed to be easy to make faster if you don't care about particular classfile bits; you can override those methods to jump forward in the input stream rather than building a structure. For just a little sampling, here are our most frequently repeated name/signature combinations. 194 signature ()V // this one is weird, wonder why there's a generic signature 115 signature $div$colon$bslash (TA1;Lscala/Function2;)TA1; 105 signature applyOrElse (TA1;Lscala/Function1;)TB1; 103 signature view ()Ljava/lang/Object; 101 signature toSet ()Lscala/collection/immutable/Set; And the top five name/descriptor combinations. 11170 descriptor ()V 10155 descriptor serialVersionUID J 7130 descriptor apply (Ljava/lang/Object;)Ljava/lang/Object; 3028 descriptor apply ()Ljava/lang/Object; 2426 descriptor ()V --- .../scala/reflect/internal/JvmClassInfo.scala | 440 +++++++++++++++++++++ .../scala/tools/cmd/program/DumpClass.scala | 40 ++ src/compiler/scala/tools/util/StringOps.scala | 10 + test/files/run/inner-parse.check | 86 ++++ test/files/run/inner-parse/J_1.java | 9 + test/files/run/inner-parse/S_2.scala | 9 + test/files/run/inner-parse/S_3.scala | 12 + tools/dump-class | 6 + 8 files changed, 612 insertions(+) create mode 100644 src/compiler/scala/reflect/internal/JvmClassInfo.scala create mode 100644 src/compiler/scala/tools/cmd/program/DumpClass.scala create mode 100644 test/files/run/inner-parse.check create mode 100644 test/files/run/inner-parse/J_1.java create mode 100644 test/files/run/inner-parse/S_2.scala create mode 100644 test/files/run/inner-parse/S_3.scala create mode 100755 tools/dump-class (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/JvmClassInfo.scala b/src/compiler/scala/reflect/internal/JvmClassInfo.scala new file mode 100644 index 0000000000..d47f51e512 --- /dev/null +++ b/src/compiler/scala/reflect/internal/JvmClassInfo.scala @@ -0,0 +1,440 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.reflect.internal + +import java.io.{ DataInput, InputStream, DataInputStream, ByteArrayInputStream, BufferedInputStream, FileInputStream } +import scala.tools.nsc.io.{ Directory } +import scala.reflect.NameTransformer.decode +import scala.tools.util.StringOps.trimTrailingSpace +import ConstantPool._ + +final case class JvmVersion(minorVersion: Int, majorVersion: Int) + +trait ClassfileModel { + type Result + type Entry + type InterfaceInfo + type MemberInfo + type AttributeInfo + type InnerClassInfo + + protected implicit def EntryArrayTag: ArrayTag[Entry] + protected implicit def InterfaceInfoArrayTag: ArrayTag[InterfaceInfo] + protected implicit def MemberInfoArrayTag: ArrayTag[MemberInfo] + protected implicit def AttributeInfoArrayTag: ArrayTag[AttributeInfo] + protected implicit def InnerClassInfoArrayTag: ArrayTag[InnerClassInfo] + + // These could be implemented to jump forward in the stream if the + // result is not wanted. + def readConstantPoolEntry(): Entry + def readInterface(): InterfaceInfo + def readMember(): MemberInfo + def readAttribute(): AttributeInfo + def readInnerClass(): InnerClassInfo + + def createInfo( + version: JvmVersion, + entries: Array[Entry], + flags: Int, + name: String, + superName: String, + interfaces: Array[InterfaceInfo], + fields: Array[MemberInfo], + methods: Array[MemberInfo], + attributes: Array[AttributeInfo] + ): Result +} + +abstract class StreamingClassfileModel extends ClassfileModel { + protected[this] val in: DataInput + private[this] var name: String = _ + private[this] var entries: Array[PoolEntry] = _ + + type Entry = PoolEntry + + // These translate null into "", it's less troublesome. + protected def nameAt(idx: Int) = entries(idx) match { + case x: Name_Info => stringAt(x.name_index).replace('/', '.') + case _ => "" + } + protected def stringAt(idx: Int) = entries(idx) match { + case x: Utf8_info => x.stringValue + case _ => "" + } + + protected def u4 = in.readInt + protected def u2 = in.readUnsignedShort.toChar + protected def u1 = in.readUnsignedByte + + // The constant_pool table is indexed from 1 to constant_pool_count−1. + protected def readConstantPool(): Array[Entry] = { + val count = u2 + val entries = new Array[Entry](count) + var i = 1 + while (i < count) { + val entry = readConstantPoolEntry() + entries(i) = entry + i += entry.width + } + entries + } + protected def readInterfaces() = { + val count = u2 + val interfaces = new Array[InterfaceInfo](count) + var i = 0 + while (i < count) { + interfaces(i) = readInterface() + i += 1 + } + interfaces + } + protected def readMembers() = { + val count = u2 + val arr = new Array[MemberInfo](count) + var i = 0 + while (i < count) { + arr(i) = readMember() + i += 1 + } + arr + } + protected def readAttributes(): Array[AttributeInfo] = { + val count = u2 + val arr = new Array[AttributeInfo](count) + var i = 0 + while (i < count) { + arr(i) = readAttribute() + i += 1 + } + arr + } + protected def readInnerClasses() = { + val count = u2 + val arr = new Array[InnerClassInfo](count) + var i = 0 + while (i < count) { + arr(i) = readInnerClass() + i += 1 + } + arr + } + protected def thisClass = name + + def parse() = { + assert(u4 == 0xCAFEBABE, "Bad magic number") + val version = JvmVersion(u2, u2) + this.entries = readConstantPool() + val flags = u2.toShort + this.name = nameAt(u2) + val superName = nameAt(u2) + val interfaces = readInterfaces() + val fields = readMembers() + val methods = readMembers() + val attributes = readAttributes() + + try createInfo(version, entries, flags, name, superName, interfaces, fields, methods, attributes) + finally entries = null + } +} + +abstract class ScalacClassfileModel extends StreamingClassfileModel { + type Result = JvmClassInfo + type InterfaceInfo = String + type MemberInfo = JvmMemberInfo + type AttributeInfo = JvmAttributeInfo + type InnerClassInfo = JvmInnerClassInfo + + protected implicit def EntryArrayTag = arrayTag[PoolEntry] + protected implicit def InterfaceInfoArrayTag = arrayTag[InterfaceInfo] + protected implicit def MemberInfoArrayTag = arrayTag[MemberInfo] + protected implicit def AttributeInfoArrayTag = arrayTag[AttributeInfo] + protected implicit def InnerClassInfoArrayTag = arrayTag[InnerClassInfo] + + def readConstantPoolEntry(): PoolEntry + def readInterface(): String + def readMember(): JvmMemberInfo + def readAttribute(): JvmAttributeInfo + def readInnerClass(): JvmInnerClassInfo + + def createInfo( + version: JvmVersion, + entries: Array[PoolEntry], + flags: Int, + name: String, + superName: String, + interfaces: Array[String], + fields: Array[JvmMemberInfo], + methods: Array[JvmMemberInfo], + attributes: Array[JvmAttributeInfo] + ): JvmClassInfo = new JvmClassInfo(name, superName, interfaces, fields, methods, attributes) +} + +class JvmClassInfoBuilder(protected[this] val in: DataInput) extends ScalacClassfileModel { + def readInterface(): InterfaceInfo = nameAt(u2) + def readMember(): JvmMemberInfo = new JvmMemberInfo(u2.toShort, stringAt(u2), stringAt(u2), readAttributes()) + def readInnerClass(): JvmInnerClassInfo = new JvmInnerClassInfo(thisClass, nameAt(u2), nameAt(u2), stringAt(u2), u2.toShort) + + def readConstantPoolEntry(): Entry = (u1: @annotation.switch) match { + case CONSTANT_Utf8 => new Utf8_info(in.readUTF) + case CONSTANT_Integer => new Integer_info(in.readInt) + case CONSTANT_Float => new Float_info(in.readFloat) + case CONSTANT_Long => new Long_info(in.readLong) + case CONSTANT_Double => new Double_info(in.readDouble) + case CONSTANT_Class => new Class_info(u2) + case CONSTANT_String => new String_info(u2) + case CONSTANT_Fieldref => new Fieldref_info(u2, u2) + case CONSTANT_Methodref => new Methodref_info(u2, u2) + case CONSTANT_InterfaceMethodref => new InterfaceMethodref_info(u2, u2) + case CONSTANT_NameAndType => new NameAndType_info(u2, u2) + } + + // field_info attributes: + // ConstantValue (§4.7.2), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15), + // RuntimeVisibleAnnotations (§4.7.16) and RuntimeInvisibleAnnotations (§4.7.17). + // + // method_info attributes: + // Code (§4.7.3), Exceptions (§4.7.5), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15), + // RuntimeVisibleAnnotations (§4.7.16), RuntimeInvisibleAnnotations (§4.7.17), RuntimeVisibleParameterAnnotations (§4.7.18), + // RuntimeInvisibleParameterAnnotations (§4.7.19) and AnnotationDefault (§4.7.20). + + def readAttribute(): AttributeInfo = stringAt(u2) match { + case "Signature" => u4 ; new SignatureAttr(stringAt(u2)) + case "InnerClasses" => u4 ; new InnerClassesAttr(readInnerClasses()) + case name => val bytes = new Array[Byte](u4) ; in.readFully(bytes) ; new GenericAttr(name, bytes) + } +} + +object Classify { + + /* + + + 4.2.2 Unqualified Names + +Names of methods, fields and local variables are stored as unqualified +names. Unqualified names must not contain the characters '.', ';', '[' +or '/'. Method names are further constrained so that, with the exception +of the special method names and (§3.9), they must not +contain the characters '<' or '>'. + + 4.3 Descriptors and Signatures + +A descriptor is a string representing the type of a field or method. +Descriptors are represented in the class file format using modified +UTF-8 strings (§4.4.7) and thus may be drawn, where not further +constrained, from the entire Unicode character set. A signature is a +string representing the generic type of a field or method, or generic +type information for a class declaration. +*/ + +} + +object ConstantPool { + type UShort = Char + + final val CONSTANT_Utf8 = 1 + final val CONSTANT_Integer = 3 + final val CONSTANT_Float = 4 + final val CONSTANT_Long = 5 + final val CONSTANT_Double = 6 + final val CONSTANT_Class = 7 + final val CONSTANT_String = 8 + final val CONSTANT_Fieldref = 9 + final val CONSTANT_Methodref = 10 + final val CONSTANT_InterfaceMethodref = 11 + final val CONSTANT_NameAndType = 12 + + abstract class Name_Info(tag: Byte) extends PoolEntry(tag) { + def name_index: UShort + } + abstract class Ref_Info(tag: Byte) extends PoolEntry(tag) { + def class_index: UShort + def name_and_type_index: UShort + } + class Class_info(val name_index: UShort) extends Name_Info(CONSTANT_Class) { } + class Double_info(val value: Double) extends PoolEntry(CONSTANT_Double) { + override def width = 2 + } + class Fieldref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_Fieldref) + class Float_info(val value: Float) extends PoolEntry(CONSTANT_Float) + class Integer_info(val value: Int) extends PoolEntry(CONSTANT_Integer) + class InterfaceMethodref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_InterfaceMethodref) + class Long_info(val value: Long) extends PoolEntry(CONSTANT_Long) { + override def width = 2 + } + class Methodref_info(val class_index: UShort, val name_and_type_index: UShort) extends Ref_Info(CONSTANT_Methodref) + class NameAndType_info(val name_index: UShort, val descriptor_index: UShort) extends Name_Info(CONSTANT_NameAndType) { + override def toString = "NameAndType #%s:#%s;".format(name_index, descriptor_index) + } + class String_info(val string_index: UShort) extends PoolEntry(CONSTANT_String) { } + class Utf8_info(override val stringValue: String) extends PoolEntry(CONSTANT_Utf8) { + override def toString = ("Asciz " + stringValue).trim + } + + abstract class PoolEntry(tag: Byte) { + def width = 1 + def stringValue: String = sys.error("Not a String-valued constant pool entry: " + this) + override def toString = ( + getClass.getName.split("[.$]").last + "/" + tag + ) + } + object NoEntry extends PoolEntry(-1) { } +} + +abstract class JvmInfo(attributes: Array[JvmAttributeInfo]) { + // def flags: Short + def name: String + + val signature = attributes collectFirst { case x: SignatureAttr => x.value } getOrElse "" + val innerClasses = attributes collectFirst { case x: InnerClassesAttr => x.value } getOrElse Array() +} + + +class JvmClassInfo( + val name: String, + val superName: String, + val interfaces: Array[String], + val fields: Array[JvmMemberInfo], + val methods: Array[JvmMemberInfo], + attributes: Array[JvmAttributeInfo] +) extends JvmInfo(attributes) { + + def members = fields ++ methods sortBy (_.decodedName) + def memberDescriptors = members map (_.toErasedString) + def memberSignatures = members filter (_.hasSignature) map (_.toGenericString) + def descriptorsString = if (memberDescriptors.nonEmpty) memberDescriptors.mkString("\n-- Member Descriptors --\n", "\n", "\n") else "" + def signaturesString = if (memberSignatures.nonEmpty) memberSignatures.mkString("\n-- Member Signatures --\n", "\n", "\n") else "" + def innersString = if (innerClasses.isEmpty) "" else innerClasses.mkString("\n-- Inner Classes --\n", "\n", "\n") + def membersString = descriptorsString + signaturesString + def extendsString = if (superName == "") "" else " extends " + superName + def implementsString = if (interfaces.isEmpty) "" else interfaces.mkString("Implements: ", ", ", "") + + private def group(label: String, xs: Traversable[(String, String)]) = + xs map { case (name, value) => line(label, name, value) } mkString "\n" + + private def line(label: String, name: String, data: String) = + trimTrailingSpace(" %-15s %30s %s".format(label, name, data)) + + override def toString = ( + List( + "class " + name + extendsString, + if (signature == "") "" else line("class sig", "", signature), + group("interface", interfaces map (x => (("", x)))), + (innerClasses map (ic => line(ic.kind, ic.innerName, ic.nestString))).sorted.mkString("\n"), + group("descriptor", members map (x => (x.name, x.descriptor))), + group("signature", members filter (_.hasSignature) map (x => (x.name, x.signature))) + ) map trimTrailingSpace filterNot (_ == "") mkString ("", "\n", "\n") + ) +} + +// method_info or field_info { +// u2 access_flags; +// u2 name_index; +// u2 descriptor_index; +// u2 attributes_count; +// attribute_info attributes[attributes_count]; +// } +class JvmMemberInfo( + val flags: Short, + val name: String, + val descriptor: String, + attributes: Array[JvmAttributeInfo] +) extends JvmInfo(attributes) { + def decodedName = decode(name) + def hasSignature = signature != "" + def toErasedString = "%-30s %s".format(decodedName, descriptor) + def toGenericString = "%-30s %s".format(decodedName, signature) + + override def toString = ( + if (hasSignature) toGenericString else toErasedString + ) +} + +abstract class JvmAttributeInfo { + def name: String + def value: Any +} +class GenericAttr(val name: String, val value: Array[Byte]) extends JvmAttributeInfo { + // attribute_info { + // u2 attribute_name_index; + // u4 attribute_length; + // u1 info[attribute_length]; + // } +} +class SignatureAttr(val value: String) extends JvmAttributeInfo { + def name = "Signature" +} +class InnerClassesAttr(val value: Array[JvmInnerClassInfo]) extends JvmAttributeInfo { + def name = "InnerClasses" +} + +// package foo { class Foo { class Bar } } +// +// javap would say +// Bar = class foo.Foo$Bar of class foo.Foo +// which is translated as +// innerClass = foo.Foo$Bar +// outerClass = foo.Foo +// innerName = Bar + +class JvmInnerClassInfo( + thisClass: String, // classfile which is being parsed + val innerClass: String, // the full name of the inner/nested class + val outerClass: String, // the full name of the outer class - must be a prefix of innerClass + val innerName: String, // the simple name of the inner class - should (?) be a suffix of innerClass + val flags: Short // flags +) { + val isEntryOfEnclosingClass = !isAnonymousClass && (innerClass == thisClass) + val isEntryOfNestedClass = !isAnonymousClass && (outerClass == thisClass) + + def isTopLevelClass = outerClass == "" + def isAnonymousClass = innerName == "" + def isMemberClass = !isTopLevelClass + + def kind = ( + if (isEntryOfEnclosingClass) "inner/enclosing" + else if (isEntryOfNestedClass) "inner/nested" + else if (isAnonymousClass) "inner/anon" + else "inner" + ) + def nestString = ( + if (isEntryOfEnclosingClass) "enclosing class: " + outerClass + else if (isEntryOfNestedClass) "member class: " + innerClass + else if (isAnonymousClass) "anonymous class: " + innerClass + else innerClass + " in " + outerClass + ) + override def toString = innerName + "=" + nestString +} + +object JvmClassInfo { + private def classFiles(path: String) = + Directory(path).deepFiles filter (_ hasExtension "class") + + def classInfoMap(path: String): Map[String, JvmClassInfo] = { + classFiles(path) map (f => (f.path, JvmClassInfo fromFile f.jfile)) toMap + } + def classInfoList(path: String): List[(String, JvmClassInfo)] = { + classInfoMap(path).toList sortBy (_._1) + } + + def fromFile(file: java.io.File) = + fromStream(new BufferedInputStream(new FileInputStream(file))) + + def fromBytes(bytes: Array[Byte]) = + fromStream(new ByteArrayInputStream(bytes)) + + def fromPath(path: String) = + fromStream(new BufferedInputStream(new FileInputStream(path))) + + def fromStream(in0: InputStream) = { + val in = new DataInputStream(in0) + try fromDataInput(in) finally in.close() + } + + def fromDataInput(in: DataInput): JvmClassInfo = { + new JvmClassInfoBuilder(in) parse + } +} diff --git a/src/compiler/scala/tools/cmd/program/DumpClass.scala b/src/compiler/scala/tools/cmd/program/DumpClass.scala new file mode 100644 index 0000000000..a583f1d3ea --- /dev/null +++ b/src/compiler/scala/tools/cmd/program/DumpClass.scala @@ -0,0 +1,40 @@ +/* NEST (New Scala Test) + * Copyright 2007-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools +package cmd +package program + +import scala.reflect.internal.JvmClassInfo +import scala.tools.nsc.io.Directory + +object DumpClass { + private val usage = """ + |Usage: dump-class [options] ... + | + |Parses and dumps the bytecode of all classes found at the given paths. + |""".stripMargin + + private val unaryOps = List( + "signatures" -> "dump signatures" + ) + private val info = Simple.scalaProgramInfo("dump-class", usage) + private val spec = Simple(info, unaryOps, Nil, null) + + def deepInfos(dir: String) = { + val files = Directory(dir).deepFiles.toList filter (_ hasExtension "class") + files.sortBy(_.path) map (f => (f.path, JvmClassInfo fromPath f.path)) + } + + def main(args: Array[String]): Unit = { + val runner = spec instance args + import runner._ + + if (args.isEmpty) + println(usage) + else + (residualArgs flatMap deepInfos) sortBy (_._1) map (_._2) foreach println + } +} diff --git a/src/compiler/scala/tools/util/StringOps.scala b/src/compiler/scala/tools/util/StringOps.scala index 02eb364abe..725e0afb79 100644 --- a/src/compiler/scala/tools/util/StringOps.scala +++ b/src/compiler/scala/tools/util/StringOps.scala @@ -25,6 +25,16 @@ trait StringOps { val ys = oempty(xs: _*) if (ys.isEmpty) orElse else ys mkString sep } + def trimTrailingSpace(s: String) = { + if (s.length == 0 || !s.charAt(s.length - 1).isWhitespace) s + else { + var idx = s.length - 1 + while (idx >= 0 && s.charAt(idx).isWhitespace) + idx -= 1 + + s.substring(0, idx + 1) + } + } def decompose(str: String, sep: Char): List[String] = { def ws(start: Int): List[String] = diff --git a/test/files/run/inner-parse.check b/test/files/run/inner-parse.check new file mode 100644 index 0000000000..87ea9ddeb5 --- /dev/null +++ b/test/files/run/inner-parse.check @@ -0,0 +1,86 @@ +file Test$$anonfun$main$1.class +class Test$$anonfun$main$1 extends scala.runtime.AbstractFunction1$mcVL$sp + interface scala.Serializable + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor ()V + descriptor apply (Lscala/Tuple2;)V + descriptor apply (Ljava/lang/Object;)Ljava/lang/Object; + descriptor cwd$1 Ljava/lang/String; + descriptor serialVersionUID J + descriptor (Ljava/lang/String;)V + signature apply (Lscala/Tuple2;)V + +file Test$.class +class Test$ extends java.lang.Object + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor ()V + descriptor MODULE$ LTest$; + descriptor main ([Ljava/lang/String;)V + descriptor ()V + +file Test.class +class Test extends java.lang.Object + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor main ([Ljava/lang/String;)V + +file j/J_1$B$C$D.class +class j.J_1$B$C$D extends java.lang.Object + inner B j.J_1$B in j.J_1 + inner C j.J_1$B$C in j.J_1$B + inner/enclosing D enclosing class: j.J_1$B$C + descriptor (Lj/J_1$B$C;)V + descriptor this$2 Lj/J_1$B$C; + +file j/J_1$B$C.class +class j.J_1$B$C extends java.lang.Object + inner B j.J_1$B in j.J_1 + inner/enclosing C enclosing class: j.J_1$B + inner/nested D member class: j.J_1$B$C$D + descriptor (Lj/J_1$B;)V + descriptor this$1 Lj/J_1$B; + +file j/J_1$B.class +class j.J_1$B extends java.lang.Object + inner/enclosing B enclosing class: j.J_1 + inner/nested C member class: j.J_1$B$C + descriptor (Lj/J_1;)V + descriptor this$0 Lj/J_1; + +file j/J_1.class +class j.J_1 extends java.lang.Object + interface java.util.RandomAccess + inner/nested B member class: j.J_1$B + descriptor ()V + +file s/J_1$B$C$D.class +class s.J_1$B$C$D extends java.lang.Object + inner B s.J_1$B in s.J_1 + inner C s.J_1$B$C in s.J_1$B + inner/enclosing D enclosing class: s.J_1$B$C + descriptor $outer Ls/J_1$B$C; + descriptor s$J_1$B$C$D$$$outer ()Ls/J_1$B$C; + descriptor (Ls/J_1$B$C;)V + +file s/J_1$B$C.class +class s.J_1$B$C extends java.lang.Object + inner B s.J_1$B in s.J_1 + inner/enclosing C enclosing class: s.J_1$B + inner/nested D member class: s.J_1$B$C$D + descriptor $outer Ls/J_1$B; + descriptor s$J_1$B$C$$$outer ()Ls/J_1$B; + descriptor (Ls/J_1$B;)V + +file s/J_1$B.class +class s.J_1$B extends java.lang.Object + inner/enclosing B enclosing class: s.J_1 + inner/nested C member class: s.J_1$B$C + descriptor $outer Ls/J_1; + descriptor s$J_1$B$$$outer ()Ls/J_1; + descriptor (Ls/J_1;)V + +file s/J_1.class +class s.J_1 extends java.lang.Object + interface java.util.RandomAccess + inner/nested B member class: s.J_1$B + descriptor ()V + diff --git a/test/files/run/inner-parse/J_1.java b/test/files/run/inner-parse/J_1.java new file mode 100644 index 0000000000..920ab951ab --- /dev/null +++ b/test/files/run/inner-parse/J_1.java @@ -0,0 +1,9 @@ +package j; + +public class J_1 implements java.util.RandomAccess { // "random" marker interface + class B { + class C { + class D { } + } + } +} diff --git a/test/files/run/inner-parse/S_2.scala b/test/files/run/inner-parse/S_2.scala new file mode 100644 index 0000000000..fd144a40b7 --- /dev/null +++ b/test/files/run/inner-parse/S_2.scala @@ -0,0 +1,9 @@ +package s; + +class J_1 extends java.util.RandomAccess { + class B { + class C { + class D { } + } + } +} diff --git a/test/files/run/inner-parse/S_3.scala b/test/files/run/inner-parse/S_3.scala new file mode 100644 index 0000000000..296a651460 --- /dev/null +++ b/test/files/run/inner-parse/S_3.scala @@ -0,0 +1,12 @@ +import scala.reflect.internal.JvmClassInfo + +object Test { + def main(args: Array[String]): Unit = { + val cwd = sys.props("partest.output") + + for ((f, info) <- JvmClassInfo.classInfoList(cwd)) { + println("file " + f.stripPrefix(cwd + "/")) + println(info) + } + } +} diff --git a/tools/dump-class b/tools/dump-class new file mode 100755 index 0000000000..0b4f2a73fa --- /dev/null +++ b/tools/dump-class @@ -0,0 +1,6 @@ +#!/bin/sh +# + +classpath=$($(dirname $BASH_SOURCE)/quickcp) + +java -cp "$classpath" scala.tools.nsc.MainGenericRunner -usejavacp scala.tools.cmd.program.DumpClass "$@" \ No newline at end of file -- cgit v1.2.3 From f7e1a4940386491b0691147b12b1b321c4cce2c5 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 23 Apr 2012 13:26:21 -0700 Subject: Better position printing in NodePrinters. Try this unreasonably long command line: scalac -Xprint-pos -Yshow-trees -Xprint:all -Yrangepos *.scala --- .../scala/tools/nsc/ast/NodePrinters.scala | 48 ++++++++++++++++------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala index 108c8fcbfa..5d849b9622 100644 --- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala @@ -63,10 +63,14 @@ abstract class NodePrinters { } trait DefaultPrintAST extends PrintAST { + val printPos = settings.Xprintpos.value || settings.Yposdebug.value + + def showNameAndPos(tree: NameTree) = showPosition(tree) + showName(tree.name) def showDefTreeName(tree: DefTree) = showName(tree.name) + def showPosition(tree: Tree) = if (printPos) tree.pos.show else "" def showFlags(tree: MemberDef) = flagsToString(tree.symbol.flags | tree.mods.flags) - def showLiteral(lit: Literal) = lit.value.escapedStringValue - def showTypeTree(tt: TypeTree) = "" + emptyOrComment(showType(tt)) + def showLiteral(lit: Literal) = showPosition(lit) + lit.value.escapedStringValue + def showTypeTree(tt: TypeTree) = showPosition(tt) + "" + emptyOrComment(showType(tt)) def showName(name: Name) = name match { case nme.EMPTY | tpnme.EMPTY => "" case name => "\"" + name + "\"" @@ -97,17 +101,21 @@ abstract class NodePrinters { private var level = 0 def showName(name: Name): String + def showPosition(tree: Tree): String + def showNameAndPos(tree: NameTree): String def showDefTreeName(defTree: DefTree): String def showFlags(tree: MemberDef): String def showLiteral(lit: Literal): String def showTypeTree(tt: TypeTree): String def showAttributes(tree: Tree): String // symbol and type - def showRefTreeName(tree: Tree): String = tree match { - case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) - case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) - case Ident(name) => showName(name) - case _ => "" + tree + def showRefTreeName(tree: Tree): String = { + tree match { + case SelectFromTypeTree(qual, name) => showRefTreeName(qual) + "#" + showName(name) + case Select(qual, name) => showRefTreeName(qual) + "." + showName(name) + case id @ Ident(name) => showNameAndPos(id) + case _ => "" + tree + } } def showRefTree(tree: RefTree): String = { def prefix0 = showRefTreeName(tree.qualifier) @@ -116,7 +124,7 @@ abstract class NodePrinters { case Select(_, _) => prefix0 + "." case _ => "" }) - prefix + showName(tree.name) + emptyOrComment(showAttributes(tree)) + prefix + showNameAndPos(tree) + emptyOrComment(showAttributes(tree)) } def emptyOrComment(s: String) = if (s == "") "" else " // " + s @@ -191,8 +199,9 @@ abstract class NodePrinters { } } + def treePrefix(tree: Tree) = showPosition(tree) + tree.printingPrefix def printMultiline(tree: Tree)(body: => Unit) { - printMultiline(tree.printingPrefix, showAttributes(tree))(body) + printMultiline(treePrefix(tree), showAttributes(tree))(body) } def printMultiline(prefix: String, comment: String)(body: => Unit) { printLine(prefix + "(", comment) @@ -218,10 +227,12 @@ abstract class NodePrinters { } def printSingle(tree: Tree, name: Name) { - println(tree.printingPrefix + "(" + showName(name) + ")" + showAttributes(tree)) + println(treePrefix(tree) + "(" + showName(name) + ")" + showAttributes(tree)) } def traverse(tree: Tree) { + showPosition(tree) + tree match { case AppliedTypeTree(tpt, args) => applyCommon(tree, tpt, args) case ApplyDynamic(fun, args) => applyCommon(tree, fun, args) @@ -230,6 +241,19 @@ abstract class NodePrinters { case Throw(Ident(name)) => printSingle(tree, name) + case b @ Bind(name, body) => + printMultiline(tree) { + println(showDefTreeName(b)) + traverse(body) + } + + case ld @ LabelDef(name, params, rhs) => + printMultiline(tree) { + showNameAndPos(ld) + traverseList("()", "params")(params) + traverse(rhs) + } + case Function(vparams, body) => printMultiline(tree) { traverseList("()", "parameter")(vparams) @@ -309,7 +333,7 @@ abstract class NodePrinters { val ps0 = parents map { p => if (p.tpe eq null) p match { case x: RefTree => showRefTree(x) - case x => "" + x + case x => showPosition(x) + x } else showName(newTypeName(p.tpe.typeSymbol.fullName)) } @@ -353,7 +377,7 @@ abstract class NodePrinters { case _ => tree match { case t: RefTree => println(showRefTree(t)) - case t if t.productArity == 0 => println(tree.printingPrefix) + case t if t.productArity == 0 => println(treePrefix(t)) case t => printMultiline(tree)(tree.productIterator foreach traverseAny) } } -- cgit v1.2.3 From 9d925a30c73ee5856c83d3caab124f7dbeaa85a8 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sun, 22 Apr 2012 02:58:26 -0700 Subject: SI-5702 Pattern parser halts on star In patterns, the parser halts when it sees stars. This means it does not handle infix notation for a case class named "*". This patch uses lookahead to decide whether to parse '_' '*' as a sequence pattern or as the start of infix. (For both normal and error cases, the tokens are always consumed immediately.) Error messages are improved for _* (as a help to learners) and slightly improved recovery helps the parse continue. The entry point for XML patterns is now distinct; otherwise, the change is local to pattern3-simplepattern; the entry point for simplepattern() is unchanged because it is commented "hook for IDE." --- .../scala/tools/nsc/ast/parser/MarkupParsers.scala | 2 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 115 +++++++++++++++------ test/files/neg/t1878-typer.check | 4 + test/files/neg/t1878-typer.scala | 6 ++ test/files/neg/t1878.check | 24 +---- test/files/neg/t1878.scala | 2 + test/files/neg/t3189.check | 4 + test/files/neg/t3189.scala | 3 + test/files/neg/t5702-neg-bad-and-wild.check | 28 +++++ test/files/neg/t5702-neg-bad-and-wild.scala | 29 ++++++ test/files/neg/t5702-neg-bad-brace.check | 10 ++ test/files/neg/t5702-neg-bad-brace.scala | 17 +++ test/files/neg/t5702-neg-bad-xbrace.check | 7 ++ test/files/neg/t5702-neg-bad-xbrace.scala | 31 ++++++ test/files/neg/t5702-neg-ugly-xbrace.check | 19 ++++ test/files/neg/t5702-neg-ugly-xbrace.scala | 14 +++ test/files/pos/t5702-pos-infix-star.scala | 15 +++ test/pending/neg/t3189.check | 7 -- test/pending/neg/t3189.scala | 3 - 19 files changed, 279 insertions(+), 61 deletions(-) create mode 100644 test/files/neg/t1878-typer.check create mode 100644 test/files/neg/t1878-typer.scala create mode 100644 test/files/neg/t3189.check create mode 100644 test/files/neg/t3189.scala create mode 100644 test/files/neg/t5702-neg-bad-and-wild.check create mode 100644 test/files/neg/t5702-neg-bad-and-wild.scala create mode 100644 test/files/neg/t5702-neg-bad-brace.check create mode 100644 test/files/neg/t5702-neg-bad-brace.scala create mode 100644 test/files/neg/t5702-neg-bad-xbrace.check create mode 100644 test/files/neg/t5702-neg-bad-xbrace.scala create mode 100644 test/files/neg/t5702-neg-ugly-xbrace.check create mode 100644 test/files/neg/t5702-neg-ugly-xbrace.scala create mode 100644 test/files/pos/t5702-pos-infix-star.scala delete mode 100644 test/pending/neg/t3189.check delete mode 100644 test/pending/neg/t3189.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index 93fa9a60f6..f702f44338 100755 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -397,7 +397,7 @@ trait MarkupParsers { /** xScalaPatterns ::= patterns */ - def xScalaPatterns: List[Tree] = escapeToScala(parser.seqPatterns(), "pattern") + def xScalaPatterns: List[Tree] = escapeToScala(parser.xmlSeqPatterns(), "pattern") def reportSyntaxError(pos: Int, str: String) = parser.syntaxError(pos, str) def reportSyntaxError(str: String) { diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index bca1cc4596..337ca7671c 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1705,11 +1705,11 @@ self => * was threaded through methods as boolean seqOK. */ trait SeqContextSensitive extends PatternContextSensitive { - /** Returns Some(tree) if it finds a star and prematurely ends parsing. - * This is an artifact of old implementation which has proven difficult - * to cleanly extract. - */ - def interceptStarPattern(top: Tree): Option[Tree] + // is a sequence pattern _* allowed? + def isSequenceOK: Boolean + + // are we in an XML pattern? + def isXML: Boolean = false def functionArgType(): Tree = argType() def argType(): Tree = { @@ -1796,45 +1796,98 @@ self => /** {{{ * Pattern3 ::= SimplePattern * | SimplePattern {Id [nl] SimplePattern} - * SeqPattern3 ::= SeqSimplePattern [ `*' | `?' | `+' ] - * | SeqSimplePattern {Id [nl] SeqSimplePattern} * }}} */ def pattern3(): Tree = { + var top = simplePattern(badPattern3) + // after peekahead + def acceptWildStar() = atPos(top.pos.startOrPoint, in.prev.offset)(Star(stripParens(top))) + def peekahead() = { + in.prev copyFrom in + in.nextToken() + } + def pushback() = { + in.next copyFrom in + in copyFrom in.prev + } + // See SI-3189, SI-4832 for motivation. Cf SI-3480 for counter-motivation. + // TODO: dredge out the remnants of regexp patterns. + // /{/ peek for _*) or _*} (for xml escape) + if (isSequenceOK) { + top match { + case Ident(nme.WILDCARD) if (isRawStar) => + peekahead() + in.token match { + case RBRACE if (isXML) => return acceptWildStar() + case RPAREN if (!isXML) => return acceptWildStar() + case _ => pushback() + } + case _ => + } + } val base = opstack - var top = simplePattern() - interceptStarPattern(top) foreach { x => return x } - while (isIdent && in.name != raw.BAR) { - top = reduceStack( - false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) + top = reduceStack(false, base, top, precedence(in.name), treeInfo.isLeftAssoc(in.name)) val op = in.name opstack = OpInfo(top, op, in.offset) :: opstack ident() - top = simplePattern() + top = simplePattern(badPattern3) } stripParens(reduceStack(false, base, top, 0, true)) } + def badPattern3(): Tree = { + def isComma = in.token == COMMA + def isAnyBrace = in.token == RPAREN || in.token == RBRACE + val badStart = "illegal start of simple pattern" + // better recovery if don't skip delims of patterns + var skip = !(isComma || isAnyBrace) + val msg = if (!opstack.isEmpty && opstack.head.operator == nme.STAR) { + opstack.head.operand match { + case Ident(nme.WILDCARD) => + if (isSequenceOK && isComma) + "bad use of _* (a sequence pattern must be the last pattern)" + else if (isSequenceOK && isAnyBrace) { + skip = true // do skip bad paren; scanner may skip bad brace already + "bad brace or paren after _*" + } else if (!isSequenceOK && isAnyBrace) + "bad use of _* (sequence pattern not allowed)" + else badStart + case _ => + if (isSequenceOK && isAnyBrace) + "use _* to match a sequence" + else if (isComma || isAnyBrace) + "trailing * is not a valid pattern" + else badStart + } + } else { + badStart + } + syntaxErrorOrIncomplete(msg, skip) + errorPatternTree + } /** {{{ * SimplePattern ::= varid * | `_' * | literal * | XmlPattern - * | StableId [TypeArgs] [`(' [SeqPatterns] `)'] + * | StableId /[TypeArgs]/ [`(' [Patterns] `)'] + * | StableId [`(' [Patterns] `)'] + * | StableId [`(' [Patterns] `,' [varid `@'] `_' `*' `)'] * | `(' [Patterns] `)' - * SimpleSeqPattern ::= varid - * | `_' - * | literal - * | XmlPattern - * | `<' xLiteralPattern - * | StableId [TypeArgs] [`(' [SeqPatterns] `)'] - * | `(' [SeqPatterns] `)' * }}} * * XXX: Hook for IDE */ def simplePattern(): Tree = { + // simple diagnostics for this entry point + def badStart(): Tree = { + syntaxErrorOrIncomplete("illegal start of simple pattern", true) + errorPatternTree + } + simplePattern(badStart) + } + def simplePattern(onError: () => Tree): Tree = { val start = in.offset in.token match { case IDENTIFIER | BACKQUOTED_IDENT | THIS => @@ -1867,8 +1920,7 @@ self => case XMLSTART => xmlLiteralPattern() case _ => - syntaxErrorOrIncomplete("illegal start of simple pattern", true) - errorPatternTree + onError() } } } @@ -1879,16 +1931,16 @@ self => } /** The implementation for parsing inside of patterns at points where sequences are allowed. */ object seqOK extends SeqContextSensitive { - // See ticket #3189 for the motivation for the null check. - // TODO: dredge out the remnants of regexp patterns. - // ... and now this is back the way it was because it caused #3480. - def interceptStarPattern(top: Tree): Option[Tree] = - if (isRawStar) Some(atPos(top.pos.startOrPoint, in.skipToken())(Star(stripParens(top)))) - else None + val isSequenceOK = true } /** The implementation for parsing inside of patterns at points where sequences are disallowed. */ object noSeq extends SeqContextSensitive { - def interceptStarPattern(top: Tree) = None + val isSequenceOK = false + } + /** For use from xml pattern, where sequence is allowed and encouraged. */ + object xmlSeqOK extends SeqContextSensitive { + val isSequenceOK = true + override val isXML = true } /** These are default entry points into the pattern context sensitive methods: * they are all initiated from non-pattern context. @@ -1902,7 +1954,8 @@ self => /** Default entry points into some pattern contexts. */ def pattern(): Tree = noSeq.pattern() def patterns(): List[Tree] = noSeq.patterns() - def seqPatterns(): List[Tree] = seqOK.patterns() // Also called from xml parser + def seqPatterns(): List[Tree] = seqOK.patterns() + def xmlSeqPatterns(): List[Tree] = xmlSeqOK.patterns() // Called from xml parser def argumentPatterns(): List[Tree] = inParens { if (in.token == RPAREN) Nil else seqPatterns() diff --git a/test/files/neg/t1878-typer.check b/test/files/neg/t1878-typer.check new file mode 100644 index 0000000000..e3a20d0be7 --- /dev/null +++ b/test/files/neg/t1878-typer.check @@ -0,0 +1,4 @@ +t1878-typer.scala:4: error: _* may only come last + case

{ _* }

=> + ^ +one error found diff --git a/test/files/neg/t1878-typer.scala b/test/files/neg/t1878-typer.scala new file mode 100644 index 0000000000..1eb0cb7dff --- /dev/null +++ b/test/files/neg/t1878-typer.scala @@ -0,0 +1,6 @@ +object Test extends App { + // illegal - bug #1764 + null match { + case

{ _* }

=> + } +} diff --git a/test/files/neg/t1878.check b/test/files/neg/t1878.check index b47367e12c..ac2071c3d8 100644 --- a/test/files/neg/t1878.check +++ b/test/files/neg/t1878.check @@ -1,21 +1,7 @@ -t1878.scala:3: error: _* may only come last +t1878.scala:3: error: bad use of _* (a sequence pattern must be the last pattern) val err1 = "" match { case Seq(f @ _*, ',') => f } - ^ -t1878.scala:3: error: scrutinee is incompatible with pattern type; - found : Seq[A] - required: String - val err1 = "" match { case Seq(f @ _*, ',') => f } - ^ -t1878.scala:3: error: not found: value f - val err1 = "" match { case Seq(f @ _*, ',') => f } - ^ -t1878.scala:3: error: value _2 is not a member of object Seq - val err1 = "" match { case Seq(f @ _*, ',') => f } - ^ -t1878.scala:9: error: _* may only come last + ^ +t1878.scala:9: error: bad use of _* (a sequence pattern must be the last pattern) val List(List(_*, arg2), _) = List(List(1,2,3), List(4,5,6)) - ^ -t1878.scala:13: error: _* may only come last - case

{ _* }

=> - ^ -6 errors found + ^ +two errors found diff --git a/test/files/neg/t1878.scala b/test/files/neg/t1878.scala index 5278fbb7bd..99fee48a96 100644 --- a/test/files/neg/t1878.scala +++ b/test/files/neg/t1878.scala @@ -8,8 +8,10 @@ object Test extends App { // illegal val List(List(_*, arg2), _) = List(List(1,2,3), List(4,5,6)) + /* see t1878-typer.scala // illegal - bug #1764 null match { case

{ _* }

=> } + */ } diff --git a/test/files/neg/t3189.check b/test/files/neg/t3189.check new file mode 100644 index 0000000000..3913c526a2 --- /dev/null +++ b/test/files/neg/t3189.check @@ -0,0 +1,4 @@ +t3189.scala:2: error: use _* to match a sequence + val Array(a,b*) = ("": Any) + ^ +one error found diff --git a/test/files/neg/t3189.scala b/test/files/neg/t3189.scala new file mode 100644 index 0000000000..4ea4bb7581 --- /dev/null +++ b/test/files/neg/t3189.scala @@ -0,0 +1,3 @@ +object A { + val Array(a,b*) = ("": Any) +} \ No newline at end of file diff --git a/test/files/neg/t5702-neg-bad-and-wild.check b/test/files/neg/t5702-neg-bad-and-wild.check new file mode 100644 index 0000000000..eae81ad5f2 --- /dev/null +++ b/test/files/neg/t5702-neg-bad-and-wild.check @@ -0,0 +1,28 @@ +t5702-neg-bad-and-wild.scala:10: error: bad use of _* (a sequence pattern must be the last pattern) + case List(1, _*,) => // bad use of _* (a sequence pattern must be the last pattern) + ^ +t5702-neg-bad-and-wild.scala:10: error: illegal start of simple pattern + case List(1, _*,) => // bad use of _* (a sequence pattern must be the last pattern) + ^ +t5702-neg-bad-and-wild.scala:12: error: illegal start of simple pattern + case List(1, _*3,) => // illegal start of simple pattern + ^ +t5702-neg-bad-and-wild.scala:14: error: use _* to match a sequence + case List(1, x*) => // use _* to match a sequence + ^ +t5702-neg-bad-and-wild.scala:15: error: trailing * is not a valid pattern + case List(x*, 1) => // trailing * is not a valid pattern + ^ +t5702-neg-bad-and-wild.scala:16: error: trailing * is not a valid pattern + case (1, x*) => // trailing * is not a valid pattern + ^ +t5702-neg-bad-and-wild.scala:17: error: bad use of _* (sequence pattern not allowed) + case (1, x@_*) => // bad use of _* (sequence pattern not allowed) + ^ +t5702-neg-bad-and-wild.scala:23: error: bad use of _* (a sequence pattern must be the last pattern) + val K(ns @ _*, x) = k // bad use of _* (a sequence pattern must be the last pattern) + ^ +t5702-neg-bad-and-wild.scala:24: error: bad use of _* (sequence pattern not allowed) + val (b, _ * ) = Pair(5,6) // bad use of _* (sequence pattern not allowed) + ^ +9 errors found diff --git a/test/files/neg/t5702-neg-bad-and-wild.scala b/test/files/neg/t5702-neg-bad-and-wild.scala new file mode 100644 index 0000000000..3833a002b1 --- /dev/null +++ b/test/files/neg/t5702-neg-bad-and-wild.scala @@ -0,0 +1,29 @@ + +object Test { + case class K(i: Int) + + def main(args: Array[String]) { + val k = new K(9) + val is = List(1,2,3) + + is match { + case List(1, _*,) => // bad use of _* (a sequence pattern must be the last pattern) + // illegal start of simple pattern + case List(1, _*3,) => // illegal start of simple pattern + //case List(1, _*3:) => // poor recovery by parens + case List(1, x*) => // use _* to match a sequence + case List(x*, 1) => // trailing * is not a valid pattern + case (1, x*) => // trailing * is not a valid pattern + case (1, x@_*) => // bad use of _* (sequence pattern not allowed) + } + +// good syntax, bad semantics, detected by typer +//gowild.scala:14: error: star patterns must correspond with varargs parameters + val K(is @ _*) = k + val K(ns @ _*, x) = k // bad use of _* (a sequence pattern must be the last pattern) + val (b, _ * ) = Pair(5,6) // bad use of _* (sequence pattern not allowed) +// no longer complains +//bad-and-wild.scala:15: error: ')' expected but '}' found. + } +} + diff --git a/test/files/neg/t5702-neg-bad-brace.check b/test/files/neg/t5702-neg-bad-brace.check new file mode 100644 index 0000000000..503f7d95ed --- /dev/null +++ b/test/files/neg/t5702-neg-bad-brace.check @@ -0,0 +1,10 @@ +t5702-neg-bad-brace.scala:14: error: Unmatched closing brace '}' ignored here + case List(1, _*} => + ^ +t5702-neg-bad-brace.scala:14: error: illegal start of simple pattern + case List(1, _*} => + ^ +t5702-neg-bad-brace.scala:15: error: ')' expected but '}' found. + } + ^ +three errors found diff --git a/test/files/neg/t5702-neg-bad-brace.scala b/test/files/neg/t5702-neg-bad-brace.scala new file mode 100644 index 0000000000..16a341cf8c --- /dev/null +++ b/test/files/neg/t5702-neg-bad-brace.scala @@ -0,0 +1,17 @@ + +object Test { + + def main(args: Array[String]) { + val is = List(1,2,3) + + is match { +// the erroneous brace is ignored, so we can't halt on it. +// maybe brace healing can detect overlapping unmatched (...} +// In this case, the fix emits an extra error: +// t5702-neg-bad-brace.scala:10: error: Unmatched closing brace '}' ignored here +// t5702-neg-bad-brace.scala:10: error: illegal start of simple pattern (i.e., =>) +// t5702-neg-bad-brace.scala:11: error: ')' expected but '}' found. + case List(1, _*} => + } + } +} diff --git a/test/files/neg/t5702-neg-bad-xbrace.check b/test/files/neg/t5702-neg-bad-xbrace.check new file mode 100644 index 0000000000..d88638aee9 --- /dev/null +++ b/test/files/neg/t5702-neg-bad-xbrace.check @@ -0,0 +1,7 @@ +t5702-neg-bad-xbrace.scala:19: error: bad brace or paren after _* + case {_*)} => y + ^ +t5702-neg-bad-xbrace.scala:28: error: bad brace or paren after _* + val {a, z@_*)} = xml + ^ +two errors found diff --git a/test/files/neg/t5702-neg-bad-xbrace.scala b/test/files/neg/t5702-neg-bad-xbrace.scala new file mode 100644 index 0000000000..64bbdb18be --- /dev/null +++ b/test/files/neg/t5702-neg-bad-xbrace.scala @@ -0,0 +1,31 @@ + +object Test { + def main(args: Array[String]) { + /* PiS example, minus a brace + val yearMade = 1965 + val old = + { if (yearMade < 2000) yearMade} + else xml.NodeSeq.Empty } + println(old) + */ + + // bad brace or paren after _* + // actually, we know it's a bad paren... + // we skip it because not in a context looking for rparen + val xyear = 1965 + val ancient = + { + val when = xyear match { + case {_*)} => y + case _ => "2035" + } + {when} + } + println(ancient) + + val xml = appleboychild + // bad brace or paren after _* + val {a, z@_*)} = xml + println("A for "+ a +", ending with "+ z) + } +} diff --git a/test/files/neg/t5702-neg-ugly-xbrace.check b/test/files/neg/t5702-neg-ugly-xbrace.check new file mode 100644 index 0000000000..7d80bbf6be --- /dev/null +++ b/test/files/neg/t5702-neg-ugly-xbrace.check @@ -0,0 +1,19 @@ +t5702-neg-ugly-xbrace.scala:11: error: bad brace or paren after _* + val {a, z@_*) = xml + ^ +t5702-neg-ugly-xbrace.scala:12: error: Missing closing brace `}' assumed here + println("A for "+ a +", ending with "+ z) + ^ +t5702-neg-ugly-xbrace.scala:13: error: in XML literal: in XML content, please use '}}' to express '}' + } + ^ +t5702-neg-ugly-xbrace.scala:11: error: I encountered a '}' where I didn't expect one, maybe this tag isn't closed + val {a, z@_*) = xml + ^ +t5702-neg-ugly-xbrace.scala:14: error: illegal start of simple pattern +} +^ +t5702-neg-ugly-xbrace.scala:14: error: '}' expected but eof found. +} + ^ +6 errors found diff --git a/test/files/neg/t5702-neg-ugly-xbrace.scala b/test/files/neg/t5702-neg-ugly-xbrace.scala new file mode 100644 index 0000000000..0ff7bfa09d --- /dev/null +++ b/test/files/neg/t5702-neg-ugly-xbrace.scala @@ -0,0 +1,14 @@ + +object Test { + def main(args: Array[String]) { + + val xml = appleboychild + // This is the more likely typo, and the uglier parse. + // We could turn it into a } if } does not follow (to + // avoid handing }} back to xml) but that is quite ad hoc. + // Assuming } for ) after _* would not be not outlandish. + // bad brace or paren after _* + val {a, z@_*) = xml + println("A for "+ a +", ending with "+ z) + } +} diff --git a/test/files/pos/t5702-pos-infix-star.scala b/test/files/pos/t5702-pos-infix-star.scala new file mode 100644 index 0000000000..756bcdd8de --- /dev/null +++ b/test/files/pos/t5702-pos-infix-star.scala @@ -0,0 +1,15 @@ + +object Test { + case class *(a: Int, b: Int) + type Star = * + case class P(a: Int, b: Star) // alias still required + + def main(args: Array[String]) { + val v = new *(6,7) + val x * y = v + printf("%d,%d\n",x,y) + val p = P(5, v) + val P(a, b * c) = p + printf("%d,%d,%d\n",a,b,c) + } +} diff --git a/test/pending/neg/t3189.check b/test/pending/neg/t3189.check deleted file mode 100644 index 43dd0f29a0..0000000000 --- a/test/pending/neg/t3189.check +++ /dev/null @@ -1,7 +0,0 @@ -t3189.scala:2: error: illegal start of simple pattern - val Array(a,b*) = ("": Any) - ^ -t3189.scala:3: error: ')' expected but '}' found. -} -^ -two errors found diff --git a/test/pending/neg/t3189.scala b/test/pending/neg/t3189.scala deleted file mode 100644 index 4ea4bb7581..0000000000 --- a/test/pending/neg/t3189.scala +++ /dev/null @@ -1,3 +0,0 @@ -object A { - val Array(a,b*) = ("": Any) -} \ No newline at end of file -- cgit v1.2.3 From c577aaca7a7dab7b03fc3b69d766378486e10c00 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Fri, 27 Apr 2012 10:17:53 +0200 Subject: SI-3755: catch exception thrown by adaptToNewrun it would be nice to have a test for this, but you'd need to involve the repl, as I couldn't trigger it using multiple scalac runs --- src/compiler/scala/reflect/internal/Types.scala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 2fe7dfda17..c049df47af 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -4832,9 +4832,14 @@ trait Types extends api.Types { self: SymbolTable => if (sym.isPackage) tp else { val pre1 = this(pre) - val sym1 = adaptToNewRun(pre1, sym) - if ((pre1 eq pre) && (sym1 eq sym)) tp - else singleType(pre1, sym1) + try { + val sym1 = adaptToNewRun(pre1, sym) + if ((pre1 eq pre) && (sym1 eq sym)) tp + else singleType(pre1, sym1) + } catch { + case _: MissingTypeControl => + tp + } } case TypeRef(pre, sym, args) => if (sym.isPackageClass) tp -- cgit v1.2.3 From 23b3e9dfd6c476b866148c18b1a4341741e1c011 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 27 Apr 2012 13:03:55 +0300 Subject: essential information about macro expansion --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index 1b8a43bf27..353514c397 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -1010,7 +1010,7 @@ trait Macros extends Traces { private def Failure(expandee: Tree) = Other(expandee) private def fail(typer: Typer, expandee: Tree, msg: String = null) = { def msgForLog = if (msg != null && (msg contains "exception during macro expansion")) msg.split(EOL).drop(1).headOption.getOrElse("?") else msg - macroLogVerbose("macro expansion has failed: %s".format(msgForLog)) + macroLogLite("macro expansion has failed: %s".format(msgForLog)) val pos = if (expandee.pos != NoPosition) expandee.pos else enclosingMacroPosition if (msg != null) typer.context.error(pos, msg) typer.infer.setError(expandee) @@ -1079,7 +1079,7 @@ trait Macros extends Traces { else expanded match { case expanded: Expr[_] => macroLogVerbose("original:") - macroLogVerbose("" + expanded.tree + "\n" + showRaw(expanded.tree)) + macroLogLite("" + expanded.tree + "\n" + showRaw(expanded.tree)) freeTerms(expanded.tree) foreach issueFreeError freeTypes(expanded.tree) foreach issueFreeError @@ -1105,11 +1105,11 @@ trait Macros extends Traces { else Skip(macroExpandAll(typer, expandee)) } else { - macroLogVerbose("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) + macroLogLite("typechecking macro expansion %s at %s".format(expandee, expandee.pos)) macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) { case args @ ((context: MacroContext) :: _) => if (nowDelayed) { - macroLogVerbose("macro expansion is delayed: %s".format(expandee)) + macroLogLite("macro expansion is delayed: %s".format(expandee)) delayed += expandee -> undetparams // need to save typer context for `macroExpandAll` // need to save macro context to preserve enclosures @@ -1176,7 +1176,7 @@ trait Macros extends Traces { } fallBackToOverridden(expandee) match { case Some(tree1) => - macroTraceVerbose("falling back to: ")(tree1) + macroTraceLite("falling back to: ")(tree1) currentRun.macroExpansionFailed = true Fallback(tree1) case None => @@ -1192,7 +1192,7 @@ trait Macros extends Traces { macroLogVerbose("macro expansion has failed: %s".format(realex.msg)) fail(typer, expandee) // error has been reported by abort case err: TypeError => - macroLogVerbose("macro expansion has failed: %s at %s".format(err.msg, err.pos)) + macroLogLite("macro expansion has failed: %s at %s".format(err.msg, err.pos)) throw err // error should be propagated, don't report case _ => val message = { -- cgit v1.2.3 From 543df62aed1fcdcf3902b9b54ec4495a882b0fcc Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 27 Apr 2012 13:27:49 +0300 Subject: fixes SI-5713 --- src/compiler/scala/tools/nsc/ToolBoxes.scala | 3 ++- test/files/run/t5713.check | 1 + test/files/run/t5713.flags | 1 + test/files/run/t5713/Impls_Macros_1.scala | 27 +++++++++++++++++++++++++++ test/files/run/t5713/Test_2.scala | 5 +++++ 5 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t5713.check create mode 100644 test/files/run/t5713.flags create mode 100644 test/files/run/t5713/Impls_Macros_1.scala create mode 100644 test/files/run/t5713/Test_2.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ToolBoxes.scala b/src/compiler/scala/tools/nsc/ToolBoxes.scala index 5b2b5ff5e9..8bf977090b 100644 --- a/src/compiler/scala/tools/nsc/ToolBoxes.scala +++ b/src/compiler/scala/tools/nsc/ToolBoxes.scala @@ -39,7 +39,8 @@ trait ToolBoxes { self: Global => def runExpr(tree0: Tree, freeTypes: Map[FreeType, Type] = Map[FreeType, Type]()): Any = { var tree = substituteFreeTypes(tree0, freeTypes) // need to reset the tree, otherwise toolbox will refuse to work with it - tree = resetAllAttrs(tree0.duplicate) + // upd. this has to be done by the user himself, otherwise we run into troubles. see SI-5713 +// tree = resetAllAttrs(tree0.duplicate) val imported = importer.importTree(tree) val toolBox = libraryClasspathMirror.mkToolBox(frontEnd.asInstanceOf[libraryClasspathMirror.FrontEnd], options) try toolBox.runExpr(imported) diff --git a/test/files/run/t5713.check b/test/files/run/t5713.check new file mode 100644 index 0000000000..d3e9348123 --- /dev/null +++ b/test/files/run/t5713.check @@ -0,0 +1 @@ +err diff --git a/test/files/run/t5713.flags b/test/files/run/t5713.flags new file mode 100644 index 0000000000..cd66464f2f --- /dev/null +++ b/test/files/run/t5713.flags @@ -0,0 +1 @@ +-language:experimental.macros \ No newline at end of file diff --git a/test/files/run/t5713/Impls_Macros_1.scala b/test/files/run/t5713/Impls_Macros_1.scala new file mode 100644 index 0000000000..b499bc7e4e --- /dev/null +++ b/test/files/run/t5713/Impls_Macros_1.scala @@ -0,0 +1,27 @@ +package m + +import language.experimental.macros +import scala.reflect.makro.Context + +object Level extends Enumeration { + val Error = Value(5) +} + +object Logger { + def error(message: String): Unit = macro LoggerMacros.error +} + +private object LoggerMacros { + + type LoggerContext = Context { type PrefixType = Logger.type } + + def error(c: LoggerContext)(message: c.Expr[String]): c.Expr[Unit] = + log(c)(c.reify(Level.Error), message) + + private def log(c: LoggerContext)(level: c.Expr[Level.Value], message: c.Expr[String]): c.Expr[Unit] = + if (level.eval.id < 4) // TODO Remove hack! + c.reify(()) + else { + c.reify(println(message.eval)) + } +} \ No newline at end of file diff --git a/test/files/run/t5713/Test_2.scala b/test/files/run/t5713/Test_2.scala new file mode 100644 index 0000000000..24f9e79b11 --- /dev/null +++ b/test/files/run/t5713/Test_2.scala @@ -0,0 +1,5 @@ +import m._ + +object Test extends App { + Logger.error("err") +} \ No newline at end of file -- cgit v1.2.3 From 1c3f66b6f2d41c02cc2bc32cb696aafa56b71176 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 27 Apr 2012 07:24:46 -0700 Subject: Revert "Moved ancillary methods off specialized traits." This reverts commit 1d0372f84f9a7325a47beb55169cc454895ef74b. I forgot about polymorphic dispatch. Have to seek another way. --- src/build/genprod.scala | 132 +++++++++++++++++++-- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 1 - src/library/scala/Function0.scala | 2 +- src/library/scala/Function1.scala | 16 +++ src/library/scala/Function2.scala | 14 +++ src/library/scala/PartialFunction.scala | 2 +- src/library/scala/Predef.scala | 8 +- src/library/scala/Tuple2.scala | 114 ++++++++++++++++++ src/library/scala/Tuple3.scala | 11 ++ src/library/scala/runtime/RichFunction1.scala | 27 ----- src/library/scala/runtime/RichFunction2.scala | 26 ---- src/library/scala/runtime/Tuple2Zipped.scala | 109 ----------------- test/files/neg/t5067.check | 8 +- test/files/neg/t5067.scala | 6 +- test/files/run/tuple-zipped.scala | 2 +- 15 files changed, 294 insertions(+), 184 deletions(-) delete mode 100644 src/library/scala/runtime/RichFunction1.scala delete mode 100644 src/library/scala/runtime/RichFunction2.scala delete mode 100644 src/library/scala/runtime/Tuple2Zipped.scala (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 8a5c44f1c1..1ea0bf7b73 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -123,7 +123,23 @@ object FunctionOne extends Function(1) { * assert(succ(0) == anonfun1(0)) * """) - override def moreMethods = "" + override def moreMethods = """ + /** Composes two instances of Function1 in a new Function1, with this function applied last. + * + * @tparam A the type to which function `g` can be applied + * @param g a function A => T1 + * @return a new function `f` such that `f(x) == apply(g(x))` + */ + def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + + /** Composes two instances of Function1 in a new Function1, with this function applied first. + * + * @tparam A the result type of function `g` + * @param g a function R => A + * @return a new function `f` such that `f(x) == g(apply(x))` + */ + def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } +""" } object FunctionTwo extends Function(2) { @@ -139,8 +155,6 @@ object FunctionTwo extends Function(2) { * } * assert(max(0, 1) == anonfun2(0, 1)) * """) - - override def moreMethods = "" } object Function { @@ -241,6 +255,11 @@ class Function(val i: Int) extends Group("Function") with Arity { zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz */ object Tuple { + val zipImports = """ +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } +""" + def make(i: Int) = apply(i)() def apply(i: Int) = i match { case 1 => TupleOne @@ -257,6 +276,7 @@ object TupleOne extends Tuple(1) object TupleTwo extends Tuple(2) { + override def imports = Tuple.zipImports override def covariantSpecs = "@specialized(Int, Long, Double, Char, Boolean, AnyRef) " override def moreMethods = """ /** Swaps the elements of this `Tuple`. @@ -264,14 +284,112 @@ object TupleTwo extends Tuple(2) * second element is the first element of this Tuple. */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) + + @deprecated("Use `zipped` instead.", "2.9.0") + def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], + w2: T2 => Iterable[El2], + cbf1: CBF[Repr1, (El1, El2), To]): To = { + zipped map ((x, y) => ((x, y))) + } + + /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. + * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] + * or [[scala.collection.IterableLike]]. + * {{{ + * scala> val tuple = (List(1,2,3),List('a','b','c')) + * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) + * + * scala> tuple.zipped map { (x,y) => x + ":" + y } + * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) + * }}} + * + * @see Zipped + * Note: will not terminate for infinite-sized collections. + */ + def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] + = new Zipped[Repr1, El1, Repr2, El2](_1, _2) + + class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter + def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + b.sizeHint(coll1) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + val el2 = elems2.next + if (f(el1, el2)) { + b1 += el1 + b2 += el2 + } + } + else return (b1.result, b2.result) + } + + (b1.result, b2.result) + } + + def exists(f: (El1, El2) => Boolean): Boolean = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) + + def foreach[U](f: (El1, El2) => U): Unit = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } + } + } """ } object TupleThree extends Tuple(3) { - override def imports = """ -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - """ + override def imports = Tuple.zipImports override def moreMethods = """ @deprecated("Use `zipped` instead.", "2.9.0") diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index f7898f2aa2..aace545ea5 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1324,7 +1324,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val lastInstr = b.lastInstruction for (instr <- b) { - instr match { case THIS(clasz) => jcode.emitALOAD_0() diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index cc17f8797a..dceed26439 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,7 +6,7 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Tue Apr 24 16:32:13 PDT 2012 +// genprod generated these sources at: Tue Feb 14 16:49:03 PST 2012 package scala diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index a4391c1509..8995ef912b 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -38,5 +38,21 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s */ def apply(v1: T1): R + /** Composes two instances of Function1 in a new Function1, with this function applied last. + * + * @tparam A the type to which function `g` can be applied + * @param g a function A => T1 + * @return a new function `f` such that `f(x) == apply(g(x))` + */ + def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + + /** Composes two instances of Function1 in a new Function1, with this function applied first. + * + * @tparam A the result type of function `g` + * @param g a function R => A + * @return a new function `f` such that `f(x) == g(apply(x))` + */ + def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + override def toString() = "" } diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index 5ea2b411bb..cacb96ef5d 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -37,6 +37,20 @@ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @speciali * @return the result of function application. */ def apply(v1: T1, v2: T2): R + /** Creates a curried version of this function. + * + * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` + */ def curried: T1 => T2 => R = { + (x1: T1) => (x2: T2) => apply(x1, x2) + } + /** Creates a tupled version of this function: instead of 2 arguments, + * it accepts a single [[scala.Tuple2]] argument. + * + * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` + */ + def tupled: Tuple2[T1, T2] => R = { + case Tuple2(x1, x2) => apply(x1, x2) + } override def toString() = "" } diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index fafaef9c2f..7154b8da34 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -78,7 +78,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self => * @return a partial function with the same domain as this partial function, which maps * arguments `x` to `k(this(x))`. */ - def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { + override def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { def isDefinedAt(x: A): Boolean = self isDefinedAt x def apply(x: A): C = k(self(x)) } diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 96b8b6d8d5..d2aa3a8b34 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -308,11 +308,11 @@ object Predef extends LowPriorityImplicits { // views -------------------------------------------------------------- implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) - implicit def function1ToRichFunction1[T, R](f: T => R): runtime.RichFunction1[T, R] = new runtime.RichFunction1(f) - implicit def function2ToRichFunction2[T1, T2, R](f: (T1, T2) => R): runtime.RichFunction2[T1, T2, R] = - new runtime.RichFunction2(f) - implicit def tuple2ToZipped[T1, T2](zz: (T1, T2)) = new runtime.Tuple2ZippedOps(zz) + implicit def zipped2ToTraversable[El1, El2](zz: Tuple2[_, _]#Zipped[_, El1, _, El2]): Traversable[(El1, El2)] = + new collection.AbstractTraversable[(El1, El2)] { + def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f) + } implicit def zipped3ToTraversable[El1, El2, El3](zz: Tuple3[_, _, _]#Zipped[_, El1, _, El2, _, El3]): Traversable[(El1, El2, El3)] = new collection.AbstractTraversable[(El1, El2, El3)] { diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 924b2b6fe3..37ab564c3c 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -9,6 +9,9 @@ package scala +import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } +import scala.collection.generic.{ CanBuildFrom => CBF } + /** A tuple of 2 elements; the canonical representation of a [[scala.Product2]]. * @@ -27,4 +30,115 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s */ def swap: Tuple2[T2,T1] = Tuple2(_2, _1) + @deprecated("Use `zipped` instead.", "2.9.0") + def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], + w2: T2 => Iterable[El2], + cbf1: CBF[Repr1, (El1, El2), To]): To = { + zipped map ((x, y) => ((x, y))) + } + + /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. + * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] + * or [[scala.collection.IterableLike]]. + * {{{ + * scala> val tuple = (List(1,2,3),List('a','b','c')) + * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) + * + * scala> tuple.zipped map { (x,y) => x + ":" + y } + * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) + * }}} + * + * @see Zipped + * Note: will not terminate for infinite-sized collections. + */ + def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] + = new Zipped[Repr1, El1, Repr2, El2](_1, _2) + + /** + * @define coll zipped + * @define Coll Zipped + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + */ + class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter + def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + b.sizeHint(coll1) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b += f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { + val b = cbf(coll1.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + b ++= f(el1, elems2.next) + else + return b.result + } + + b.result + } + + def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { + val b1 = cbf1(coll1.repr) + val b2 = cbf2(coll2.repr) + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + val el2 = elems2.next + if (f(el1, el2)) { + b1 += el1 + b2 += el2 + } + } + else return (b1.result, b2.result) + } + + (b1.result, b2.result) + } + + def exists(f: (El1, El2) => Boolean): Boolean = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) { + if (f(el1, elems2.next)) + return true + } + else return false + } + false + } + + def forall(f: (El1, El2) => Boolean): Boolean = + !exists((x, y) => !f(x, y)) + + def foreach[U](f: (El1, El2) => U): Unit = { + val elems2 = coll2.iterator + + for (el1 <- coll1) { + if (elems2.hasNext) + f(el1, elems2.next) + else + return + } + } + } + } diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index dfa0c962a2..cd5ee23757 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -53,6 +53,17 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) + /** + * @define coll zipped + * @define Coll Zipped + * @define orderDependent + * @define orderDependentFold + * @define mayNotTerminateInf + * @define willNotTerminateInf + * @define collectExample + * @define undefinedorder + * @define thatInfo The class of the returned collection. + */ class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2], coll3: ILike[El3, Repr3]) { diff --git a/src/library/scala/runtime/RichFunction1.scala b/src/library/scala/runtime/RichFunction1.scala deleted file mode 100644 index 26651b8d6a..0000000000 --- a/src/library/scala/runtime/RichFunction1.scala +++ /dev/null @@ -1,27 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.runtime - -@inline final class RichFunction1[-T1, +R](f: T1 => R) { - /** Composes two instances of Function1 in a new Function1, with the function on the left applied last. - * - * @tparam A the type to which function `g` can be applied - * @param g a function A => T1 - * @return a new function `h` such that `h(x) == f(g(x))` - */ - def compose[A](g: A => T1): A => R = { x => f(g(x)) } - - /** Composes two instances of Function1 in a new Function1, with the function on the left applied first. - * - * @tparam A the result type of function `g` - * @param g a function R => A - * @return a new function `h` such that `h(x) == g(f(x))` - */ - def andThen[A](g: R => A): T1 => A = { x => g(f(x)) } -} diff --git a/src/library/scala/runtime/RichFunction2.scala b/src/library/scala/runtime/RichFunction2.scala deleted file mode 100644 index 14e23be31b..0000000000 --- a/src/library/scala/runtime/RichFunction2.scala +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.runtime - -@inline final class RichFunction2[-T1, -T2, +R](f: (T1, T2) => R) { - /** Creates a curried version of this function. - * - * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` - */ - def curried: T1 => T2 => R = (x1: T1) => (x2: T2) => f(x1, x2) - - /** Creates a tupled version of this function: instead of 2 arguments, - * it accepts a single [[scala.Tuple2]] argument. - * - * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` - */ - def tupled: ((T1, T2)) => R = { - case Tuple2(x1, x2) => f(x1, x2) - } -} diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala deleted file mode 100644 index 2eb2a47e46..0000000000 --- a/src/library/scala/runtime/Tuple2Zipped.scala +++ /dev/null @@ -1,109 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala.runtime - -import scala.collection.{ TraversableLike => TLike, IterableLike => ILike } -import scala.collection.generic.{ CanBuildFrom => CBF } - - /** Wraps a tuple in a `Zipped`, which supports 2-ary generalisations of `map`, `flatMap`, `filter`, etc. - * Note that there must be an implicit value to convert this tuple's types into a [[scala.collection.TraversableLike]] - * or [[scala.collection.IterableLike]]. - * {{{ - * scala> val tuple = (List(1,2,3),List('a','b','c')) - * tuple: (List[Int], List[Char]) = (List(1, 2, 3),List(a, b, c)) - * - * scala> tuple.zipped map { (x,y) => x + ":" + y } - * res6: List[java.lang.String] = List(1:a, 2:b, 3:c) - * }}} - * - * @see Zipped - * Note: will not terminate for infinite-sized collections. - */ -@inline private[scala] final class Tuple2Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { - // coll2: ILike for filter - def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - b.sizeHint(coll1) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b += f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def flatMap[B, To](f: (El1, El2) => TraversableOnce[B])(implicit cbf: CBF[Repr1, B, To]): To = { - val b = cbf(coll1.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - b ++= f(el1, elems2.next) - else - return b.result - } - - b.result - } - - def filter[To1, To2](f: (El1, El2) => Boolean)(implicit cbf1: CBF[Repr1, El1, To1], cbf2: CBF[Repr2, El2, To2]): (To1, To2) = { - val b1 = cbf1(coll1.repr) - val b2 = cbf2(coll2.repr) - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - val el2 = elems2.next - if (f(el1, el2)) { - b1 += el1 - b2 += el2 - } - } - else return (b1.result, b2.result) - } - - (b1.result, b2.result) - } - - def exists(f: (El1, El2) => Boolean): Boolean = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) { - if (f(el1, elems2.next)) - return true - } - else return false - } - false - } - - def forall(f: (El1, El2) => Boolean): Boolean = - !exists((x, y) => !f(x, y)) - - def foreach[U](f: (El1, El2) => U): Unit = { - val elems2 = coll2.iterator - - for (el1 <- coll1) { - if (elems2.hasNext) - f(el1, elems2.next) - else - return - } - } -} - -@inline private[scala] final class Tuple2ZippedOps[T1, T2](zz: (T1, T2)) { - def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]) = - new Tuple2Zipped[Repr1, El1, Repr2, El2](w1(zz._1), w2(zz._2)) -} diff --git a/test/files/neg/t5067.check b/test/files/neg/t5067.check index 395eda7442..32491766d7 100644 --- a/test/files/neg/t5067.check +++ b/test/files/neg/t5067.check @@ -1,6 +1,6 @@ t5067.scala:3: error: type mismatch; - found : ((Int, Int, Int)) => Int - required: (Int, Int, Int) => Int - override def tupled: (Int, Int, Int) => Int = super.tupled - ^ + found : ((Int, Int)) => Int + required: (Int, Int) => Int + override def tupled: (Int, Int) => Int = super.tupled + ^ one error found diff --git a/test/files/neg/t5067.scala b/test/files/neg/t5067.scala index 0a961d2f40..f8235c0e83 100644 --- a/test/files/neg/t5067.scala +++ b/test/files/neg/t5067.scala @@ -1,4 +1,4 @@ -class Foo extends Function3[Int, Int, Int, Int] { - def apply(x: Int, y: Int, z: Int) = x + y + z - override def tupled: (Int, Int, Int) => Int = super.tupled +class Foo extends Function2[Int, Int, Int] { + def apply(x: Int, y: Int) = x + y + override def tupled: (Int, Int) => Int = super.tupled } diff --git a/test/files/run/tuple-zipped.scala b/test/files/run/tuple-zipped.scala index 08dcc82de6..a9851346bc 100644 --- a/test/files/run/tuple-zipped.scala +++ b/test/files/run/tuple-zipped.scala @@ -15,7 +15,7 @@ object Test { def main(args: Array[String]): Unit = { for (cc1 <- xss1 ; cc2 <- xss2) { - val sum1 = (cc1 zip cc2) map { case (x, y) => x + y } sum + val sum1 = (cc1, cc2).zip map { case (x, y) => x + y } sum val sum2 = (cc1, cc2).zipped map (_ + _) sum assert(sum1 == sum2) -- cgit v1.2.3 From d1460afa09989bcecb306b3cf78880cea39cbdc7 Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Sat, 28 Apr 2012 16:22:47 +0200 Subject: Removes @bridge methods. --- src/library/scala/collection/GenSeqLike.scala | 7 ---- src/library/scala/collection/GenSetLike.scala | 15 -------- src/library/scala/collection/IterableLike.scala | 11 ------ src/library/scala/collection/MapLike.scala | 3 -- src/library/scala/collection/SeqLike.scala | 36 ----------------- src/library/scala/collection/SeqViewLike.scala | 4 -- src/library/scala/collection/SetLike.scala | 9 ----- src/library/scala/collection/Traversable.scala | 6 --- src/library/scala/collection/TraversableLike.scala | 4 -- .../scala/collection/generic/GenSeqFactory.scala | 7 +--- .../collection/generic/GenericSeqCompanion.scala | 10 +---- .../generic/GenericTraversableTemplate.scala | 5 --- .../scala/collection/generic/MapFactory.scala | 2 - .../scala/collection/generic/SetFactory.scala | 9 +---- .../scala/collection/generic/Subtractable.scala | 3 -- .../collection/generic/TraversableFactory.scala | 45 +--------------------- .../scala/collection/immutable/ListMap.scala | 3 -- .../scala/collection/immutable/ListSet.scala | 2 - .../scala/collection/immutable/MapLike.scala | 2 - src/library/scala/collection/immutable/Range.scala | 5 +-- .../scala/collection/immutable/SortedMap.scala | 2 - .../scala/collection/immutable/TreeMap.scala | 2 - .../scala/collection/mutable/BufferLike.scala | 5 --- src/library/scala/collection/mutable/MapLike.scala | 4 -- .../scala/collection/mutable/PriorityQueue.scala | 3 -- src/library/scala/collection/mutable/SetLike.scala | 4 -- src/library/scala/package.scala | 5 --- src/library/scala/runtime/RichInt.scala | 6 --- 28 files changed, 5 insertions(+), 214 deletions(-) (limited to 'src') diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 71316cefc9..646fe09855 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -228,9 +228,6 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal */ def startsWith[B](that: GenSeq[B]): Boolean = startsWith(that, 0) - @bridge - def startsWith[B](that: Seq[B]): Boolean = startsWith(that: GenSeq[B]) - /** Tests whether this $coll contains the given sequence at a given index. * * '''Note''': If the both the receiver object `this` and the argument @@ -413,10 +410,6 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal */ def union[B >: A, That](that: GenSeq[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = this ++ that - @bridge - def union[B >: A, That](that: Seq[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = - union(that: GenSeq[B])(bf) - /** Computes the multiset difference between this $coll and another sequence. * * @param that the sequence of elements to remove diff --git a/src/library/scala/collection/GenSetLike.scala b/src/library/scala/collection/GenSetLike.scala index f729f82bb4..a576014445 100644 --- a/src/library/scala/collection/GenSetLike.scala +++ b/src/library/scala/collection/GenSetLike.scala @@ -51,9 +51,6 @@ extends GenIterableLike[A, Repr] */ def intersect(that: GenSet[A]): Repr = this filter that - @bridge - def intersect(that: Set[A]): Repr = intersect(that: GenSet[A]) - /** Computes the intersection between this set and another set. * * '''Note:''' Same as `intersect`. @@ -63,9 +60,6 @@ extends GenIterableLike[A, Repr] */ def &(that: GenSet[A]): Repr = this intersect that - @bridge - def &(that: Set[A]): Repr = &(that: GenSet[A]) - /** Computes the union between of set and another set. * * @param that the set to form the union with. @@ -83,9 +77,6 @@ extends GenIterableLike[A, Repr] */ def | (that: GenSet[A]): Repr = this union that - @bridge - def | (that: Set[A]): Repr = | (that: GenSet[A]) - /** Computes the difference of this set and another set. * * @param that the set of elements to exclude. @@ -103,9 +94,6 @@ extends GenIterableLike[A, Repr] */ def &~(that: GenSet[A]): Repr = this diff that - @bridge - def &~(that: Set[A]): Repr = &~(that: GenSet[A]) - /** Tests whether this set is a subset of another set. * * @param that the set to test. @@ -114,9 +102,6 @@ extends GenIterableLike[A, Repr] */ def subsetOf(that: GenSet[A]): Boolean = this forall that - @bridge - def subsetOf(that: Set[A]): Boolean = subsetOf(that: GenSet[A]) - /** Compares this set with another object for equality. * * '''Note:''' This operation contains an unchecked cast: if `that` diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index 3c4ad0612a..6a000abd54 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -239,10 +239,6 @@ self => b.result } - @bridge - def zip[A1 >: A, B, That](that: Iterable[B])(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = - zip(that: GenIterable[B])(bf) - def zipAll[B, A1 >: A, That](that: GenIterable[B], thisElem: A1, thatElem: B)(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = { val b = bf(repr) val these = this.iterator @@ -256,10 +252,6 @@ self => b.result } - @bridge - def zipAll[B, A1 >: A, That](that: Iterable[B], thisElem: A1, thatElem: B)(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = - zipAll(that: GenIterable[B], thisElem, thatElem)(bf) - def zipWithIndex[A1 >: A, That](implicit bf: CanBuildFrom[Repr, (A1, Int), That]): That = { val b = bf(repr) var i = 0 @@ -280,9 +272,6 @@ self => !these.hasNext && !those.hasNext } - @bridge - def sameElements[B >: A](that: Iterable[B]): Boolean = sameElements(that: GenIterable[B]) - override /*TraversableLike*/ def toStream: Stream[A] = iterator.toStream /** Method called from equality methods, so that user-defined subclasses can diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala index 8f88e62791..034c1a0c0c 100644 --- a/src/library/scala/collection/MapLike.scala +++ b/src/library/scala/collection/MapLike.scala @@ -297,9 +297,6 @@ self => def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1] = ((repr: Map[A, B1]) /: xs.seq) (_ + _) - @bridge - def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** Returns a new map with all key/value pairs for which the predicate * `p` returns `true`. * diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index ced99e897f..5e37566008 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -296,9 +296,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ !j.hasNext } - @bridge - def startsWith[B](that: Seq[B], offset: Int): Boolean = startsWith(that: GenSeq[B], offset) - def endsWith[B](that: GenSeq[B]): Boolean = { val i = this.iterator.drop(length - that.length) val j = that.iterator @@ -309,10 +306,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ !j.hasNext } - @bridge - def endsWith[B](that: Seq[B]): Boolean = endsWith(that: GenSeq[B]) - - /** Finds first index where this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test @@ -321,9 +314,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ */ def indexOfSlice[B >: A](that: GenSeq[B]): Int = indexOfSlice(that, 0) - @bridge - def indexOfSlice[B >: A](that: Seq[B]): Int = indexOfSlice(that: GenSeq[B]) - /** Finds first index after or at a start index where this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test @@ -354,9 +344,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ -1 } - @bridge - def indexOfSlice[B >: A](that: Seq[B], from: Int): Int = indexOfSlice(that: GenSeq[B], from) - /** Finds last index where this $coll contains a given sequence as a slice. * $willNotTerminateInf * @param that the sequence to test @@ -365,9 +352,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ */ def lastIndexOfSlice[B >: A](that: GenSeq[B]): Int = lastIndexOfSlice(that, length) - @bridge - def lastIndexOfSlice[B >: A](that: Seq[B]): Int = lastIndexOfSlice(that: GenSeq[B]) - /** Finds last index before or at a given end index where this $coll contains a given sequence as a slice. * @param that the sequence to test * @param end the end index @@ -385,9 +369,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ else SeqLike.kmpSearch(thisCollection, 0, clippedL+tl, that.seq, 0, tl, false) } - @bridge - def lastIndexOfSlice[B >: A](that: Seq[B], end: Int): Int = lastIndexOfSlice(that: GenSeq[B], end) - /** Tests whether this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test @@ -396,9 +377,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ */ def containsSlice[B](that: GenSeq[B]): Boolean = indexOfSlice(that) != -1 - @bridge - def containsSlice[B](that: Seq[B]): Boolean = containsSlice(that: GenSeq[B]) - /** Tests whether this $coll contains a given value as an element. * $mayNotTerminateInf * @@ -463,9 +441,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ b.result } - @bridge - def diff[B >: A](that: Seq[B]): Repr = diff(that: GenSeq[B]) - /** Computes the multiset intersection between this $coll and another sequence. * * @param that the sequence of elements to intersect with. @@ -499,9 +474,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ b.result } - @bridge - def intersect[B >: A](that: Seq[B]): Repr = intersect(that: GenSeq[B]) - private def occCounts[B](sq: Seq[B]): mutable.Map[B, Int] = { val occ = new mutable.HashMap[B, Int] { override def default(k: B) = 0 } for (y <- sq.seq) occ(y) += 1 @@ -534,10 +506,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ b.result } - @bridge - def patch[B >: A, That](from: Int, patch: Seq[B], replaced: Int)(implicit bf: CanBuildFrom[Repr, B, That]): That = - this.patch(from, patch: GenSeq[B], replaced)(bf) - def updated[B >: A, That](index: Int, elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) val (prefix, rest) = this.splitAt(index) @@ -583,10 +551,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[ !i.hasNext && !j.hasNext } - @bridge - def corresponds[B](that: Seq[B])(p: (A,B) => Boolean): Boolean = - corresponds(that: GenSeq[B])(p) - /** Sorts this $coll according to a comparison function. * $willNotTerminateInf * diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index a32cad08e5..9b697a164c 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -132,13 +132,9 @@ trait SeqViewLike[+A, override def diff[B >: A](that: GenSeq[B]): This = newForced(thisSeq diff that).asInstanceOf[This] - @bridge def diff[B >: A](that: Seq[B]): This = diff(that: GenSeq[B]) - override def intersect[B >: A](that: GenSeq[B]): This = newForced(thisSeq intersect that).asInstanceOf[This] - @bridge def intersect[B >: A](that: Seq[B]): This = intersect(that: GenSeq[B]) - override def sorted[B >: A](implicit ord: Ordering[B]): This = newForced(thisSeq sorted ord).asInstanceOf[This] diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala index 7293f3775c..04ec4af830 100644 --- a/src/library/scala/collection/SetLike.scala +++ b/src/library/scala/collection/SetLike.scala @@ -127,9 +127,6 @@ self => */ def ++ (elems: GenTraversableOnce[A]): This = (repr /: elems.seq)(_ + _) - @bridge - def ++ (elems: TraversableOnce[A]): This = ++ (elems: GenTraversableOnce[A]) - /** Creates a new set with a given element removed from this set. * * @param elem the element to be removed @@ -152,9 +149,6 @@ self => */ def union(that: GenSet[A]): This = this ++ that - @bridge - def union(that: Set[A]): This = union(that: GenSet[A]) - /** Computes the difference of this set and another set. * * @param that the set of elements to exclude. @@ -163,9 +157,6 @@ self => */ def diff(that: GenSet[A]): This = this -- that - @bridge - def diff(that: Set[A]): This = diff(that: GenSet[A]) - /** An iterator over all subsets of this set of the given size. * If the requested size is impossible, an empty iterator is returned. * diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index a65be3ffcc..e75000297f 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -28,12 +28,6 @@ trait Traversable[+A] extends TraversableLike[A, Traversable[A]] override def seq: Traversable[A] = this - @bridge - def flatten[B](implicit asTraversable: A => /*<: /*<:: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = - ++(that: GenTraversableOnce[B])(bf) - /** As with `++`, returns a new collection containing the elements from the left operand followed by the * elements from the right operand. * diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala index 3bd63c08b8..3664fe1b4f 100644 --- a/src/library/scala/collection/generic/GenSeqFactory.scala +++ b/src/library/scala/collection/generic/GenSeqFactory.scala @@ -19,9 +19,4 @@ import language.higherKinds * @since 2.8 */ abstract class GenSeqFactory[CC[X] <: GenSeq[X] with GenericTraversableTemplate[X, CC]] -extends GenTraversableFactory[CC] { - - @bridge - def unapplySeq[A](x: GenSeq[A]): Some[GenSeq[A]] = Some(x) - -} +extends GenTraversableFactory[CC] diff --git a/src/library/scala/collection/generic/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala index 4c0c34733c..79cc2f13d4 100644 --- a/src/library/scala/collection/generic/GenericSeqCompanion.scala +++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala @@ -14,12 +14,4 @@ import annotation.bridge import language.higherKinds trait GenericSeqCompanion[CC[X] <: Traversable[X]] - extends GenericCompanion[CC] { - - @bridge - override def empty[A]: CC[A] = super.empty[A] - - @bridge - override def apply[A](elems: A*): CC[A] = super.apply(elems: _*) - -} + extends GenericCompanion[CC] \ No newline at end of file diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index b26e07393c..69eab43150 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -147,11 +147,6 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew b.result } - // cannot have a bridge, because it would have the same signature as the target method after erasure - // @bridge - // def flatten[B](implicit asTraversable: A => /*<: GenTraversableOnce[B]) - /** Transposes this $coll of traversable collections into * a $coll of ${coll}s. * diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index e502c4067e..5a6d825aa8 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -36,6 +36,4 @@ abstract class MapFactory[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]] ex def empty[A, B]: CC[A, B] - @bridge - override def apply[A, B](elems: (A, B)*): CC[A, B] = super.apply(elems: _*) } diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index fb99f83ebb..7443bfbf6a 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -16,11 +16,4 @@ import annotation.bridge import language.higherKinds abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] - extends GenSetFactory[CC] with GenericSeqCompanion[CC] { - - @bridge - override def empty[A]: CC[A] = super.empty[A] - - @bridge - override def apply[A](elems: A*): CC[A] = super.apply(elems: _*) -} + extends GenSetFactory[CC] with GenericSeqCompanion[CC] \ No newline at end of file diff --git a/src/library/scala/collection/generic/Subtractable.scala b/src/library/scala/collection/generic/Subtractable.scala index 1ca9d706f0..ef4f466119 100644 --- a/src/library/scala/collection/generic/Subtractable.scala +++ b/src/library/scala/collection/generic/Subtractable.scala @@ -58,7 +58,4 @@ trait Subtractable[A, +Repr <: Subtractable[A, Repr]] { self => * except one less occurrence of each of the elements of `elems`. */ def --(xs: GenTraversableOnce[A]): Repr = (repr /: xs.seq) (_ - _) - - @bridge - def --(xs: TraversableOnce[A]): Repr = --(xs: GenTraversableOnce[A]) } diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index 07da1bb5c2..e99c77c4f1 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -37,48 +37,5 @@ import language.higherKinds * @see GenericCanBuildFrom */ trait TraversableFactory[CC[X] <: Traversable[X] with GenericTraversableTemplate[X, CC]] - extends GenTraversableFactory[CC] with GenericSeqCompanion[CC] { - - @bridge - override def concat[A](xss: Traversable[A]*): CC[A] = super.concat(xss: _*) - - @bridge - override def fill[A](n: Int)(elem: => A): CC[A] = super.fill(n)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int)(elem: => A): CC[CC[A]] = super.fill(n1, n2)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int, n3: Int)(elem: => A): CC[CC[CC[A]]] = super.fill(n1, n2, n3)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): CC[CC[CC[CC[A]]]] = super.fill(n1, n2, n3, n4)(elem) - - @bridge - override def fill[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): CC[CC[CC[CC[CC[A]]]]] = super.fill(n1, n2, n3, n4, n5)(elem) - - @bridge - override def tabulate[A](n: Int)(f: Int => A): CC[A] = super.tabulate(n)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int)(f: (Int, Int) => A): CC[CC[A]] = super.tabulate(n1, n2)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): CC[CC[CC[A]]] = super.tabulate(n1, n2, n3)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): CC[CC[CC[CC[A]]]] = super.tabulate(n1, n2, n3, n4)(f) - - @bridge - override def tabulate[A](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): CC[CC[CC[CC[CC[A]]]]] = super.tabulate(n1, n2, n3, n4, n5)(f) - - @bridge - override def range[T: Integral](start: T, end: T): CC[T] = super.range(start, end) - - @bridge - override def range[T: Integral](start: T, end: T, step: T): CC[T] = super.range(start, end, step) - - @bridge - override def iterate[A](start: A, len: Int)(f: A => A): CC[A] = super.iterate(start, len)(f) -} + extends GenTraversableFactory[CC] with GenericSeqCompanion[CC] diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index e008fb86e3..9289b35632 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -105,9 +105,6 @@ extends AbstractMap[A, B] override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): ListMap[A, B1] = ((repr: ListMap[A, B1]) /: xs.seq) (_ + _) - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): ListMap[A, B1] = - ++(xs: GenTraversableOnce[(A, B1)]) - /** This creates a new mapping without the given `key`. * If the map does not contain a mapping for the given key, the * method returns the same map. diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index b71071d3c0..0331e01f35 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -102,8 +102,6 @@ class ListSet[A] extends AbstractSet[A] if (xs.isEmpty) this else (new ListSet.ListSetBuilder(this) ++= xs.seq).result - @bridge def ++(xs: TraversableOnce[A]): ListSet[A] = ++(xs: GenTraversableOnce[A]): ListSet[A] - private[ListSet] def unchecked_+(e: A): ListSet[A] = new Node(e) private[ListSet] def unchecked_outer: ListSet[A] = throw new NoSuchElementException("Empty ListSet has no outer pointer") diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index 80da1ab010..090c7f3043 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -86,8 +86,6 @@ trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): immutable.Map[A, B1] = ((repr: immutable.Map[A, B1]) /: xs.seq) (_ + _) - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): immutable.Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** Filters this map by retaining only keys satisfying a predicate. * @param p the predicate used to test keys * @return an immutable map consisting only of those key value pairs of this map where the key satisfies diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index b72d83f896..3eb37e99fc 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -400,8 +400,5 @@ object Range { } @deprecated("use Range instead", "2.9.0") - trait ByOne extends Range { -// @bridge override def foreach[@specialized(Unit) U](f: Int => U) = -// super.foreach(f) - } + trait ByOne extends Range } diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index 902a0f8457..05248e5805 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -77,8 +77,6 @@ trait SortedMap[A, +B] extends Map[A, B] */ override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): SortedMap[A, B1] = ((repr: SortedMap[A, B1]) /: xs.seq) (_ + _) - - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): SortedMap[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) } /** $factoryInfo diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index dc4f79be35..5c85621b0f 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -162,8 +162,6 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi override def ++[B1 >: B] (xs: GenTraversableOnce[(A, B1)]): TreeMap[A, B1] = ((repr: TreeMap[A, B1]) /: xs.seq) (_ + _) - @bridge def ++[B1 >: B] (xs: TraversableOnce[(A, B1)]): TreeMap[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** A new TreeMap with the entry added is returned, * assuming that key is not in the TreeMap. * diff --git a/src/library/scala/collection/mutable/BufferLike.scala b/src/library/scala/collection/mutable/BufferLike.scala index 1dc2fc27d5..f82a596b32 100644 --- a/src/library/scala/collection/mutable/BufferLike.scala +++ b/src/library/scala/collection/mutable/BufferLike.scala @@ -223,9 +223,6 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] @migration("`++` creates a new buffer. Use `++=` to add an element from this buffer and return that buffer itself.", "2.8.0") def ++(xs: GenTraversableOnce[A]): This = clone() ++= xs.seq - @bridge - def ++(xs: TraversableOnce[A]): This = ++(xs: GenTraversableOnce[A]) - /** Creates a new collection with all the elements of this collection except `elem`. * * @param elem the element to remove. @@ -255,6 +252,4 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]] */ @migration("`--` creates a new buffer. Use `--=` to remove an element from this buffer and return that buffer itself.", "2.8.0") override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq - - @bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A]) } diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala index b08a4b7bc9..b8b1152099 100644 --- a/src/library/scala/collection/mutable/MapLike.scala +++ b/src/library/scala/collection/mutable/MapLike.scala @@ -119,8 +119,6 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1] = clone().asInstanceOf[Map[A, B1]] ++= xs.seq - @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)]) - /** Removes a key from this map, returning the value associated previously * with that key as an option. * @param key the key to be removed @@ -224,6 +222,4 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] */ @migration("`--` creates a new map. Use `--=` to remove an element from this map and return that map itself.", "2.8.0") override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq - - @bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A]) } diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 381cb09e18..324af77dd4 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -113,9 +113,6 @@ class PriorityQueue[A](implicit val ord: Ordering[A]) */ def ++(xs: GenTraversableOnce[A]): PriorityQueue[A] = { this.clone() ++= xs.seq } - @bridge - def ++(xs: TraversableOnce[A]): PriorityQueue[A] = ++ (xs: GenTraversableOnce[A]) - /** Adds all elements to the queue. * * @param elems the elements to add. diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala index 5e201d9959..37313c8ca3 100644 --- a/src/library/scala/collection/mutable/SetLike.scala +++ b/src/library/scala/collection/mutable/SetLike.scala @@ -170,8 +170,6 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] @migration("`++` creates a new set. Use `++=` to add elements to this set and return that set itself.", "2.8.0") override def ++(xs: GenTraversableOnce[A]): This = clone() ++= xs.seq - @bridge def ++(xs: TraversableOnce[A]): This = ++(xs: GenTraversableOnce[A]) - /** Creates a new set consisting of all the elements of this set except `elem`. * * @param elem the element to remove. @@ -203,8 +201,6 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]] @migration("`--` creates a new set. Use `--=` to remove elements from this set and return that set itself.", "2.8.0") override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq - @bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A]) - /** Send a message to this scriptable object. * * @param cmd the message to send. diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 1ef1911fd3..e50f854bc5 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -84,11 +84,6 @@ package object scala { @deprecated("Use Thread.currentThread instead", "2.9.0") def currentThread = java.lang.Thread.currentThread() - // Moved back into Predef to avoid unnecessary indirection by - // way of the scala package object within the standard library, - // but bridged for compatibility. - @bridge def $scope = scala.xml.TopScope - // Numeric types which were moved into scala.math.* type BigDecimal = scala.math.BigDecimal diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index cf5aab0be4..fcacb9c82a 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -37,9 +37,6 @@ final class RichInt(val self: Int) extends ScalaNumberProxy[Int] with RangedProx */ def until(end: Int, step: Int): Range = Range(self, end, step) -// @bridge -// def until(end: Int): Range with Range.ByOne = new Range(self, end, 1) with Range.ByOne - /** like `until`, but includes the last index */ /** * @param end The final bound of the range to make. @@ -56,9 +53,6 @@ final class RichInt(val self: Int) extends ScalaNumberProxy[Int] with RangedProx */ def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(self, end, step) -// @bridge -// def to(end: Int): Range with Range.ByOne = new Range.Inclusive(self, end, 1) with Range.ByOne - /** * @return `'''this'''` if `'''this''' < that` or `that` otherwise */ -- cgit v1.2.3 From 14144be0bcd3f6823a9622c6f962aed295ef3392 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 11:52:10 -0700 Subject: Removed a few more @deprecated members. The ones which remain I'm not removing on purpose, as I know from experience it's more trouble than it's yet worth. --- src/compiler/scala/reflect/internal/TreeGen.scala | 15 ++++++++------- src/compiler/scala/tools/nsc/javac/JavaParsers.scala | 13 +++++++------ src/library/scala/Predef.scala | 7 ------- src/library/scala/collection/immutable/Range.scala | 3 --- src/library/scala/package.scala | 13 ------------- src/library/scala/reflect/makro/internal/macroImpl.scala | 2 +- src/library/scala/runtime/package.scala | 12 +----------- test/files/neg/annot-nonconst.check | 4 ++-- test/files/neg/annot-nonconst.scala | 4 ++-- test/files/neg/reify_ann2b.check | 8 ++++---- test/files/neg/reify_ann2b.scala | 2 +- test/files/pos/annot-inner.scala | 2 +- test/files/pos/annotDepMethType.scala | 2 +- test/files/pos/annotations.scala | 10 +++++----- test/files/pos/attributes.scala | 14 +++++++------- test/files/pos/spec-annotations.scala | 2 +- test/files/pos/t1029/Test_1.scala | 2 +- test/files/pos/t1203.scala | 2 +- test/files/pos/t1942/A_1.scala | 2 +- test/files/pos/t2868/pick_1.scala | 2 +- test/files/pos/t3800.scala | 2 +- test/files/pos/t3951/Coll_1.scala | 2 +- test/files/run/bugs.scala | 3 +-- .../files/run/macro-declared-in-annotation/Macros_2.scala | 2 +- test/files/run/reify_ann1a.scala | 2 +- test/files/run/reify_ann1b.scala | 2 +- test/files/run/reify_ann2a.scala | 2 +- test/files/run/reify_classfileann_a.scala | 2 +- test/files/run/reify_classfileann_b.scala | 2 +- test/files/run/t1500.scala | 2 +- test/files/run/t1501.scala | 2 +- test/files/run/t5224.scala | 2 +- test/files/run/t5419.scala | 2 +- test/files/run/t5423.scala | 2 +- 34 files changed, 59 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index f30ec67c7e..f2f9842595 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -7,13 +7,14 @@ abstract class TreeGen extends api.AbsTreeGen { import global._ import definitions._ - def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name) - def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) - def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) - def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass - def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass - def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass - def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass + def rootId(name: Name) = Select(Ident(nme.ROOTPKG), name) + def rootScalaDot(name: Name) = Select(rootId(nme.scala_) setSymbol ScalaPackage, name) + def scalaDot(name: Name) = Select(Ident(nme.scala_) setSymbol ScalaPackage, name) + def scalaAnnotationDot(name: Name) = Select(scalaDot(nme.annotation), name) + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) setSymbol AnyRefClass + def scalaUnitConstr = scalaDot(tpnme.Unit) setSymbol UnitClass + def productConstr = scalaDot(tpnme.Product) setSymbol ProductRootClass + def serializableConstr = scalaDot(tpnme.Serializable) setSymbol SerializableClass def scalaFunctionConstr(argtpes: List[Tree], restpe: Tree, abstractFun: Boolean = false): Tree = { val cls = if (abstractFun) diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index ca3f3ff635..5c413243e8 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -789,23 +789,24 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { val idefs = members.toList ::: (sdefs flatMap forwarders) (sdefs, idefs) } - + def annotationParents = List( + gen.scalaAnnotationDot(tpnme.Annotation), + Select(javaLangDot(nme.annotation), tpnme.Annotation), + gen.scalaAnnotationDot(tpnme.ClassfileAnnotation) + ) def annotationDecl(mods: Modifiers): List[Tree] = { accept(AT) accept(INTERFACE) val pos = in.currentPos val name = identForType() - val parents = List(scalaDot(tpnme.Annotation), - Select(javaLangDot(nme.annotation), tpnme.Annotation), - scalaDot(tpnme.ClassfileAnnotation)) val (statics, body) = typeBody(AT, name) def getValueMethodType(tree: Tree) = tree match { case DefDef(_, nme.value, _, _, tpt, _) => Some(tpt.duplicate) case _ => None } - var templ = makeTemplate(parents, body) + var templ = makeTemplate(annotationParents, body) for (stat <- templ.body; tpt <- getValueMethodType(stat)) - templ = makeTemplate(parents, makeConstructor(List(tpt)) :: templ.body) + templ = makeTemplate(annotationParents, makeConstructor(List(tpt)) :: templ.body) addCompanionObject(statics, atPos(pos) { ClassDef(mods, name, List(), templ) }) diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index d2aa3a8b34..b84fcc4126 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -468,13 +468,6 @@ object Predef extends LowPriorityImplicits { implicit def tpEquals[A]: A =:= A = singleton_=:=.asInstanceOf[A =:= A] } - // less useful due to #2781 - @deprecated("Use From => To instead", "2.9.0") - sealed abstract class <%<[-From, +To] extends (From => To) with Serializable - object <%< { - implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x} - } - /** A type for which there is always an implicit value. * @see fallbackCanBuildFrom in Array.scala */ diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 3eb37e99fc..07c8df57ba 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -398,7 +398,4 @@ object Range { def apply(start: Int, end: Int, step: Int) = NumericRange(start, end, step) def inclusive(start: Int, end: Int, step: Int) = NumericRange.inclusive(start, end, step) } - - @deprecated("use Range instead", "2.9.0") - trait ByOne extends Range } diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index e50f854bc5..064ccd7735 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -80,10 +80,6 @@ package object scala { type Range = scala.collection.immutable.Range val Range = scala.collection.immutable.Range - // Migrated from Predef - @deprecated("Use Thread.currentThread instead", "2.9.0") - def currentThread = java.lang.Thread.currentThread() - // Numeric types which were moved into scala.math.* type BigDecimal = scala.math.BigDecimal @@ -127,13 +123,4 @@ package object scala { type unchecked = annotation.unchecked.unchecked type volatile = annotation.volatile */ - - @deprecated("use scala.annotation.Annotation instead", "2.9.0") - type Annotation = scala.annotation.Annotation - @deprecated("use scala.annotation.ClassfileAnnotation instead", "2.9.0") - type ClassfileAnnotation = scala.annotation.ClassfileAnnotation - @deprecated("use scala.annotation.StaticAnnotation instead", "2.9.0") - type StaticAnnotation = scala.annotation.StaticAnnotation - @deprecated("use scala.annotation.TypeConstraint instead", "2.9.0") - type TypeConstraint = scala.annotation.TypeConstraint } diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/makro/internal/macroImpl.scala index 86600ba0a1..9cf4d23072 100644 --- a/src/library/scala/reflect/makro/internal/macroImpl.scala +++ b/src/library/scala/reflect/makro/internal/macroImpl.scala @@ -2,4 +2,4 @@ package scala.reflect.makro package internal /** This type is required by the compiler and should not be used in client code. */ -class macroImpl(val referenceToMacroImpl: Any) extends StaticAnnotation +class macroImpl(val referenceToMacroImpl: Any) extends annotation.StaticAnnotation diff --git a/src/library/scala/runtime/package.scala b/src/library/scala/runtime/package.scala index 9c87baf6a7..e4472b3ea1 100644 --- a/src/library/scala/runtime/package.scala +++ b/src/library/scala/runtime/package.scala @@ -1,13 +1,3 @@ package scala -package object runtime { - @deprecated("Use `scala.Unit` instead.", "2.9.0") val Unit = scala.Unit - @deprecated("Use `scala.Boolean` instead.", "2.9.0") val Boolean = scala.Boolean - @deprecated("Use `scala.Byte` instead.", "2.9.0") val Byte = scala.Byte - @deprecated("Use `scala.Short` instead.", "2.9.0") val Short = scala.Short - @deprecated("Use `scala.Char` instead.", "2.9.0") val Char = scala.Char - @deprecated("Use `scala.Int` instead.", "2.9.0") val Int = scala.Int - @deprecated("Use `scala.Long` instead.", "2.9.0") val Long = scala.Long - @deprecated("Use `scala.Float` instead.", "2.9.0") val Float = scala.Float - @deprecated("Use `scala.Double` instead.", "2.9.0") val Double = scala.Double -} +package object runtime { } diff --git a/test/files/neg/annot-nonconst.check b/test/files/neg/annot-nonconst.check index e4166e08b6..b43e58a0ca 100644 --- a/test/files/neg/annot-nonconst.check +++ b/test/files/neg/annot-nonconst.check @@ -1,12 +1,12 @@ annot-nonconst.scala:1: warning: Implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java. -class Length(value: Int) extends ClassfileAnnotation +class Length(value: Int) extends annotation.ClassfileAnnotation ^ annot-nonconst.scala:2: warning: Implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java. -class Ann2(value: String) extends ClassfileAnnotation +class Ann2(value: String) extends annotation.ClassfileAnnotation ^ annot-nonconst.scala:6: error: annotation argument needs to be a constant; found: n @Length(n) def foo = "foo" diff --git a/test/files/neg/annot-nonconst.scala b/test/files/neg/annot-nonconst.scala index 69bb60d34e..1b5856f8b2 100644 --- a/test/files/neg/annot-nonconst.scala +++ b/test/files/neg/annot-nonconst.scala @@ -1,5 +1,5 @@ -class Length(value: Int) extends ClassfileAnnotation -class Ann2(value: String) extends ClassfileAnnotation +class Length(value: Int) extends annotation.ClassfileAnnotation +class Ann2(value: String) extends annotation.ClassfileAnnotation object Test { def n = 15 diff --git a/test/files/neg/reify_ann2b.check b/test/files/neg/reify_ann2b.check index b9dd84c1ee..52bdbe5b7c 100644 --- a/test/files/neg/reify_ann2b.check +++ b/test/files/neg/reify_ann2b.check @@ -1,4 +1,4 @@ -reify_ann2b.scala:6: error: inner classes cannot be classfile annotations - class ann(bar: String) extends ClassfileAnnotation - ^ -one error found +reify_ann2b.scala:6: error: inner classes cannot be classfile annotations + class ann(bar: String) extends annotation.ClassfileAnnotation + ^ +one error found diff --git a/test/files/neg/reify_ann2b.scala b/test/files/neg/reify_ann2b.scala index 6b6da8f790..397d00210d 100644 --- a/test/files/neg/reify_ann2b.scala +++ b/test/files/neg/reify_ann2b.scala @@ -3,7 +3,7 @@ import scala.reflect.mirror._ object Test extends App { // test 1: reify val tree = reify{ - class ann(bar: String) extends ClassfileAnnotation + class ann(bar: String) extends annotation.ClassfileAnnotation @ann(bar="1a") @ann(bar="1b") class C[@ann(bar="2a") @ann(bar="2b") T](@ann(bar="3a") @ann(bar="3b") x: T @ann(bar="4a") @ann(bar="4b")) { @ann(bar="5a") @ann(bar="5b") def f(x: Int @ann(bar="6a") @ann(bar="6b")) = { diff --git a/test/files/pos/annot-inner.scala b/test/files/pos/annot-inner.scala index f2ecb5ddb3..9f155a5a83 100644 --- a/test/files/pos/annot-inner.scala +++ b/test/files/pos/annot-inner.scala @@ -1,5 +1,5 @@ object test { - class annot extends Annotation + class annot extends scala.annotation.Annotation def foo { @annot def bar(i: Int): Int = i diff --git a/test/files/pos/annotDepMethType.scala b/test/files/pos/annotDepMethType.scala index b5e7cb9e8b..079ca6224c 100644 --- a/test/files/pos/annotDepMethType.scala +++ b/test/files/pos/annotDepMethType.scala @@ -1,4 +1,4 @@ -case class pc(calls: Any*) extends TypeConstraint +case class pc(calls: Any*) extends annotation.TypeConstraint object Main { class C0 { def baz: String = "" } diff --git a/test/files/pos/annotations.scala b/test/files/pos/annotations.scala index 4e5fddda39..706a715bad 100644 --- a/test/files/pos/annotations.scala +++ b/test/files/pos/annotations.scala @@ -1,5 +1,5 @@ -class ann(i: Int) extends Annotation -class cfann(x: String) extends ClassfileAnnotation +class ann(i: Int) extends scala.annotation.Annotation +class cfann(x: String) extends annotation.ClassfileAnnotation // annotations on abstract types abstract class C1[@serializable @cloneable +T, U, V[_]] @@ -91,9 +91,9 @@ trait BeanF { } -class Ann3(arr: Array[String]) extends ClassfileAnnotation -class Ann4(i: Int) extends ClassfileAnnotation -class Ann5(value: Class[_]) extends ClassfileAnnotation +class Ann3(arr: Array[String]) extends annotation.ClassfileAnnotation +class Ann4(i: Int) extends annotation.ClassfileAnnotation +class Ann5(value: Class[_]) extends annotation.ClassfileAnnotation object Test3 { final val i = 1083 diff --git a/test/files/pos/attributes.scala b/test/files/pos/attributes.scala index f3bbb4c42e..ec735d0aae 100644 --- a/test/files/pos/attributes.scala +++ b/test/files/pos/attributes.scala @@ -52,15 +52,15 @@ object O6 { } object myAttrs { - class a1 extends scala.Annotation; - class a2(x: Int) extends scala.Annotation; - class a3(x: a1) extends scala.Annotation; + class a1 extends scala.annotation.Annotation; + class a2(x: Int) extends scala.annotation.Annotation; + class a3(x: a1) extends scala.annotation.Annotation; } -class a4(ns: Array[Int]) extends scala.Annotation; +class a4(ns: Array[Int]) extends scala.annotation.Annotation; object O7 { - class a1 extends scala.Annotation; - class a2(x: Int) extends scala.Annotation; - class a3(x: a1) extends scala.Annotation; + class a1 extends scala.annotation.Annotation; + class a2(x: Int) extends scala.annotation.Annotation; + class a3(x: a1) extends scala.annotation.Annotation; final val x = new a1; @a1 class C1; diff --git a/test/files/pos/spec-annotations.scala b/test/files/pos/spec-annotations.scala index 35cab6de09..48281e5df5 100644 --- a/test/files/pos/spec-annotations.scala +++ b/test/files/pos/spec-annotations.scala @@ -1,4 +1,4 @@ -class ann(i: Int) extends Annotation +class ann(i: Int) extends scala.annotation.Annotation // annotations on abstract types abstract class C1[@serializable @cloneable +T, U, V[_]] diff --git a/test/files/pos/t1029/Test_1.scala b/test/files/pos/t1029/Test_1.scala index e828087f2c..d268c71429 100644 --- a/test/files/pos/t1029/Test_1.scala +++ b/test/files/pos/t1029/Test_1.scala @@ -1,4 +1,4 @@ -class ann(a: Array[Int]) extends StaticAnnotation +class ann(a: Array[Int]) extends annotation.StaticAnnotation object Test1 { // bug #1029 diff --git a/test/files/pos/t1203.scala b/test/files/pos/t1203.scala index 4938621aa9..062ef93fc6 100644 --- a/test/files/pos/t1203.scala +++ b/test/files/pos/t1203.scala @@ -1,4 +1,4 @@ -case class ant(t: String) extends Annotation +case class ant(t: String) extends scala.annotation.Annotation object Test { def main(args: Array[String]): Unit = { val a: scala.xml.NodeSeq @ant("12") = Nil diff --git a/test/files/pos/t1942/A_1.scala b/test/files/pos/t1942/A_1.scala index 19a7575a0a..4915b54a64 100644 --- a/test/files/pos/t1942/A_1.scala +++ b/test/files/pos/t1942/A_1.scala @@ -3,7 +3,7 @@ class A { def foo(x: String) = 1 } -class ann(x: Int) extends StaticAnnotation +class ann(x: Int) extends annotation.StaticAnnotation class t { val a = new A diff --git a/test/files/pos/t2868/pick_1.scala b/test/files/pos/t2868/pick_1.scala index e91728ec2f..a211687432 100644 --- a/test/files/pos/t2868/pick_1.scala +++ b/test/files/pos/t2868/pick_1.scala @@ -1,4 +1,4 @@ -class ann(s: String) extends StaticAnnotation +class ann(s: String) extends annotation.StaticAnnotation class pick { final val s = "bang!" @ann("bang!") def foo = 1 diff --git a/test/files/pos/t3800.scala b/test/files/pos/t3800.scala index 796eb268c5..61dbeafff3 100644 --- a/test/files/pos/t3800.scala +++ b/test/files/pos/t3800.scala @@ -1,4 +1,4 @@ -class meh extends StaticAnnotation +class meh extends annotation.StaticAnnotation class ALike[C] abstract class AFactory[CC[x] <: ALike[CC[x]]] { diff --git a/test/files/pos/t3951/Coll_1.scala b/test/files/pos/t3951/Coll_1.scala index c2cc39a1a9..556c848688 100644 --- a/test/files/pos/t3951/Coll_1.scala +++ b/test/files/pos/t3951/Coll_1.scala @@ -15,7 +15,7 @@ sealed trait DynamicDocument extends Document { class Coll extends StaticDocument // similiar issue with annotations -class ann[T] extends StaticAnnotation +class ann[T] extends annotation.StaticAnnotation trait StatDoc extends Doc { @ann[StatFB] diff --git a/test/files/run/bugs.scala b/test/files/run/bugs.scala index d5905af76c..ca598603bb 100644 --- a/test/files/run/bugs.scala +++ b/test/files/run/bugs.scala @@ -445,8 +445,7 @@ object Test { test; } catch { case exception => - val curr: String = currentThread.toString(); - Console.print("Exception in thread \"" + curr + "\" " + exception); + Console.print("Exception in thread \"" + Thread.currentThread + "\" " + exception); Console.println; errors += 1 } diff --git a/test/files/run/macro-declared-in-annotation/Macros_2.scala b/test/files/run/macro-declared-in-annotation/Macros_2.scala index a565849aa9..40d71c62fb 100644 --- a/test/files/run/macro-declared-in-annotation/Macros_2.scala +++ b/test/files/run/macro-declared-in-annotation/Macros_2.scala @@ -1,4 +1,4 @@ -class foo(val bar: String) extends StaticAnnotation +class foo(val bar: String) extends annotation.StaticAnnotation object Api { // foo in ann must have a different name diff --git a/test/files/run/reify_ann1a.scala b/test/files/run/reify_ann1a.scala index 1f5d1daccd..6c062ca2c2 100644 --- a/test/files/run/reify_ann1a.scala +++ b/test/files/run/reify_ann1a.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: List[String]) extends StaticAnnotation +class ann(bar: List[String]) extends annotation.StaticAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/reify_ann1b.scala b/test/files/run/reify_ann1b.scala index 13d861a15c..4faddef72c 100644 --- a/test/files/run/reify_ann1b.scala +++ b/test/files/run/reify_ann1b.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: String) extends ClassfileAnnotation +class ann(bar: String) extends annotation.ClassfileAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/reify_ann2a.scala b/test/files/run/reify_ann2a.scala index 370abadba0..a1723c221d 100644 --- a/test/files/run/reify_ann2a.scala +++ b/test/files/run/reify_ann2a.scala @@ -3,7 +3,7 @@ import scala.reflect.mirror._ object Test extends App { // test 1: reify val tree = reify{ - class ann(bar: List[String]) extends StaticAnnotation + class ann(bar: List[String]) extends annotation.StaticAnnotation @ann(bar=List("1a")) @ann(bar=List("1b")) class C[@ann(bar=List("2a")) @ann(bar=List("2b")) T](@ann(bar=List("3a")) @ann(bar=List("3b")) x: T @ann(bar=List("4a")) @ann(bar=List("4b"))) { @ann(bar=List("5a")) @ann(bar=List("5b")) def f(x: Int @ann(bar=List("6a")) @ann(bar=List("6b"))) = { diff --git a/test/files/run/reify_classfileann_a.scala b/test/files/run/reify_classfileann_a.scala index c3e7d8d2e9..9aec69b4a3 100644 --- a/test/files/run/reify_classfileann_a.scala +++ b/test/files/run/reify_classfileann_a.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation +class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends annotation.ClassfileAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/reify_classfileann_b.scala b/test/files/run/reify_classfileann_b.scala index 4e50494af3..a37f20e72e 100644 --- a/test/files/run/reify_classfileann_b.scala +++ b/test/files/run/reify_classfileann_b.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends ClassfileAnnotation +class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends annotation.ClassfileAnnotation object Test extends App { // test 1: reify diff --git a/test/files/run/t1500.scala b/test/files/run/t1500.scala index c312a9a883..586a2666ad 100644 --- a/test/files/run/t1500.scala +++ b/test/files/run/t1500.scala @@ -8,7 +8,7 @@ object Test { val testCode = - class posingAs[A] extends TypeConstraint + class posingAs[A] extends annotation.TypeConstraint def resolve[A,B](x: A @posingAs[B]): B = x.asInstanceOf[B] diff --git a/test/files/run/t1501.scala b/test/files/run/t1501.scala index 05e4da8c7a..dee6e0c68e 100644 --- a/test/files/run/t1501.scala +++ b/test/files/run/t1501.scala @@ -8,7 +8,7 @@ object Test { val testCode = - class xyz[A] extends TypeConstraint + class xyz[A] extends annotation.TypeConstraint def loopWhile[T](cond: =>Boolean)(body: =>(Unit @xyz[T])): Unit @ xyz[T] = {{ if (cond) {{ diff --git a/test/files/run/t5224.scala b/test/files/run/t5224.scala index 93b244e03e..cf65f16457 100644 --- a/test/files/run/t5224.scala +++ b/test/files/run/t5224.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class Foo(bar: String) extends ClassfileAnnotation +class Foo(bar: String) extends annotation.ClassfileAnnotation object Test extends App { val tree = reify{@Foo(bar = "qwe") class C}.tree diff --git a/test/files/run/t5419.scala b/test/files/run/t5419.scala index d65d8f38c8..5f11f5056c 100644 --- a/test/files/run/t5419.scala +++ b/test/files/run/t5419.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -class Foo extends StaticAnnotation +class Foo extends annotation.StaticAnnotation object Test extends App { val tree = reify{(5: @Foo).asInstanceOf[Int]}.tree diff --git a/test/files/run/t5423.scala b/test/files/run/t5423.scala index 645c8c7c1d..ed1faf0429 100644 --- a/test/files/run/t5423.scala +++ b/test/files/run/t5423.scala @@ -1,6 +1,6 @@ import scala.reflect.mirror._ -final class table extends StaticAnnotation +final class table extends annotation.StaticAnnotation @table class A object Test extends App { -- cgit v1.2.3 From 3404d5a9bf750e7022934d6b70035718544be900 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 12:37:12 -0700 Subject: @unspecialized annotation. Suppresses specialization on a per-method basis. I would have preferred to call it @nospecialize, but seeing as the positive form of the annotation is @specialized, that would have sown unnecessary grammatical confusion. @nospecialized sounds a bit too caveman for my tastes. "Grog no specialized! Grog generic!" --- src/build/genprod.scala | 23 +++++++++++----------- .../scala/reflect/internal/Definitions.scala | 1 + .../tools/nsc/transform/SpecializeTypes.scala | 17 ++++++++++------ src/library/scala/Function0.scala | 6 +++--- src/library/scala/Function1.scala | 8 ++++---- src/library/scala/Function10.scala | 7 ++++--- src/library/scala/Function11.scala | 7 ++++--- src/library/scala/Function12.scala | 7 ++++--- src/library/scala/Function13.scala | 7 ++++--- src/library/scala/Function14.scala | 7 ++++--- src/library/scala/Function15.scala | 7 ++++--- src/library/scala/Function16.scala | 7 ++++--- src/library/scala/Function17.scala | 7 ++++--- src/library/scala/Function18.scala | 7 ++++--- src/library/scala/Function19.scala | 7 ++++--- src/library/scala/Function2.scala | 11 ++++++----- src/library/scala/Function20.scala | 7 ++++--- src/library/scala/Function21.scala | 7 ++++--- src/library/scala/Function22.scala | 7 ++++--- src/library/scala/Function3.scala | 7 ++++--- src/library/scala/Function4.scala | 7 ++++--- src/library/scala/Function5.scala | 7 ++++--- src/library/scala/Function6.scala | 7 ++++--- src/library/scala/Function7.scala | 7 ++++--- src/library/scala/Function8.scala | 7 ++++--- src/library/scala/Function9.scala | 7 ++++--- src/library/scala/Tuple2.scala | 13 ++---------- src/library/scala/Tuple3.scala | 13 +----------- src/library/scala/annotation/unspecialized.scala | 17 ++++++++++++++++ .../scala/runtime/AbstractPartialFunction.scala | 8 ++++---- 30 files changed, 141 insertions(+), 116 deletions(-) create mode 100644 src/library/scala/annotation/unspecialized.scala (limited to 'src') diff --git a/src/build/genprod.scala b/src/build/genprod.scala index 1ea0bf7b73..5a77c7a699 100644 --- a/src/build/genprod.scala +++ b/src/build/genprod.scala @@ -130,7 +130,7 @@ object FunctionOne extends Function(1) { * @param g a function A => T1 * @return a new function `f` such that `f(x) == apply(g(x))` */ - def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + @annotation.unspecialized def compose[A](g: A => T1): A => R = { x => apply(g(x)) } /** Composes two instances of Function1 in a new Function1, with this function applied first. * @@ -138,7 +138,7 @@ object FunctionOne extends Function(1) { * @param g a function R => A * @return a new function `f` such that `f(x) == g(apply(x))` */ - def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + @annotation.unspecialized def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } """ } @@ -169,19 +169,20 @@ object Function { class Function(val i: Int) extends Group("Function") with Arity { def descriptiveComment = "" - def functionNTemplate = """ + def functionNTemplate = +""" * In the following example, the definition of %s is a * shorthand for the anonymous class definition %s: * * {{{ - * object Main extends App { %s } + * object Main extends App {%s} * }}} * * Note that `Function1` does not define a total function, as might * be suggested by the existence of [[scala.PartialFunction]]. The only * distinction between `Function1` and `PartialFunction` is that the * latter can specify inputs which it will not handle. - """ +""" def toStr() = "\"" + ("" format i) + "\"" def apply() = { @@ -195,7 +196,7 @@ class Function(val i: Int) extends Group("Function") with Arity { * @return the result of function application. */ def apply({funArgs}): R - {moreMethods} +{moreMethods} override def toString() = {toStr} }} @@ -218,15 +219,15 @@ class Function(val i: Int) extends Group("Function") with Arity { // f(x1,x2,x3,x4,x5,x6) == (f.curried)(x1)(x2)(x3)(x4)(x5)(x6) def curryComment = { -"""/** Creates a curried version of this function. +""" /** Creates a curried version of this function. * * @return a function `f` such that `f%s == apply%s` */""".format(xdefs map ("(" + _ + ")") mkString, commaXs) } def tupleMethod = { - def comment = """ - /** Creates a tupled version of this function: instead of %d arguments, + def comment = +""" /** Creates a tupled version of this function: instead of %d arguments, * it accepts a single [[scala.Tuple%d]] argument. * * @return a function `f` such that `f(%s) == f(Tuple%d%s) == apply%s` @@ -234,14 +235,14 @@ class Function(val i: Int) extends Group("Function") with Arity { """.format(i, i, commaXs, i, commaXs, commaXs) def body = "case Tuple%d%s => apply%s".format(i, commaXs, commaXs) - comment + " def tupled: Tuple%d%s => R = {\n %s\n }".format(i, invariantArgs, body) + comment + "\n @annotation.unspecialized def tupled: Tuple%d%s => R = {\n %s\n }".format(i, invariantArgs, body) } def curryMethod = { val body = if (i < 5) shortCurry else longCurry curryComment + - " def curried: %s => R = {\n %s\n }\n".format( + "\n @annotation.unspecialized def curried: %s => R = {\n %s\n }\n".format( targs mkString " => ", body ) } diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index d89e852124..9e28319882 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -946,6 +946,7 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val ThrowsClass = getRequiredClass("scala.throws") lazy val TransientAttr = getRequiredClass("scala.transient") lazy val UncheckedClass = getRequiredClass("scala.unchecked") + lazy val UnspecializedClass = getRequiredClass("scala.annotation.unspecialized") lazy val VolatileAttr = getRequiredClass("scala.volatile") // Meta-annotations diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 1fb7fac184..f6296acdca 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -68,7 +68,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { import definitions.{ RootClass, BooleanClass, UnitClass, ArrayClass, ScalaValueClasses, isPrimitiveValueClass, isScalaValueType, - SpecializedClass, AnyRefClass, ObjectClass, AnyRefModule, + SpecializedClass, UnspecializedClass, AnyRefClass, ObjectClass, AnyRefModule, GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass } @@ -374,12 +374,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * - members with specialized type parameters found in the given environment * - constructors of specialized classes * - normalized members whose type bounds appear in the environment + * But suppressed for: + * - any member with the @unspecialized annotation, or which has an + * enclosing member with the annotation. */ - private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = { - specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty || - (sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized))) || - (isNormalizedMember(sym) && info(sym).typeBoundsIn(env)) - } + private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = ( + !sym.ownerChain.exists(_ hasAnnotation UnspecializedClass) && ( + specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty + || sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized)) + || isNormalizedMember(sym) && info(sym).typeBoundsIn(env) + ) + ) def isNormalizedMember(m: Symbol) = m.isSpecialized && (info get m exists { case NormalizedMember(_) => true diff --git a/src/library/scala/Function0.scala b/src/library/scala/Function0.scala index dceed26439..e1e9ddb3fb 100644 --- a/src/library/scala/Function0.scala +++ b/src/library/scala/Function0.scala @@ -6,13 +6,13 @@ ** |/ ** \* */ // GENERATED CODE: DO NOT EDIT. -// genprod generated these sources at: Tue Feb 14 16:49:03 PST 2012 +// genprod generated these sources at: Sat Apr 28 12:59:55 PDT 2012 package scala /** A function of 0 parameters. - * + * * In the following example, the definition of javaVersion is a * shorthand for the anonymous class definition anonfun0: * @@ -24,7 +24,7 @@ package scala * def apply(): String = sys.props("java.version") * } * assert(javaVersion() == anonfun0()) - * } + * } * }}} * * Note that `Function1` does not define a total function, as might diff --git a/src/library/scala/Function1.scala b/src/library/scala/Function1.scala index 8995ef912b..f9b37fc6bd 100644 --- a/src/library/scala/Function1.scala +++ b/src/library/scala/Function1.scala @@ -11,7 +11,7 @@ package scala /** A function of 1 parameter. - * + * * In the following example, the definition of succ is a * shorthand for the anonymous class definition anonfun1: * @@ -22,7 +22,7 @@ package scala * def apply(x: Int): Int = x + 1 * } * assert(succ(0) == anonfun1(0)) - * } + * } * }}} * * Note that `Function1` does not define a total function, as might @@ -44,7 +44,7 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s * @param g a function A => T1 * @return a new function `f` such that `f(x) == apply(g(x))` */ - def compose[A](g: A => T1): A => R = { x => apply(g(x)) } + @annotation.unspecialized def compose[A](g: A => T1): A => R = { x => apply(g(x)) } /** Composes two instances of Function1 in a new Function1, with this function applied first. * @@ -52,7 +52,7 @@ trait Function1[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, s * @param g a function R => A * @return a new function `f` such that `f(x) == g(apply(x))` */ - def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } + @annotation.unspecialized def andThen[A](g: R => A): T1 => A = { x => g(apply(x)) } override def toString() = "" } diff --git a/src/library/scala/Function10.scala b/src/library/scala/Function10.scala index 9e107fc53d..f7e5d414f2 100644 --- a/src/library/scala/Function10.scala +++ b/src/library/scala/Function10.scala @@ -21,16 +21,17 @@ trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)).curried } - /** Creates a tupled version of this function: instead of 10 arguments, * it accepts a single [[scala.Tuple10]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) == f(Tuple10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)` */ - def tupled: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] => R = { + + @annotation.unspecialized def tupled: Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] => R = { case Tuple10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) } override def toString() = "" diff --git a/src/library/scala/Function11.scala b/src/library/scala/Function11.scala index 783a86ab5d..53742bf733 100644 --- a/src/library/scala/Function11.scala +++ b/src/library/scala/Function11.scala @@ -21,16 +21,17 @@ trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] ex /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)).curried } - /** Creates a tupled version of this function: instead of 11 arguments, * it accepts a single [[scala.Tuple11]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) == f(Tuple11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)` */ - def tupled: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] => R = { + + @annotation.unspecialized def tupled: Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11] => R = { case Tuple11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) } override def toString() = "" diff --git a/src/library/scala/Function12.scala b/src/library/scala/Function12.scala index 7f4dee6216..e349d9017d 100644 --- a/src/library/scala/Function12.scala +++ b/src/library/scala/Function12.scala @@ -21,16 +21,17 @@ trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)).curried } - /** Creates a tupled version of this function: instead of 12 arguments, * it accepts a single [[scala.Tuple12]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) == f(Tuple12(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)` */ - def tupled: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] => R = { + + @annotation.unspecialized def tupled: Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12] => R = { case Tuple12(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) } override def toString() = "" diff --git a/src/library/scala/Function13.scala b/src/library/scala/Function13.scala index 23853dde69..10ec64b87a 100644 --- a/src/library/scala/Function13.scala +++ b/src/library/scala/Function13.scala @@ -21,16 +21,17 @@ trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)).curried } - /** Creates a tupled version of this function: instead of 13 arguments, * it accepts a single [[scala.Tuple13]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) == f(Tuple13(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)` */ - def tupled: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] => R = { + + @annotation.unspecialized def tupled: Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13] => R = { case Tuple13(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) } override def toString() = "" diff --git a/src/library/scala/Function14.scala b/src/library/scala/Function14.scala index 372f1cfafb..82dd409223 100644 --- a/src/library/scala/Function14.scala +++ b/src/library/scala/Function14.scala @@ -21,16 +21,17 @@ trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)).curried } - /** Creates a tupled version of this function: instead of 14 arguments, * it accepts a single [[scala.Tuple14]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) == f(Tuple14(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)` */ - def tupled: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] => R = { + + @annotation.unspecialized def tupled: Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14] => R = { case Tuple14(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) } override def toString() = "" diff --git a/src/library/scala/Function15.scala b/src/library/scala/Function15.scala index 47c7309695..be5fbeeca1 100644 --- a/src/library/scala/Function15.scala +++ b/src/library/scala/Function15.scala @@ -21,16 +21,17 @@ trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)).curried } - /** Creates a tupled version of this function: instead of 15 arguments, * it accepts a single [[scala.Tuple15]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) == f(Tuple15(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)` */ - def tupled: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] => R = { + + @annotation.unspecialized def tupled: Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15] => R = { case Tuple15(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) } override def toString() = "" diff --git a/src/library/scala/Function16.scala b/src/library/scala/Function16.scala index 8eea42de5b..7a185b369c 100644 --- a/src/library/scala/Function16.scala +++ b/src/library/scala/Function16.scala @@ -21,16 +21,17 @@ trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)).curried } - /** Creates a tupled version of this function: instead of 16 arguments, * it accepts a single [[scala.Tuple16]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) == f(Tuple16(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)` */ - def tupled: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] => R = { + + @annotation.unspecialized def tupled: Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16] => R = { case Tuple16(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) } override def toString() = "" diff --git a/src/library/scala/Function17.scala b/src/library/scala/Function17.scala index 2d93af34f2..94e0000802 100644 --- a/src/library/scala/Function17.scala +++ b/src/library/scala/Function17.scala @@ -21,16 +21,17 @@ trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)).curried } - /** Creates a tupled version of this function: instead of 17 arguments, * it accepts a single [[scala.Tuple17]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) == f(Tuple17(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)` */ - def tupled: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] => R = { + + @annotation.unspecialized def tupled: Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17] => R = { case Tuple17(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) } override def toString() = "" diff --git a/src/library/scala/Function18.scala b/src/library/scala/Function18.scala index ffca98c443..a3ee6776ba 100644 --- a/src/library/scala/Function18.scala +++ b/src/library/scala/Function18.scala @@ -21,16 +21,17 @@ trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)).curried } - /** Creates a tupled version of this function: instead of 18 arguments, * it accepts a single [[scala.Tuple18]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) == f(Tuple18(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)` */ - def tupled: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] => R = { + + @annotation.unspecialized def tupled: Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18] => R = { case Tuple18(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) } override def toString() = "" diff --git a/src/library/scala/Function19.scala b/src/library/scala/Function19.scala index f661ea7707..038dcbb778 100644 --- a/src/library/scala/Function19.scala +++ b/src/library/scala/Function19.scala @@ -21,16 +21,17 @@ trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)).curried } - /** Creates a tupled version of this function: instead of 19 arguments, * it accepts a single [[scala.Tuple19]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) == f(Tuple19(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)` */ - def tupled: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] => R = { + + @annotation.unspecialized def tupled: Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19] => R = { case Tuple19(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) } override def toString() = "" diff --git a/src/library/scala/Function2.scala b/src/library/scala/Function2.scala index cacb96ef5d..0794a4048a 100644 --- a/src/library/scala/Function2.scala +++ b/src/library/scala/Function2.scala @@ -11,7 +11,7 @@ package scala /** A function of 2 parameters. - * + * * In the following example, the definition of max is a * shorthand for the anonymous class definition anonfun2: * @@ -23,7 +23,7 @@ package scala * def apply(x: Int, y: Int): Int = if (x < y) y else x * } * assert(max(0, 1) == anonfun2(0, 1)) - * } + * } * }}} * * Note that `Function1` does not define a total function, as might @@ -40,16 +40,17 @@ trait Function2[@specialized(scala.Int, scala.Long, scala.Double) -T1, @speciali /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2) == apply(x1, x2)` - */ def curried: T1 => T2 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => R = { (x1: T1) => (x2: T2) => apply(x1, x2) } - /** Creates a tupled version of this function: instead of 2 arguments, * it accepts a single [[scala.Tuple2]] argument. * * @return a function `f` such that `f((x1, x2)) == f(Tuple2(x1, x2)) == apply(x1, x2)` */ - def tupled: Tuple2[T1, T2] => R = { + + @annotation.unspecialized def tupled: Tuple2[T1, T2] => R = { case Tuple2(x1, x2) => apply(x1, x2) } override def toString() = "" diff --git a/src/library/scala/Function20.scala b/src/library/scala/Function20.scala index e4fb9f280c..727684d6d5 100644 --- a/src/library/scala/Function20.scala +++ b/src/library/scala/Function20.scala @@ -21,16 +21,17 @@ trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19)(x20) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)).curried } - /** Creates a tupled version of this function: instead of 20 arguments, * it accepts a single [[scala.Tuple20]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) == f(Tuple20(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)` */ - def tupled: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] => R = { + + @annotation.unspecialized def tupled: Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20] => R = { case Tuple20(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) } override def toString() = "" diff --git a/src/library/scala/Function21.scala b/src/library/scala/Function21.scala index 9823386856..2441278be8 100644 --- a/src/library/scala/Function21.scala +++ b/src/library/scala/Function21.scala @@ -21,16 +21,17 @@ trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19)(x20)(x21) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)).curried } - /** Creates a tupled version of this function: instead of 21 arguments, * it accepts a single [[scala.Tuple21]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) == f(Tuple21(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)` */ - def tupled: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] => R = { + + @annotation.unspecialized def tupled: Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21] => R = { case Tuple21(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) } override def toString() = "" diff --git a/src/library/scala/Function22.scala b/src/library/scala/Function22.scala index e708f7f49a..1f70b190a6 100644 --- a/src/library/scala/Function22.scala +++ b/src/library/scala/Function22.scala @@ -21,16 +21,17 @@ trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9)(x10)(x11)(x12)(x13)(x14)(x15)(x16)(x17)(x18)(x19)(x20)(x21)(x22) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => T22 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => T10 => T11 => T12 => T13 => T14 => T15 => T16 => T17 => T18 => T19 => T20 => T21 => T22 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9, x10: T10, x11: T11, x12: T12, x13: T13, x14: T14, x15: T15, x16: T16, x17: T17, x18: T18, x19: T19, x20: T20, x21: T21, x22: T22) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)).curried } - /** Creates a tupled version of this function: instead of 22 arguments, * it accepts a single [[scala.Tuple22]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) == f(Tuple22(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)` */ - def tupled: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] => R = { + + @annotation.unspecialized def tupled: Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22] => R = { case Tuple22(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) } override def toString() = "" diff --git a/src/library/scala/Function3.scala b/src/library/scala/Function3.scala index 62a997c1b5..bbbde82056 100644 --- a/src/library/scala/Function3.scala +++ b/src/library/scala/Function3.scala @@ -21,16 +21,17 @@ trait Function3[-T1, -T2, -T3, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3) == apply(x1, x2, x3)` - */ def curried: T1 => T2 => T3 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => R = { (x1: T1) => (x2: T2) => (x3: T3) => apply(x1, x2, x3) } - /** Creates a tupled version of this function: instead of 3 arguments, * it accepts a single [[scala.Tuple3]] argument. * * @return a function `f` such that `f((x1, x2, x3)) == f(Tuple3(x1, x2, x3)) == apply(x1, x2, x3)` */ - def tupled: Tuple3[T1, T2, T3] => R = { + + @annotation.unspecialized def tupled: Tuple3[T1, T2, T3] => R = { case Tuple3(x1, x2, x3) => apply(x1, x2, x3) } override def toString() = "" diff --git a/src/library/scala/Function4.scala b/src/library/scala/Function4.scala index 86d2faeac8..f100860a97 100644 --- a/src/library/scala/Function4.scala +++ b/src/library/scala/Function4.scala @@ -21,16 +21,17 @@ trait Function4[-T1, -T2, -T3, -T4, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4) == apply(x1, x2, x3, x4)` - */ def curried: T1 => T2 => T3 => T4 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => R = { (x1: T1) => (x2: T2) => (x3: T3) => (x4: T4) => apply(x1, x2, x3, x4) } - /** Creates a tupled version of this function: instead of 4 arguments, * it accepts a single [[scala.Tuple4]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4)) == f(Tuple4(x1, x2, x3, x4)) == apply(x1, x2, x3, x4)` */ - def tupled: Tuple4[T1, T2, T3, T4] => R = { + + @annotation.unspecialized def tupled: Tuple4[T1, T2, T3, T4] => R = { case Tuple4(x1, x2, x3, x4) => apply(x1, x2, x3, x4) } override def toString() = "" diff --git a/src/library/scala/Function5.scala b/src/library/scala/Function5.scala index bd9af77f12..cba9b6ce52 100644 --- a/src/library/scala/Function5.scala +++ b/src/library/scala/Function5.scala @@ -21,16 +21,17 @@ trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5) == apply(x1, x2, x3, x4, x5)` - */ def curried: T1 => T2 => T3 => T4 => T5 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5) => self.apply(x1, x2, x3, x4, x5)).curried } - /** Creates a tupled version of this function: instead of 5 arguments, * it accepts a single [[scala.Tuple5]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5)) == f(Tuple5(x1, x2, x3, x4, x5)) == apply(x1, x2, x3, x4, x5)` */ - def tupled: Tuple5[T1, T2, T3, T4, T5] => R = { + + @annotation.unspecialized def tupled: Tuple5[T1, T2, T3, T4, T5] => R = { case Tuple5(x1, x2, x3, x4, x5) => apply(x1, x2, x3, x4, x5) } override def toString() = "" diff --git a/src/library/scala/Function6.scala b/src/library/scala/Function6.scala index 4f601a468c..0b8addf7de 100644 --- a/src/library/scala/Function6.scala +++ b/src/library/scala/Function6.scala @@ -21,16 +21,17 @@ trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6) == apply(x1, x2, x3, x4, x5, x6)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6) => self.apply(x1, x2, x3, x4, x5, x6)).curried } - /** Creates a tupled version of this function: instead of 6 arguments, * it accepts a single [[scala.Tuple6]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6)) == f(Tuple6(x1, x2, x3, x4, x5, x6)) == apply(x1, x2, x3, x4, x5, x6)` */ - def tupled: Tuple6[T1, T2, T3, T4, T5, T6] => R = { + + @annotation.unspecialized def tupled: Tuple6[T1, T2, T3, T4, T5, T6] => R = { case Tuple6(x1, x2, x3, x4, x5, x6) => apply(x1, x2, x3, x4, x5, x6) } override def toString() = "" diff --git a/src/library/scala/Function7.scala b/src/library/scala/Function7.scala index 6978b6545d..2098658fa9 100644 --- a/src/library/scala/Function7.scala +++ b/src/library/scala/Function7.scala @@ -21,16 +21,17 @@ trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends AnyRef { self => /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7) == apply(x1, x2, x3, x4, x5, x6, x7)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7) => self.apply(x1, x2, x3, x4, x5, x6, x7)).curried } - /** Creates a tupled version of this function: instead of 7 arguments, * it accepts a single [[scala.Tuple7]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7)) == f(Tuple7(x1, x2, x3, x4, x5, x6, x7)) == apply(x1, x2, x3, x4, x5, x6, x7)` */ - def tupled: Tuple7[T1, T2, T3, T4, T5, T6, T7] => R = { + + @annotation.unspecialized def tupled: Tuple7[T1, T2, T3, T4, T5, T6, T7] => R = { case Tuple7(x1, x2, x3, x4, x5, x6, x7) => apply(x1, x2, x3, x4, x5, x6, x7) } override def toString() = "" diff --git a/src/library/scala/Function8.scala b/src/library/scala/Function8.scala index 903551d939..08a480dce5 100644 --- a/src/library/scala/Function8.scala +++ b/src/library/scala/Function8.scala @@ -21,16 +21,17 @@ trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends AnyRef { sel /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8) == apply(x1, x2, x3, x4, x5, x6, x7, x8)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8)).curried } - /** Creates a tupled version of this function: instead of 8 arguments, * it accepts a single [[scala.Tuple8]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8)) == f(Tuple8(x1, x2, x3, x4, x5, x6, x7, x8)) == apply(x1, x2, x3, x4, x5, x6, x7, x8)` */ - def tupled: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] => R = { + + @annotation.unspecialized def tupled: Tuple8[T1, T2, T3, T4, T5, T6, T7, T8] => R = { case Tuple8(x1, x2, x3, x4, x5, x6, x7, x8) => apply(x1, x2, x3, x4, x5, x6, x7, x8) } override def toString() = "" diff --git a/src/library/scala/Function9.scala b/src/library/scala/Function9.scala index 0c273ba929..2e35f7949c 100644 --- a/src/library/scala/Function9.scala +++ b/src/library/scala/Function9.scala @@ -21,16 +21,17 @@ trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends AnyRef /** Creates a curried version of this function. * * @return a function `f` such that `f(x1)(x2)(x3)(x4)(x5)(x6)(x7)(x8)(x9) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9)` - */ def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => R = { + */ + @annotation.unspecialized def curried: T1 => T2 => T3 => T4 => T5 => T6 => T7 => T8 => T9 => R = { (x1: T1) => ((x2: T2, x3: T3, x4: T4, x5: T5, x6: T6, x7: T7, x8: T8, x9: T9) => self.apply(x1, x2, x3, x4, x5, x6, x7, x8, x9)).curried } - /** Creates a tupled version of this function: instead of 9 arguments, * it accepts a single [[scala.Tuple9]] argument. * * @return a function `f` such that `f((x1, x2, x3, x4, x5, x6, x7, x8, x9)) == f(Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9)) == apply(x1, x2, x3, x4, x5, x6, x7, x8, x9)` */ - def tupled: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] => R = { + + @annotation.unspecialized def tupled: Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9] => R = { case Tuple9(x1, x2, x3, x4, x5, x6, x7, x8, x9) => apply(x1, x2, x3, x4, x5, x6, x7, x8, x9) } override def toString() = "" diff --git a/src/library/scala/Tuple2.scala b/src/library/scala/Tuple2.scala index 37ab564c3c..58638f440f 100644 --- a/src/library/scala/Tuple2.scala +++ b/src/library/scala/Tuple2.scala @@ -23,7 +23,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s extends Product2[T1, T2] { override def toString() = "(" + _1 + "," + _2 + ")" - + /** Swaps the elements of this `Tuple`. * @return a new Tuple where the first element is the second element of this Tuple and the * second element is the first element of this Tuple. @@ -31,6 +31,7 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s def swap: Tuple2[T2,T1] = Tuple2(_2, _1) @deprecated("Use `zipped` instead.", "2.9.0") + @annotation.unspecialized def zip[Repr1, El1, El2, To](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => Iterable[El2], cbf1: CBF[Repr1, (El1, El2), To]): To = { @@ -54,16 +55,6 @@ case class Tuple2[@specialized(Int, Long, Double, Char, Boolean, AnyRef) +T1, @s def zipped[Repr1, El1, Repr2, El2](implicit w1: T1 => TLike[El1, Repr1], w2: T2 => ILike[El2, Repr2]): Zipped[Repr1, El1, Repr2, El2] = new Zipped[Repr1, El1, Repr2, El2](_1, _2) - /** - * @define coll zipped - * @define Coll Zipped - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define collectExample - * @define undefinedorder - */ class Zipped[+Repr1, +El1, +Repr2, +El2](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2]) { // coll2: ILike for filter def map[B, To](f: (El1, El2) => B)(implicit cbf: CBF[Repr1, B, To]): To = { val b = cbf(coll1.repr) diff --git a/src/library/scala/Tuple3.scala b/src/library/scala/Tuple3.scala index cd5ee23757..0d5399308b 100644 --- a/src/library/scala/Tuple3.scala +++ b/src/library/scala/Tuple3.scala @@ -24,7 +24,7 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) extends Product3[T1, T2, T3] { override def toString() = "(" + _1 + "," + _2 + "," + _3 + ")" - + @deprecated("Use `zipped` instead.", "2.9.0") def zip[Repr1, El1, El2, El3, To](implicit w1: T1 => TLike[El1, Repr1], @@ -53,17 +53,6 @@ case class Tuple3[+T1, +T2, +T3](_1: T1, _2: T2, _3: T3) w3: T3 => ILike[El3, Repr3]): Zipped[Repr1, El1, Repr2, El2, Repr3, El3] = new Zipped[Repr1, El1, Repr2, El2, Repr3, El3](_1, _2, _3) - /** - * @define coll zipped - * @define Coll Zipped - * @define orderDependent - * @define orderDependentFold - * @define mayNotTerminateInf - * @define willNotTerminateInf - * @define collectExample - * @define undefinedorder - * @define thatInfo The class of the returned collection. - */ class Zipped[+Repr1, +El1, +Repr2, +El2, +Repr3, +El3](coll1: TLike[El1, Repr1], coll2: ILike[El2, Repr2], coll3: ILike[El3, Repr3]) { diff --git a/src/library/scala/annotation/unspecialized.scala b/src/library/scala/annotation/unspecialized.scala new file mode 100644 index 0000000000..28d9aa169c --- /dev/null +++ b/src/library/scala/annotation/unspecialized.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.annotation + +/** A method annotation which suppresses the creation of + * additional specialized forms based on enclosing specialized + * type parameters. + * + * @since 2.10 + */ +class unspecialized extends annotation.StaticAnnotation diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala index 2e435d8a7e..f499350ce9 100644 --- a/src/library/scala/runtime/AbstractPartialFunction.scala +++ b/src/library/scala/runtime/AbstractPartialFunction.scala @@ -36,7 +36,7 @@ abstract class AbstractPartialFunction[@specialized(scala.Int, scala.Long, scala // let's not make it final so as not to confuse anyone /*final*/ def apply(x: T1): R = applyOrElse(x, PartialFunction.empty) - override final def andThen[C](k: R => C) : PartialFunction[T1, C] = + @annotation.unspecialized override final def andThen[C](k: R => C) : PartialFunction[T1, C] = new AbstractPartialFunction[T1, C] { def isDefinedAt(x: T1): Boolean = self.isDefinedAt(x) override def applyOrElse[A1 <: T1, C1 >: C](x: A1, default: A1 => C1): C1 = @@ -61,8 +61,8 @@ abstract class AbstractPartialFunction[@specialized(scala.Int, scala.Long, scala */ abstract class AbstractTotalFunction[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, scala.AnyRef) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double, scala.AnyRef) +R] extends Function1[T1, R] with PartialFunction[T1, R] { final def isDefinedAt(x: T1): Boolean = true - override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x) - override final def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = this + @annotation.unspecialized override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x) + @annotation.unspecialized override final def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = this //TODO: check generated code for PF literal here - override final def andThen[C](k: R => C): PartialFunction[T1, C] = { case x => k(apply(x)) } + @annotation.unspecialized override final def andThen[C](k: R => C): PartialFunction[T1, C] = { case x => k(apply(x)) } } -- cgit v1.2.3 From 774cd4f87b1ef1ba0b0850f1934fa1539b0e2bce Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 14:13:42 -0700 Subject: Removed all the imports of the bridge annotation. Now that nothing uses it. --- src/library/scala/annotation/bridge.scala | 1 + src/library/scala/collection/GenSeqLike.scala | 1 - src/library/scala/collection/GenSetLike.scala | 1 - src/library/scala/collection/IterableLike.scala | 1 - src/library/scala/collection/SeqLike.scala | 1 - src/library/scala/collection/SeqViewLike.scala | 1 - src/library/scala/collection/Traversable.scala | 1 - src/library/scala/collection/generic/GenSeqFactory.scala | 1 - src/library/scala/collection/generic/GenericSeqCompanion.scala | 1 - src/library/scala/collection/generic/MapFactory.scala | 1 - src/library/scala/collection/generic/SetFactory.scala | 1 - src/library/scala/collection/generic/Subtractable.scala | 1 - src/library/scala/collection/generic/TraversableFactory.scala | 1 - src/library/scala/collection/immutable/MapLike.scala | 1 - src/library/scala/collection/immutable/Range.scala | 1 - src/library/scala/collection/immutable/SortedMap.scala | 1 - src/library/scala/collection/immutable/TreeMap.scala | 1 - src/library/scala/collection/mutable/PriorityQueue.scala | 1 - src/library/scala/package.scala | 1 - src/library/scala/runtime/RichInt.scala | 1 - 20 files changed, 1 insertion(+), 19 deletions(-) (limited to 'src') diff --git a/src/library/scala/annotation/bridge.scala b/src/library/scala/annotation/bridge.scala index 690370854e..a56129fb96 100644 --- a/src/library/scala/annotation/bridge.scala +++ b/src/library/scala/annotation/bridge.scala @@ -10,4 +10,5 @@ package scala.annotation /** If this annotation is present on a method, it will be treated as a bridge method. */ +@deprecated("Reconsider whether using this annotation will accomplish anything", "2.10.0") private[scala] class bridge extends annotation.StaticAnnotation diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index 646fe09855..fd7892c9f9 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -9,7 +9,6 @@ package scala.collection import generic._ -import annotation.bridge /** A template trait for all sequences which may be traversed * in parallel. diff --git a/src/library/scala/collection/GenSetLike.scala b/src/library/scala/collection/GenSetLike.scala index a576014445..219374abc6 100644 --- a/src/library/scala/collection/GenSetLike.scala +++ b/src/library/scala/collection/GenSetLike.scala @@ -8,7 +8,6 @@ package scala.collection -import annotation.bridge /** A template trait for sets which may possibly * have their operations implemented in parallel. diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala index 6a000abd54..f4397f2167 100644 --- a/src/library/scala/collection/IterableLike.scala +++ b/src/library/scala/collection/IterableLike.scala @@ -12,7 +12,6 @@ package scala.collection import generic._ import immutable.{ List, Stream } import annotation.unchecked.uncheckedVariance -import annotation.bridge /** A template trait for iterable collections of type `Iterable[A]`. * $iterableInfo diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index 5e37566008..a9535adc23 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -12,7 +12,6 @@ import mutable.{ ListBuffer, ArraySeq } import immutable.{ List, Range } import generic._ import parallel.ParSeq -import annotation.bridge import scala.math.Ordering /** A template trait for sequences of type `Seq[A]` diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index 9b697a164c..f64045c9f6 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -11,7 +11,6 @@ package scala.collection import generic._ import Seq.fill import TraversableView.NoBuilder -import annotation.bridge /** A template trait for non-strict views of sequences. * $seqViewInfo diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index e75000297f..cd85ea4d2d 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -13,7 +13,6 @@ package scala.collection import generic._ import mutable.{Builder, Buffer, ArrayBuffer, ListBuffer} import scala.util.control.Breaks -import annotation.bridge /** A trait for traversable collections. * All operations are guaranteed to be performed in a single-threaded manner. diff --git a/src/library/scala/collection/generic/GenSeqFactory.scala b/src/library/scala/collection/generic/GenSeqFactory.scala index 3664fe1b4f..19eeba9b1d 100644 --- a/src/library/scala/collection/generic/GenSeqFactory.scala +++ b/src/library/scala/collection/generic/GenSeqFactory.scala @@ -11,7 +11,6 @@ package scala.collection package generic -import annotation.bridge import language.higherKinds /** A template for companion objects of Seq and subclasses thereof. diff --git a/src/library/scala/collection/generic/GenericSeqCompanion.scala b/src/library/scala/collection/generic/GenericSeqCompanion.scala index 79cc2f13d4..90063c1ca2 100644 --- a/src/library/scala/collection/generic/GenericSeqCompanion.scala +++ b/src/library/scala/collection/generic/GenericSeqCompanion.scala @@ -10,7 +10,6 @@ package scala.collection package generic -import annotation.bridge import language.higherKinds trait GenericSeqCompanion[CC[X] <: Traversable[X]] diff --git a/src/library/scala/collection/generic/MapFactory.scala b/src/library/scala/collection/generic/MapFactory.scala index 5a6d825aa8..ce44ae9bf4 100644 --- a/src/library/scala/collection/generic/MapFactory.scala +++ b/src/library/scala/collection/generic/MapFactory.scala @@ -11,7 +11,6 @@ package generic import mutable.{Builder, MapBuilder} -import annotation.bridge import language.higherKinds /** A template for companion objects of `Map` and subclasses thereof. diff --git a/src/library/scala/collection/generic/SetFactory.scala b/src/library/scala/collection/generic/SetFactory.scala index 7443bfbf6a..646e99dd1e 100644 --- a/src/library/scala/collection/generic/SetFactory.scala +++ b/src/library/scala/collection/generic/SetFactory.scala @@ -12,7 +12,6 @@ package scala.collection package generic import mutable.Builder -import annotation.bridge import language.higherKinds abstract class SetFactory[CC[X] <: Set[X] with SetLike[X, CC[X]]] diff --git a/src/library/scala/collection/generic/Subtractable.scala b/src/library/scala/collection/generic/Subtractable.scala index ef4f466119..cda71c0291 100644 --- a/src/library/scala/collection/generic/Subtractable.scala +++ b/src/library/scala/collection/generic/Subtractable.scala @@ -10,7 +10,6 @@ package scala.collection package generic -import annotation.bridge /** This trait represents collection-like objects that can be reduced * using a '+' operator. It defines variants of `-` and `--` diff --git a/src/library/scala/collection/generic/TraversableFactory.scala b/src/library/scala/collection/generic/TraversableFactory.scala index e99c77c4f1..254a6a224f 100644 --- a/src/library/scala/collection/generic/TraversableFactory.scala +++ b/src/library/scala/collection/generic/TraversableFactory.scala @@ -10,7 +10,6 @@ package scala.collection package generic -import annotation.bridge import language.higherKinds /** A template for companion objects of `Traversable` and subclasses thereof. diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index 090c7f3043..84c87b4eae 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -11,7 +11,6 @@ package immutable import generic._ import parallel.immutable.ParMap -import annotation.bridge /** * A generic template for immutable maps from keys of type `A` diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 07c8df57ba..5698d53b06 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -10,7 +10,6 @@ package scala.collection.immutable import scala.collection.parallel.immutable.ParRange -import annotation.bridge /** The `Range` class represents integer values in range * ''[start;end)'' with non-zero step value `step`. diff --git a/src/library/scala/collection/immutable/SortedMap.scala b/src/library/scala/collection/immutable/SortedMap.scala index 05248e5805..526f7a1ffe 100644 --- a/src/library/scala/collection/immutable/SortedMap.scala +++ b/src/library/scala/collection/immutable/SortedMap.scala @@ -14,7 +14,6 @@ package immutable import generic._ import mutable.Builder import annotation.unchecked.uncheckedVariance -import annotation.bridge /** A map whose keys are sorted. * diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index 5c85621b0f..4c1a5f2e03 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -14,7 +14,6 @@ package immutable import generic._ import immutable.{RedBlackTree => RB} import mutable.Builder -import annotation.bridge /** $factoryInfo * @define Coll immutable.TreeMap diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 324af77dd4..12dee45bae 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -12,7 +12,6 @@ package scala.collection package mutable import generic._ -import annotation.bridge /** This class implements priority queues using a heap. * To prioritize elements of type A there must be an implicit diff --git a/src/library/scala/package.scala b/src/library/scala/package.scala index 064ccd7735..e3890d7a9d 100644 --- a/src/library/scala/package.scala +++ b/src/library/scala/package.scala @@ -6,7 +6,6 @@ ** |/ ** \* */ -import annotation.bridge /** * Core Scala types. They are always available without an explicit import. diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index fcacb9c82a..d03968212f 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -9,7 +9,6 @@ package scala.runtime import scala.collection.immutable.Range -import annotation.bridge // Note that this does not implement IntegralProxy[Int] so that it can return // the Int-specific Range class from until/to. -- cgit v1.2.3 From e6d5d22d280909dacf635a0a2398158a1b1a6ae1 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sat, 28 Apr 2012 22:37:56 -0700 Subject: Eliminate useless type parameter. --- src/compiler/scala/reflect/internal/Symbols.scala | 2 +- src/library/scala/reflect/DummyMirror.scala | 2 +- src/library/scala/reflect/api/Symbols.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 31f068494c..37caa06fe9 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -2053,7 +2053,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this - @inline final def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt + @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt // ------ toString ------------------------------------------------------------------- diff --git a/src/library/scala/reflect/DummyMirror.scala b/src/library/scala/reflect/DummyMirror.scala index f5b757fdba..422598caef 100644 --- a/src/library/scala/reflect/DummyMirror.scala +++ b/src/library/scala/reflect/DummyMirror.scala @@ -443,7 +443,7 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror { def name: Name = notSupported() def fullName: String = notSupported() def id: Int = notSupported() - def orElse[T](alt: => Symbol): Symbol = notSupported() + def orElse(alt: => Symbol): Symbol = notSupported() def filter(cond: Symbol => Boolean): Symbol = notSupported() def suchThat(cond: Symbol => Boolean): Symbol = notSupported() def privateWithin: Symbol = notSupported() diff --git a/src/library/scala/reflect/api/Symbols.scala b/src/library/scala/reflect/api/Symbols.scala index dbd264c0ab..32faee2512 100755 --- a/src/library/scala/reflect/api/Symbols.scala +++ b/src/library/scala/reflect/api/Symbols.scala @@ -146,7 +146,7 @@ trait Symbols { self: Universe => /** ... */ - def orElse[T](alt: => Symbol): Symbol + def orElse(alt: => Symbol): Symbol /** ... */ -- cgit v1.2.3 From 94c63f5da548996535cad43142758c9405118828 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 29 Apr 2012 17:16:48 -0700 Subject: Fighting bitrot with typing. if (false && settings.debug.value) { ... } Date: 7 years ago *** empty log message *** That's way past the sell-by date for 'if (false && condition)'. --- src/compiler/scala/reflect/internal/Symbols.scala | 11 ++- .../reflect/runtime/SynchronizedSymbols.scala | 2 +- .../scala/tools/nsc/typechecker/Contexts.scala | 11 +++ .../scala/tools/nsc/typechecker/Modes.scala | 2 +- .../scala/tools/nsc/typechecker/Namers.scala | 49 +++------- .../tools/nsc/typechecker/NamesDefaults.scala | 11 +-- .../tools/nsc/typechecker/PatMatVirtualiser.scala | 11 ++- .../scala/tools/nsc/typechecker/Typers.scala | 103 ++++++++------------- 8 files changed, 81 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 37caa06fe9..c2ef633d58 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1425,7 +1425,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Reset symbol to initial state */ - def reset(completer: Type) { + def reset(completer: Type): this.type = { resetFlags() infos = null _validTo = NoPeriod @@ -2054,6 +2054,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this @inline final def orElse(alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt + @inline final def andAlso(f: Symbol => Unit): Symbol = if (this eq NoSymbol) NoSymbol else { f(this) ; this } // ------ toString ------------------------------------------------------------------- @@ -2636,10 +2637,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => info.baseTypeIndex(that) >= 0 ) - override def reset(completer: Type) { + override def reset(completer: Type): this.type = { super.reset(completer) tpePeriod = NoPeriod tyconRunId = NoRunId + this } /*** example: @@ -2822,9 +2824,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => else super.sourceFile override def sourceFile_=(f: AbstractFileType) { source = f } - override def reset(completer: Type) { + override def reset(completer: Type): this.type = { super.reset(completer) thissym = this + this } /** the type this.type in this class */ @@ -3022,7 +3025,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def ownerChain: List[Symbol] = List() override def ownersIterator: Iterator[Symbol] = Iterator.empty override def alternatives: List[Symbol] = List() - override def reset(completer: Type) {} + override def reset(completer: Type): this.type = this override def info: Type = NoType override def existentialBound: Type = NoType override def rawInfo: Type = NoType diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala index 4048e94d0f..8378f1a892 100644 --- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala @@ -46,7 +46,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def typeParams: List[Symbol] = synchronized { super.typeParams } - override def reset(completer: Type) = synchronized { super.reset(completer) } + override def reset(completer: Type): this.type = synchronized { super.reset(completer) } override def infosString: String = synchronized { super.infosString } diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index e2d4efab83..4584ba032d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -405,6 +405,17 @@ trait Contexts { self: Analyzer => case _ => outer.isLocal() } + /** Fast path for some slow checks (ambiguous assignment in Refchecks, and + * existence of __match for MatchTranslation in virtpatmat.) This logic probably + * needs improvement. + */ + def isNameInScope(name: Name) = ( + enclosingContextChain exists (ctx => + (ctx.scope.lookupEntry(name) != null) + || (ctx.owner.rawInfo.member(name) != NoSymbol) + ) + ) + // nextOuter determines which context is searched next for implicits // (after `this`, which contributes `newImplicits` below.) In // most cases, it is simply the outer context: if we're owned by diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/compiler/scala/tools/nsc/typechecker/Modes.scala index 48068b58d4..3eff5ef024 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Modes.scala @@ -105,7 +105,7 @@ trait Modes { final def inFunMode(mode: Int) = (mode & FUNmode) != 0 final def inPolyMode(mode: Int) = (mode & POLYmode) != 0 final def inPatternMode(mode: Int) = (mode & PATTERNmode) != 0 - + final def inExprModeOr(mode: Int, others: Int) = (mode & (EXPRmode | others)) != 0 final def inExprModeButNot(mode: Int, prohibited: Int) = (mode & (EXPRmode | prohibited)) == EXPRmode diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index ffd00751e0..45f7d7e618 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -139,16 +139,9 @@ trait Namers extends MethodSynthesis { || vd.symbol.isLazy ) - def setPrivateWithin[Sym <: Symbol](tree: Tree, sym: Sym, mods: Modifiers): Sym = + def setPrivateWithin[T <: Symbol](tree: Tree, sym: T, mods: Modifiers): T = if (sym.isPrivateLocal || !mods.hasAccessBoundary) sym - else sym setPrivateWithin ( - typer.qualifyingClass(tree, mods.privateWithin, true) match { - case None => - NoSymbol - case Some(sym) => - sym - } - ) + else sym setPrivateWithin typer.qualifyingClass(tree, mods.privateWithin, packageOK = true) def setPrivateWithin(tree: MemberDef, sym: Symbol): Symbol = setPrivateWithin(tree, sym, tree.mods) @@ -160,24 +153,14 @@ trait Namers extends MethodSynthesis { def moduleClassFlags(moduleFlags: Long) = (moduleFlags & ModuleToClassFlags) | inConstructorFlag - private def resetKeepingFlags(sym: Symbol, keeping: Long): Symbol = { - val keep = sym.flags & keeping - sym reset NoType - sym setFlag keep - } - def updatePosFlags(sym: Symbol, pos: Position, flags: Long): Symbol = { debuglog("[overwrite] " + sym) - resetKeepingFlags(sym, LOCKED) - sym setFlag flags - sym setPos pos - - if (sym.isModule && sym.moduleClass != NoSymbol) - updatePosFlags(sym.moduleClass, pos, moduleClassFlags(flags)) + val newFlags = (sym.flags & LOCKED) | flags + sym reset NoType setFlag newFlags setPos pos + sym.moduleClass andAlso (updatePosFlags(_, pos, moduleClassFlags(flags))) if (sym.owner.isPackageClass) { - val companion = companionSymbolOf(sym, context) - if (companion != NoSymbol) { + companionSymbolOf(sym, context) andAlso { companion => val assignNoType = companion.rawInfo match { case _: SymLoader => true case tp => tp.isComplete && (runId(sym.validTo) != currentRunId) @@ -400,9 +383,7 @@ trait Namers extends MethodSynthesis { if (m.isModule && !m.isPackage && inCurrentScope(m) && (currentRun.canRedefine(m) || m.isSynthetic)) { updatePosFlags(m, tree.pos, moduleFlags) setPrivateWithin(tree, m) - if (m.moduleClass != NoSymbol) - setPrivateWithin(tree, m.moduleClass) - + m.moduleClass andAlso (setPrivateWithin(tree, _)) context.unit.synthetics -= m tree.symbol = m } @@ -475,8 +456,7 @@ trait Namers extends MethodSynthesis { val defSym = context.prefix.member(to) filter ( sym => sym.exists && context.isAccessible(sym, context.prefix, false)) - if (defSym != NoSymbol) - typer.permanentlyHiddenWarning(pos, to0, defSym) + defSym andAlso (typer.permanentlyHiddenWarning(pos, to0, _)) } } if (!tree.symbol.isSynthetic && expr.symbol != null && !expr.symbol.isInterpreterWrapper) { @@ -669,10 +649,9 @@ trait Namers extends MethodSynthesis { protected def enterExistingSym(sym: Symbol): Context = { if (forInteractive && sym != null && sym.owner.isTerm) { enterIfNotThere(sym) - if (sym.isLazy) { - val acc = sym.lazyAccessor - if (acc != NoSymbol) enterIfNotThere(acc) - } + if (sym.isLazy) + sym.lazyAccessor andAlso enterIfNotThere + defaultParametersOfMethod(sym) foreach { symRef => enterIfNotThere(symRef()) } } this.context @@ -1547,13 +1526,13 @@ trait Namers extends MethodSynthesis { * call this method? */ def companionSymbolOf(original: Symbol, ctx: Context): Symbol = { - try original.companionSymbol match { - case NoSymbol => + try { + original.companionSymbol orElse { ctx.lookup(original.name.companionName, original.owner).suchThat(sym => (original.isTerm || sym.hasModuleFlag) && (sym isCoDefinedWith original) ) - case sym => sym + } } catch { case e: InvalidCompanions => diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 3d9fc67389..898a9fee9f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -444,21 +444,12 @@ trait NamesDefaults { self: Analyzer => } } - /** Fast path for ambiguous assignment check. - */ - private def isNameInScope(context: Context, name: Name) = ( - context.enclosingContextChain exists (ctx => - (ctx.scope.lookupEntry(name) != null) - || (ctx.owner.rawInfo.member(name) != NoSymbol) - ) - ) - /** A full type check is very expensive; let's make sure there's a name * somewhere which could potentially be ambiguous before we go that route. */ private def isAmbiguousAssignment(typer: Typer, param: Symbol, arg: Tree) = { import typer.context - isNameInScope(context, param.name) && { + (context isNameInScope param.name) && { // for named arguments, check whether the assignment expression would // typecheck. if it does, report an ambiguous error. val paramtpe = param.tpe.cloneInfo(param) diff --git a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala index e5dc8e9ca9..e5b5746e8d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatMatVirtualiser.scala @@ -55,10 +55,15 @@ trait PatMatVirtualiser extends ast.TreeDSL { self: Analyzer => def apply(typer: Typer): MatchTranslation with CodegenCore = { import typer._ // typing `_match` to decide which MatchTranslator to create adds 4% to quick.comp.timer - newTyper(context.makeImplicit(reportAmbiguousErrors = false)).silent(_.typed(Ident(vpmName._match), EXPRmode, WildcardType), reportAmbiguousErrors = false) match { - case SilentResultValue(ms) => new PureMatchTranslator(typer, ms) - case _ => new OptimizingMatchTranslator(typer) + val matchStrategy: Tree = ( + if (!context.isNameInScope(vpmName._match)) null // fast path, avoiding the next line if there's no __match to be seen + else newTyper(context.makeImplicit(reportAmbiguousErrors = false)).silent(_.typed(Ident(vpmName._match), EXPRmode, WildcardType), reportAmbiguousErrors = false) match { + case SilentResultValue(ms) => ms + case _ => null } + ) + if (matchStrategy eq null) new OptimizingMatchTranslator(typer) + else new PureMatchTranslator(typer, matchStrategy) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6234c05258..89c30590c9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -458,13 +458,10 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser * of a this or super with prefix qual. * packageOk is equal false when qualifying class symbol */ - def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean = false): Option[Symbol] = + def qualifyingClass(tree: Tree, qual: Name, packageOK: Boolean) = context.enclClass.owner.ownerChain.find(o => qual.isEmpty || o.isClass && o.name == qual) match { - case Some(c) if packageOK || !c.isPackageClass => - Some(c) - case _ => - QualifyingClassError(tree, qual) - None + case Some(c) if packageOK || !c.isPackageClass => c + case _ => QualifyingClassError(tree, qual) ; NoSymbol } /** The typer for an expression, depending on where we are. If we are before a superclass @@ -4133,7 +4130,7 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser } def convertToAssignment(fun: Tree, qual: Tree, name: Name, args: List[Tree]): Tree = { - val prefix = name.subName(0, name.length - nme.EQL.length) + val prefix = name stripSuffix nme.EQL def mkAssign(vble: Tree): Tree = Assign( vble, @@ -4142,21 +4139,18 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser ) setPos tree.pos def mkUpdate(table: Tree, indices: List[Tree]) = { - gen.evalOnceAll(table :: indices, context.owner, context.unit) { ts => - val tab = ts.head - val is = ts.tail - Apply( - Select(tab(), nme.update) setPos table.pos, - ((is map (i => i())) ::: List( - Apply( - Select( - Apply( - Select(tab(), nme.apply) setPos table.pos, - is map (i => i())) setPos qual.pos, - prefix) setPos fun.pos, - args) setPos tree.pos) - ) - ) setPos tree.pos + gen.evalOnceAll(table :: indices, context.owner, context.unit) { + case tab :: is => + def mkCall(name: Name, extraArgs: Tree*) = ( + Apply( + Select(tab(), name) setPos table.pos, + is.map(i => i()) ++ extraArgs + ) setPos tree.pos + ) + mkCall( + nme.update, + Apply(Select(mkCall(nme.apply), prefix) setPos fun.pos, args) setPos tree.pos + ) } } @@ -4223,15 +4217,11 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser treeCopy.Super(tree, qual1, mix) setType SuperType(clazz.thisType, owntype) } - def typedThis(qual: Name) = { - val qualifyingClassSym = if (tree.symbol != NoSymbol) Some(tree.symbol) else qualifyingClass(tree, qual) - qualifyingClassSym match { - case Some(clazz) => - tree setSymbol clazz setType clazz.thisType.underlying - if (isStableContext(tree, mode, pt)) tree setType clazz.thisType - tree - case None => tree - } + def typedThis(qual: Name) = tree.symbol orElse qualifyingClass(tree, qual, packageOK = false) match { + case NoSymbol => tree + case clazz => + tree setSymbol clazz setType clazz.thisType.underlying + if (isStableContext(tree, mode, pt)) tree setType clazz.thisType else tree } /** Attribute a selection where tree is qual.name. @@ -4242,34 +4232,19 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser * @return ... */ def typedSelect(qual: Tree, name: Name): Tree = { - val sym = - if (tree.symbol != NoSymbol) { - if (phase.erasedTypes && qual.isInstanceOf[Super]) - qual.tpe = tree.symbol.owner.tpe - if (false && settings.debug.value) { // todo: replace by settings.check.value? - val alts = qual.tpe.member(tree.symbol.name).alternatives - if (!(alts exists (alt => - alt == tree.symbol || alt.isTerm && (alt.tpe matches tree.symbol.tpe)))) - assert(false, "symbol "+tree.symbol+tree.symbol.locationString+" not in "+alts+" of "+qual.tpe+ - "\n members = "+qual.tpe.members+ - "\n type history = "+qual.tpe.termSymbol.infosString+ - "\n phase = "+phase) - } - tree.symbol - } else { - member(qual, name) + val sym = tree.symbol orElse member(qual, name) orElse { + // symbol not found? --> try to convert implicitly to a type that does have the required + // member. Added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an + // xml member to StringContext, which in turn has an unapply[Seq] method) + if (name != nme.CONSTRUCTOR && inExprModeOr(mode, PATTERNmode)) { + val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, true, true) + if (qual1 ne qual) + return typed(treeCopy.Select(tree, qual1, name), mode, pt) } - - // symbol not found? --> try to convert implicitly to a type that does have the required member - // added `| PATTERNmode` to allow enrichment in patterns (so we can add e.g., an xml member to StringContext, which in turn has an unapply[Seq] method) - if (sym == NoSymbol && name != nme.CONSTRUCTOR && (mode & (EXPRmode | PATTERNmode)) != 0) { - val qual1 = - if (member(qual, name) != NoSymbol) qual - else adaptToMemberWithArgs(tree, qual, name, mode, true, true) - - if (qual1 ne qual) - return typed(treeCopy.Select(tree, qual1, name), mode, pt) + NoSymbol } + if (phase.erasedTypes && qual.isInstanceOf[Super] && tree.symbol != NoSymbol) + qual.tpe = tree.symbol.owner.tpe if (!reallyExists(sym)) { if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { @@ -4284,14 +4259,12 @@ trait Typers extends Modes with Adaptations with Taggings with PatMatVirtualiser case _ => } - if (settings.debug.value) { - log( - "qual = "+qual+":"+qual.tpe+ - "\nSymbol="+qual.tpe.termSymbol+"\nsymbol-info = "+qual.tpe.termSymbol.info+ - "\nscope-id = "+qual.tpe.termSymbol.info.decls.hashCode()+"\nmembers = "+qual.tpe.members+ - "\nname = "+name+"\nfound = "+sym+"\nowner = "+context.enclClass.owner - ) - } + debuglog( + "qual = "+qual+":"+qual.tpe+ + "\nSymbol="+qual.tpe.termSymbol+"\nsymbol-info = "+qual.tpe.termSymbol.info+ + "\nscope-id = "+qual.tpe.termSymbol.info.decls.hashCode()+"\nmembers = "+qual.tpe.members+ + "\nname = "+name+"\nfound = "+sym+"\nowner = "+context.enclClass.owner + ) def makeInteractiveErrorTree = { val tree1 = tree match { -- cgit v1.2.3