diff options
Diffstat (limited to 'src')
102 files changed, 898 insertions, 774 deletions
diff --git a/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala b/src/compiler/scala/reflect/macros/runtime/AbortMacroException.scala index a68910859d..f45dde8a85 100644 --- a/src/compiler/scala/reflect/makro/runtime/AbortMacroException.scala +++ b/src/compiler/scala/reflect/macros/runtime/AbortMacroException.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime import scala.reflect.internal.util.Position diff --git a/src/compiler/scala/reflect/makro/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala index 760f7fc54d..8b742755cd 100644 --- a/src/compiler/scala/reflect/makro/runtime/Aliases.scala +++ b/src/compiler/scala/reflect/macros/runtime/Aliases.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Aliases { diff --git a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala index 021b93ceee..78fb7100b0 100644 --- a/src/compiler/scala/reflect/makro/runtime/CapturedVariables.scala +++ b/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait CapturedVariables { diff --git a/src/compiler/scala/reflect/makro/runtime/Context.scala b/src/compiler/scala/reflect/macros/runtime/Context.scala index 68964b7abb..8bbfef44a3 100644 --- a/src/compiler/scala/reflect/makro/runtime/Context.scala +++ b/src/compiler/scala/reflect/macros/runtime/Context.scala @@ -1,9 +1,9 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime import scala.tools.nsc.Global -abstract class Context extends scala.reflect.makro.Context +abstract class Context extends scala.reflect.macros.Context with Aliases with CapturedVariables with Infrastructure diff --git a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala index 360a4b8e8a..ebde4447d7 100644 --- a/src/compiler/scala/reflect/makro/runtime/Enclosures.scala +++ b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Enclosures { diff --git a/src/compiler/scala/reflect/makro/runtime/Evals.scala b/src/compiler/scala/reflect/macros/runtime/Evals.scala index 0574359a19..348e29cdd7 100644 --- a/src/compiler/scala/reflect/makro/runtime/Evals.scala +++ b/src/compiler/scala/reflect/macros/runtime/Evals.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime import scala.reflect.runtime.{universe => ru} diff --git a/src/compiler/scala/reflect/makro/runtime/ExprUtils.scala b/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala index e301dfc2a4..672699f00e 100644 --- a/src/compiler/scala/reflect/makro/runtime/ExprUtils.scala +++ b/src/compiler/scala/reflect/macros/runtime/ExprUtils.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait ExprUtils { @@ -29,7 +29,7 @@ trait ExprUtils { def literal(x: Double) = Expr[Double](Literal(Constant(x)))(TypeTag.Double) - def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag[String](definitions.StringClass.asTypeConstructor)) + def literal(x: String) = Expr[String](Literal(Constant(x)))(TypeTag[String](definitions.StringClass.toTypeConstructor)) def literal(x: Char) = Expr[Char](Literal(Constant(x)))(TypeTag.Char) } diff --git a/src/compiler/scala/reflect/makro/runtime/Exprs.scala b/src/compiler/scala/reflect/macros/runtime/Exprs.scala index b680b56bab..4217a6a404 100644 --- a/src/compiler/scala/reflect/makro/runtime/Exprs.scala +++ b/src/compiler/scala/reflect/macros/runtime/Exprs.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Exprs { diff --git a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala index 6644c579ac..69fa416f8f 100644 --- a/src/compiler/scala/reflect/makro/runtime/FrontEnds.scala +++ b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait FrontEnds extends scala.tools.reflect.FrontEnds { diff --git a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala index 76c4b21731..19fb03364e 100644 --- a/src/compiler/scala/reflect/makro/runtime/Infrastructure.scala +++ b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime import scala.tools.nsc.util.ScalaClassLoader diff --git a/src/compiler/scala/reflect/makro/runtime/Names.scala b/src/compiler/scala/reflect/macros/runtime/Names.scala index 3f43b15d90..ee9f3a56d3 100644 --- a/src/compiler/scala/reflect/makro/runtime/Names.scala +++ b/src/compiler/scala/reflect/macros/runtime/Names.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Names { diff --git a/src/compiler/scala/reflect/makro/runtime/Parsers.scala b/src/compiler/scala/reflect/macros/runtime/Parsers.scala index ac8d09f592..6d89b71f39 100644 --- a/src/compiler/scala/reflect/makro/runtime/Parsers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Parsers.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime import language.existentials diff --git a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala index 10b5ae5f42..056549578a 100644 --- a/src/compiler/scala/reflect/makro/runtime/Reifiers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala @@ -3,7 +3,7 @@ * @author Gilles Dubochet */ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Reifiers { diff --git a/src/compiler/scala/reflect/makro/runtime/Settings.scala b/src/compiler/scala/reflect/macros/runtime/Settings.scala index 8288180b8d..b7dba665fa 100644 --- a/src/compiler/scala/reflect/makro/runtime/Settings.scala +++ b/src/compiler/scala/reflect/macros/runtime/Settings.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Settings { diff --git a/src/compiler/scala/reflect/makro/runtime/Traces.scala b/src/compiler/scala/reflect/macros/runtime/Traces.scala index 225ee1f62b..0238e9f84e 100644 --- a/src/compiler/scala/reflect/makro/runtime/Traces.scala +++ b/src/compiler/scala/reflect/macros/runtime/Traces.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Traces extends util.Traces { diff --git a/src/compiler/scala/reflect/makro/runtime/TypeTags.scala b/src/compiler/scala/reflect/macros/runtime/TypeTags.scala index 4f9b287674..2bc2fe6384 100644 --- a/src/compiler/scala/reflect/makro/runtime/TypeTags.scala +++ b/src/compiler/scala/reflect/macros/runtime/TypeTags.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait TypeTags { diff --git a/src/compiler/scala/reflect/makro/runtime/Typers.scala b/src/compiler/scala/reflect/macros/runtime/Typers.scala index 18c1714d15..9fa8567ada 100644 --- a/src/compiler/scala/reflect/makro/runtime/Typers.scala +++ b/src/compiler/scala/reflect/macros/runtime/Typers.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package runtime trait Typers { @@ -10,8 +10,9 @@ trait Typers { def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { 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] _) + val context = callsiteTyper.context + val wrapper1 = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _) + val wrapper2 = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _) def wrapper (tree: => Tree) = wrapper1(wrapper2(tree)) // if you get a "silent mode is not available past typer" here // don't rush to change the typecheck not to use the silent method when the silent parameter is false @@ -31,29 +32,21 @@ trait Typers { def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { macroLogVerbose("inferring implicit value of type %s, macros = %s".format(pt, !withMacrosDisabled)) - import universe.analyzer.SearchResult - val context = callsiteTyper.context - val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) - def wrapper (inference: => SearchResult) = wrapper1(inference) - wrapper(universe.analyzer.inferImplicit(universe.EmptyTree, pt, true, false, context, !silent, pos)) match { - case failure if failure.tree.isEmpty => - macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits") - if (context.hasErrors) throw new universe.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) - universe.EmptyTree - case success => - success.tree - } + inferImplicit(universe.EmptyTree, pt, isView = false, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) + } + + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree = { + macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s".format(from, to, tree, !withMacrosDisabled)) + val viewTpe = universe.appliedType(universe.definitions.FunctionClass(1).toTypeConstructor, List(from, to)) + inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) } - def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree = { - macroLogVerbose("inferring implicit view from %s to %s for %s, macros = %s, reportAmbiguous = %s".format(from, to, tree, !withMacrosDisabled, reportAmbiguous)) + private def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree = { import universe.analyzer.SearchResult val context = callsiteTyper.context val wrapper1 = if (!withMacrosDisabled) (context.withMacrosEnabled[SearchResult] _) else (context.withMacrosDisabled[SearchResult] _) def wrapper (inference: => SearchResult) = wrapper1(inference) - val fun1 = universe.definitions.FunctionClass(1) - val viewTpe = universe.TypeRef(fun1.typeConstructor.prefix, fun1, List(from, to)) - wrapper(universe.analyzer.inferImplicit(tree, viewTpe, reportAmbiguous, true, context, !silent, pos)) match { + wrapper(universe.analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos)) match { case failure if failure.tree.isEmpty => macroLogVerbose("implicit search has failed. to find out the reason, turn on -Xlog-implicits") if (context.hasErrors) throw new universe.TypeError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg) diff --git a/src/compiler/scala/reflect/makro/util/Traces.scala b/src/compiler/scala/reflect/macros/util/Traces.scala index 2363cc4bac..6c2f115994 100644 --- a/src/compiler/scala/reflect/makro/util/Traces.scala +++ b/src/compiler/scala/reflect/macros/util/Traces.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package util trait Traces { diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 1b72b3075b..5e15c5ad3a 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -1,7 +1,7 @@ package scala.reflect.reify -import scala.reflect.makro.ReificationError -import scala.reflect.makro.UnexpectedReificationError +import scala.reflect.macros.ReificationError +import scala.reflect.macros.UnexpectedReificationError trait Errors { self: Reifier => diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index 8fba7274be..53e01309cb 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -1,8 +1,8 @@ package scala.reflect.reify import scala.tools.nsc.Global -import scala.reflect.makro.ReificationError -import scala.reflect.makro.UnexpectedReificationError +import scala.reflect.macros.ReificationError +import scala.reflect.macros.UnexpectedReificationError import scala.reflect.reify.utils.Utils /** Given a tree or a type, generate a tree that when executed at runtime produces the original tree or type. @@ -115,7 +115,7 @@ abstract class Reifier extends States // todo. maybe try `resetLocalAttrs` once the dust settles var importantSymbols = Set[Symbol]( NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass, - BaseUniverseClass, ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror) + BaseUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror) importantSymbols ++= importantSymbols map (_.companionSymbol) importantSymbols ++= importantSymbols map (_.moduleClass) importantSymbols ++= importantSymbols map (_.linkedClassOfClass) diff --git a/src/compiler/scala/reflect/reify/Taggers.scala b/src/compiler/scala/reflect/reify/Taggers.scala index 4e30d0acf8..a8523fe686 100644 --- a/src/compiler/scala/reflect/reify/Taggers.scala +++ b/src/compiler/scala/reflect/reify/Taggers.scala @@ -1,7 +1,7 @@ package scala.reflect.reify -import scala.reflect.makro.{ReificationError, UnexpectedReificationError} -import scala.reflect.makro.runtime.Context +import scala.reflect.macros.{ReificationError, UnexpectedReificationError} +import scala.reflect.macros.runtime.Context abstract class Taggers { val c: Context diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala index 38c8fedac5..59651bcdf9 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala @@ -36,7 +36,7 @@ trait GenSymbols { else if (sym.isEmptyPackageClass) mirrorMirrorSelect(nme.EmptyPackageClass) else if (sym.isModuleClass) - Select(Select(reify(sym.sourceModule), nme.asModuleSymbol), nme.moduleClass) + Select(Select(reify(sym.sourceModule), nme.asModule), nme.moduleClass) else if (sym.isPackage) mirrorMirrorCall(nme.staticPackage, reify(sym.fullName)) else if (sym.isLocatable) { diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index c49e5b3342..c762a28f99 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -30,7 +30,7 @@ trait GenTypes { val tsym = tpe.typeSymbolDirect if (tsym.isClass && tpe == tsym.typeConstructor && tsym.isStatic) - Select(Select(reify(tsym), nme.asTypeSymbol), nme.asTypeConstructor) + Select(Select(reify(tsym), nme.asType), nme.toTypeConstructor) else tpe match { case tpe @ NoType => reifyMirrorObject(tpe) @@ -42,7 +42,7 @@ trait GenTypes { mirrorBuildCall(nme.thisPrefix, mirrorMirrorSelect(nme.EmptyPackageClass)) case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => val module = reify(clazz.sourceModule) - val moduleClass = Select(Select(module, nme.asModuleSymbol), nme.moduleClass) + val moduleClass = Select(Select(module, nme.asModule), nme.moduleClass) mirrorFactoryCall(nme.ThisType, moduleClass) case tpe @ ThisType(_) => reifyProduct(tpe) @@ -94,7 +94,7 @@ trait GenTypes { } case success => if (reifyDebug) println("implicit search has produced a result: " + success) - state.reificationIsConcrete &= concrete || success.tpe <:< TypeTagClass.asTypeConstructor + state.reificationIsConcrete &= concrete || success.tpe <:< TypeTagClass.toTypeConstructor Select(Apply(Select(success, nme.in), List(Ident(nme.MIRROR_SHORT))), nme.tpe) } if (result != EmptyTree) return result @@ -109,7 +109,7 @@ trait GenTypes { def searchForManifest(typer: analyzer.Typer): Tree = analyzer.inferImplicit( EmptyTree, - appliedType(FullManifestClass.asTypeConstructor, List(tpe)), + appliedType(FullManifestClass.toTypeConstructor, List(tpe)), reportAmbiguous = false, isView = false, context = typer.context, diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 80011368a8..a253effc1c 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -1,9 +1,8 @@ package scala.reflect import language.implicitConversions -import language.experimental.macros import scala.reflect.base.{Universe => BaseUniverse} -import scala.reflect.makro.{Context, ReificationError, UnexpectedReificationError} +import scala.reflect.macros.{Context, ReificationError, UnexpectedReificationError} import scala.tools.nsc.Global package object reify { @@ -29,7 +28,7 @@ package object reify { import definitions._ val enclosingErasure = reifyEnclosingRuntimeClass(global)(typer0) // JavaUniverse is defined in scala-reflect.jar, so we must be very careful in case someone reifies stuff having only scala-library.jar on the classpath - val isJavaUniverse = JavaUniverseClass != NoSymbol && universe.tpe <:< JavaUniverseClass.asTypeConstructor + val isJavaUniverse = JavaUniverseClass != NoSymbol && universe.tpe <:< JavaUniverseClass.toTypeConstructor if (isJavaUniverse && !enclosingErasure.isEmpty) Apply(Select(universe, nme.runtimeMirror), List(Select(enclosingErasure, sn.GetClassLoader))) else Select(universe, nme.rootMirror) } @@ -69,7 +68,7 @@ package object reify { if (isThisInScope) { val enclosingClasses = typer0.context.enclosingContextChain map (_.tree) collect { case classDef: ClassDef => classDef } val classInScope = enclosingClasses.headOption getOrElse EmptyTree - if (!classInScope.isEmpty) reifyRuntimeClass(global)(typer0, classInScope.symbol.asTypeConstructor, concrete = true) + if (!classInScope.isEmpty) reifyRuntimeClass(global)(typer0, classInScope.symbol.toTypeConstructor, concrete = true) else Select(This(tpnme.EMPTY), sn.GetClass) } else EmptyTree } diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala index 86265ec77a..ebe3957e69 100644 --- a/src/compiler/scala/reflect/reify/utils/Extractors.scala +++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala @@ -20,11 +20,6 @@ trait Extractors { // () // }; // def apply[U >: Nothing <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = { - // val $u: scala.reflect.api.Universe = $m$untyped.universe.asInstanceOf[scala.reflect.api.Universe]; - // val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror]; - // applyImpl($m).asInstanceOf[U#Tree]; - // } - // def applyImpl[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = { // val $u: U = $m$untyped.universe; // val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror]; // $u.Apply($u.Select($u.Select($u.build.This($m.staticPackage("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2)))) @@ -40,7 +35,7 @@ trait Extractors { // def apply[U >: Nothing <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Type = { // val $u: U = $m$untyped.universe; // val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror]; - // $u.TypeRef($u.ThisType($m.staticPackage("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").asTypeConstructor)) + // $u.TypeRef($u.ThisType($m.staticPackage("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").toTypeConstructor)) // } // }; // new $typecreator1() @@ -51,23 +46,7 @@ trait Extractors { val tparamu = newTypeName("U") val (reifierBase, reifierName, reifierTpt, reifierUniverse) = flavor match { case tpnme.REIFY_TYPECREATOR_PREFIX => (TypeCreatorClass, nme.apply, SelectFromTypeTree(Ident(tparamu), tpnme.Type), BaseUniverseClass) - case tpnme.REIFY_TREECREATOR_PREFIX => (TreeCreatorClass, nme.applyImpl, SelectFromTypeTree(Ident(BaseUniverseClass), tpnme.Tree), ApiUniverseClass) - case _ => throw new Error(s"unexpected flavor $flavor") - } - val reifierPreamble = flavor match { - case tpnme.REIFY_TYPECREATOR_PREFIX => Nil - case tpnme.REIFY_TREECREATOR_PREFIX => List[Tree]( - DefDef(NoMods, - nme.apply, - List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(BaseUniverseClass), Ident(SingletonClass)), emptyValDef, List()))))), - List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorOfClass), List(Ident(tparamu))), EmptyTree))), - SelectFromTypeTree(Ident(tparamu), tpnme.Tree), - Block( - ValDef(NoMods, nme.UNIVERSE_SHORT, Ident(ApiUniverseClass), TypeApply(Select(Select(Ident(nme.MIRROR_UNTYPED), nme.universe), nme.asInstanceOf_), List(Ident(ApiUniverseClass)))), - ValDef(NoMods, nme.MIRROR_SHORT, Select(Ident(nme.UNIVERSE_SHORT), tpnme.Mirror), TypeApply(Select(Ident(nme.MIRROR_UNTYPED), nme.asInstanceOf_), List(Select(Ident(nme.UNIVERSE_SHORT), tpnme.Mirror)))), - TypeApply(Select(Apply(TypeApply(Ident(reifierName), List(SingletonTypeTree(Ident(nme.UNIVERSE_SHORT)))), List(Ident(nme.MIRROR_SHORT))), nme.asInstanceOf_), List(SelectFromTypeTree(Ident(tparamu), tpnme.Tree))) - )) - ) + case tpnme.REIFY_TREECREATOR_PREFIX => (TreeCreatorClass, nme.apply, SelectFromTypeTree(Ident(tparamu), tpnme.Tree), BaseUniverseClass) case _ => throw new Error(s"unexpected flavor $flavor") } val reifierBody = { @@ -98,8 +77,7 @@ trait Extractors { Template(List(Ident(reifierBase)), emptyValDef, List( - DefDef(NoMods, nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))) - ) ++ reifierPreamble ++ List( + DefDef(NoMods, nme.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))), DefDef(NoMods, reifierName, List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), emptyValDef, List()))))), @@ -128,7 +106,7 @@ trait Extractors { case Block( List(udef @ ValDef(_, _, _, universe), mdef @ ValDef(_, _, _, mirror)), Apply( - Apply(TypeApply(_, List(ttpe @ TypeTree())), List(_, Block(List(ClassDef(_, _, _, Template(_, _, List(_, _, DefDef(_, _, _, _, _, Block(_ :: _ :: symbolTable1, rtree)))))), _))), + Apply(TypeApply(_, List(ttpe @ TypeTree())), List(_, Block(List(ClassDef(_, _, _, Template(_, _, List(_, DefDef(_, _, _, _, _, Block(_ :: _ :: symbolTable1, rtree)))))), _))), // todo. doesn't take into account optimizations such as $u.TypeTag.Int or the upcoming closure optimization List(Apply(TypeApply(tagFactory @ Select(_, _), _), List(_, Block(List(ClassDef(_, _, _, Template(_, _, List(_, DefDef(_, _, _, _, _, Block(_ :: _ :: symbolTable2, rtpe)))))), _)))))) if udef.name == nme.UNIVERSE_SHORT && mdef.name == nme.MIRROR_SHORT => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index e590a0b691..f681de93b6 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -993,8 +993,13 @@ abstract class GenASM extends SubComponent with BytecodeWriters { case sb@ScalaSigBytes(bytes) => // see http://www.scala-lang.org/sid/10 (Storage of pickled Scala signatures in class files) // also JVMS Sec. 4.7.16.1 The element_value structure and JVMS Sec. 4.4.7 The CONSTANT_Utf8_info Structure. - val assocValue = (if(sb.fitsInOneString) strEncode(sb) else arrEncode(sb)) - av.visit(name, assocValue) + if (sb.fitsInOneString) + av.visit(name, strEncode(sb)) + else { + val arrAnnotV: asm.AnnotationVisitor = av.visitArray(name) + for(arg <- arrEncode(sb)) { arrAnnotV.visit(name, arg) } + arrAnnotV.visitEnd() + } // for the lazy val in ScalaSigBytes to be GC'ed, the invoker of emitAnnotations() should hold the ScalaSigBytes in a method-local var that doesn't escape. case ArrayAnnotArg(args) => diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 00e6f3769e..8805f68634 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -380,7 +380,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { if (settings.docImplicits.value) makeImplicitConversions(sym, this) else Nil // members as given by the compiler - lazy val memberSyms = sym.info.members.filter(s => membersShouldDocument(s, this)) + lazy val memberSyms = sym.info.members.filter(s => membersShouldDocument(s, this)).toList // the inherited templates (classes, traits or objects) var memberSymsLazy = memberSyms.filter(t => templateShouldDocument(t, this) && !inOriginalOwner(t, this)) @@ -712,7 +712,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { override def inheritedFrom = Nil override def isRootPackage = true override lazy val memberSyms = - (bSym.info.members ++ EmptyPackage.info.members) filter { s => + (bSym.info.members ++ EmptyPackage.info.members).toList filter { s => s != EmptyPackage && s != RootPackage } }) diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index a12b67c9ed..5a0cc602e5 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -386,7 +386,7 @@ trait ModelFactoryImplicitSupport { lazy val memberImpls: List[MemberImpl] = { // Obtain the members inherited by the implicit conversion - val memberSyms = toType.members.filter(implicitShouldDocument(_)) + val memberSyms = toType.members.filter(implicitShouldDocument(_)).toList val existingSyms = sym.info.members // Debugging part :) diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 27b6cae2a6..77bc77e966 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -749,12 +749,20 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") val originalTypeParams = sym.owner.typeParams parseAndEnter(unit) val pre = adaptToNewRunMap(ThisType(sym.owner)) - val newsym = pre.typeSymbol.info.decl(sym.name) filter { alt => + val rawsym = pre.typeSymbol.info.decl(sym.name) + val newsym = rawsym filter { alt => sym.isType || { try { val tp1 = pre.memberType(alt) onTypeError NoType val tp2 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, sym.owner.typeParams) - matchesType(tp1, tp2, false) + matchesType(tp1, tp2, false) || { + debugLog(s"getLinkPos matchesType($tp1, $tp2) failed") + val tp3 = adaptToNewRunMap(sym.tpe) substSym (originalTypeParams, alt.owner.typeParams) + matchesType(tp1, tp3, false) || { + debugLog(s"getLinkPos fallback matchesType($tp1, $tp3) failed") + false + } + } } catch { case ex: ControlThrowable => throw ex @@ -766,8 +774,11 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") } } if (newsym == NoSymbol) { - debugLog("link not found " + sym + " " + source + " " + pre) - NoPosition + if (rawsym.exists && !rawsym.isOverloaded) rawsym.pos + else { + debugLog("link not found " + sym + " " + source + " " + pre) + NoPosition + } } else if (newsym.isOverloaded) { settings.uniqid.value = true debugLog("link ambiguous " + sym + " " + source + " " + pre + " " + newsym.alternatives) diff --git a/src/compiler/scala/tools/nsc/interpreter/Imports.scala b/src/compiler/scala/tools/nsc/interpreter/Imports.scala index d579e0369e..5e72d2b661 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Imports.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Imports.scala @@ -191,5 +191,5 @@ trait Imports { prevRequestList flatMap (req => req.handlers map (req -> _)) private def membersAtPickler(sym: Symbol): List[Symbol] = - beforePickler(sym.info.nonPrivateMembers) + beforePickler(sym.info.nonPrivateMembers.toList) }
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala index c429e3b196..b9849e40d1 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala @@ -52,10 +52,10 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput // XXX we'd like to say "filterNot (_.isDeprecated)" but this causes the // compiler to crash for reasons not yet known. - def members = afterTyper((effectiveTp.nonPrivateMembers ++ anyMembers) filter (_.isPublic)) - def methods = members filter (_.isMethod) - def packages = members filter (_.isPackage) - def aliases = members filter (_.isAliasType) + def members = afterTyper((effectiveTp.nonPrivateMembers.toList ++ anyMembers) filter (_.isPublic)) + def methods = members.toList filter (_.isMethod) + def packages = members.toList filter (_.isPackage) + def aliases = members.toList filter (_.isAliasType) def memberNames = members map tos def methodNames = methods map tos diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 236f3f23c5..5cea86d57d 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -9,6 +9,7 @@ package interpreter import scala.collection.{ mutable, immutable } import scala.PartialFunction.cond import scala.reflect.internal.Chars +import scala.reflect.internal.Flags._ import language.implicitConversions trait MemberHandlers { @@ -126,7 +127,7 @@ trait MemberHandlers { class DefHandler(member: DefDef) extends MemberDefHandler(member) { private def vparamss = member.vparamss - private def isMacro = member.mods.hasFlag(scala.reflect.internal.Flags.MACRO) + private def isMacro = member.symbol hasFlag MACRO // true if not a macro and 0-arity override def definesValue = !isMacro && flattensToEmpty(vparamss) override def resultExtractionCode(req: Request) = @@ -211,7 +212,7 @@ trait MemberHandlers { beforePickler(individualNames map (targetType nonPrivateMember _)) lazy val wildcardSymbols: List[Symbol] = - if (importsWildcard) beforePickler(targetType.nonPrivateMembers) + if (importsWildcard) beforePickler(targetType.nonPrivateMembers.toList) else Nil /** Complete list of names imported by a wildcard */ diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 57d7cef726..ebc02d98ed 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -62,7 +62,7 @@ class Power[ReplValsImpl <: ReplVals : ru.TypeTag: ClassTag](val intp: IMain, re def discarded = seen.size - keep.size def members(x: Symbol): List[Symbol] = - if (x.rawInfo.isComplete) x.info.members + if (x.rawInfo.isComplete) x.info.members.toList else Nil var lastCount = -1 @@ -216,7 +216,7 @@ class Power[ReplValsImpl <: ReplVals : ru.TypeTag: ClassTag](val intp: IMain, re def declsOriginal = membersDeclared filterNot (_.isOverride) def members = membersUnabridged filterNot excludeMember - def membersUnabridged = tpe.members + def membersUnabridged = tpe.members.toList def membersDeclared = members filterNot excludeMember def membersInherited = members filterNot (membersDeclared contains _) def memberTypes = members filter (_.name.isTypeName) diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index 56b9c7011c..202d5d3f82 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -212,8 +212,7 @@ trait TypeStrings { } private def tparamString[T: ru.TypeTag] : String = { - // [Eugene++ to Paul] needs review!! - def typeArguments: List[ru.Type] = ru.typeOf[T].typeArguments + def typeArguments: List[ru.Type] = ru.typeOf[T] match { case ru.TypeRef(_, _, args) => args; case _ => Nil } // [Eugene++] todo. need to use not the `rootMirror`, but a mirror with the REPL's classloader // how do I get to it? acquiring context classloader seems unreliable because of multithreading def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => ru.rootMirror.runtimeClass(targ)) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index aa30a7a45b..3906d7761f 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -205,8 +205,6 @@ trait ScalaSettings extends AbsScalaSettings // Feature extensions val XmacroSettings = MultiStringSetting("-Xmacro-settings", "option", "Custom settings for macros.") - val XmacroPrimaryClasspath = PathSetting("-Xmacro-primary-classpath", "Classpath to load macros implementations from, defaults to compilation classpath (aka \"library classpath\".", "") - val XmacroFallbackClasspath = PathSetting("-Xmacro-fallback-classpath", "Classpath to load macros implementations from if they cannot be loaded from library classpath.", "") /** * IDE-specific settings diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 0fc298e886..c7dab69f62 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -360,7 +360,7 @@ trait Contexts { self: Analyzer => private def unitError(pos: Position, msg: String) = unit.error(pos, if (checking) "\n**** ERROR DURING INTERNAL CHECKING ****\n" + msg else msg) - + @inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) { debugwarn("issue error: " + err.errMsg) if (settings.Yissuedebug.value) (new Exception).printStackTrace() @@ -611,8 +611,8 @@ trait Contexts { self: Analyzer => (e ne null) && (e.owner == scope) }) - private def collectImplicits(syms: List[Symbol], pre: Type, imported: Boolean = false): List[ImplicitInfo] = - for (sym <- syms if isQualifyingImplicit(sym.name, sym, pre, imported)) yield + private def collectImplicits(syms: Scope, pre: Type, imported: Boolean = false): List[ImplicitInfo] = + for (sym <- syms.toList if isQualifyingImplicit(sym.name, sym, pre, imported)) yield new ImplicitInfo(sym.name, pre, sym) private def collectImplicitImports(imp: ImportInfo): List[ImplicitInfo] = { @@ -657,7 +657,7 @@ trait Contexts { self: Analyzer => } } else if (scope != nextOuter.scope && !owner.isPackageClass) { debuglog("collect local implicits " + scope.toList)//DEBUG - collectImplicits(scope.toList, NoPrefix) + collectImplicits(scope, NoPrefix) } else if (imports != nextOuter.imports) { assert(imports.tail == nextOuter.imports, (imports, nextOuter.imports)) collectImplicitImports(imports.head) @@ -725,7 +725,7 @@ trait Contexts { self: Analyzer => result } - def allImportedSymbols: List[Symbol] = + def allImportedSymbols: Iterable[Symbol] = qual.tpe.members flatMap (transformImport(tree.selectors, _)) private def transformImport(selectors: List[ImportSelector], sym: Symbol): List[Symbol] = selectors match { diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index da045e1a48..b442d16b1c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -957,7 +957,7 @@ trait Implicits { companion.moduleClass match { case mc: ModuleClassSymbol => val infos = - for (im <- mc.implicitMembers) yield new ImplicitInfo(im.name, singleType(pre, companion), im) + for (im <- mc.implicitMembers.toList) yield new ImplicitInfo(im.name, singleType(pre, companion), im) if (infos.nonEmpty) infoMap += (sym -> infos) case _ => @@ -1196,7 +1196,7 @@ trait Implicits { gen.mkAttributedThis(thisSym) case _ => // if ``pre'' is not a PDT, e.g. if someone wrote - // implicitly[scala.reflect.makro.Context#TypeTag[Int]] + // implicitly[scala.reflect.macros.Context#TypeTag[Int]] // then we need to fail, because we don't know the prefix to use during type reification // upd. we also need to fail silently, because this is a very common situation // e.g. quite often we're searching for BaseUniverse#TypeTag, e.g. for a type tag in any universe diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index d33857371d..1381450970 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -8,7 +8,7 @@ import scala.reflect.runtime.ReflectionUtils import scala.collection.mutable.ListBuffer import scala.compat.Platform.EOL import reflect.internal.util.Statistics -import scala.reflect.makro.util._ +import scala.reflect.macros.util._ import java.lang.{Class => jClass} import java.lang.reflect.{Array => jArray, Method => jMethod} @@ -24,7 +24,7 @@ import java.lang.reflect.{Array => jArray, Method => jMethod} * Then fooBar needs to point to a static method of the following form: * * def fooBar[T: c.TypeTag] - * (c: scala.reflect.makro.Context) + * (c: scala.reflect.macros.Context) * (xs: c.Expr[List[T]]) * : c.Expr[T] = { * ... @@ -51,7 +51,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { /** A list of compatible macro implementation signatures. * * In the example above: - * (c: scala.reflect.makro.Context)(xs: c.Expr[List[T]]): c.Expr[T] + * (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]]): c.Expr[T] * * @param macroDef The macro definition symbol * @param tparams The type parameters of the macro definition @@ -591,53 +591,34 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { runtimeType } - /** Primary classloader that is used to resolve and run macro implementations. - * Loads classes from -Xmacro-primary-classpath, or from -cp if the option is not specified. + /** Macro classloader that is used to resolve and run macro implementations. + * Loads classes from from -cp (aka the library classpath). * Is also capable of detecting REPL and reusing its classloader. */ - private lazy val primaryClassloader: ClassLoader = { + private lazy val macroClassloader: ClassLoader = { if (global.forMSIL) throw new UnsupportedOperationException("Scala reflection not available on this platform") - if (settings.XmacroPrimaryClasspath.value != "") { - macroLogVerbose("primary macro classloader: initializing from -Xmacro-primary-classpath: %s".format(settings.XmacroPrimaryClasspath.value)) - val classpath = toURLs(settings.XmacroPrimaryClasspath.value) - ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - } else { - macroLogVerbose("primary macro classloader: initializing from -cp: %s".format(global.classPath.asURLs)) - val classpath = global.classPath.asURLs - var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - - // [Eugene] a heuristic to detect the REPL - if (global.settings.exposeEmptyPackage.value) { - macroLogVerbose("primary macro classloader: initializing from a REPL classloader".format(global.classPath.asURLs)) - import scala.tools.nsc.interpreter._ - val virtualDirectory = global.settings.outputDirs.getSingleOutput.get - loader = new AbstractFileClassLoader(virtualDirectory, loader) {} - } + val classpath = global.classPath.asURLs + macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath)) + val loader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) + // [Eugene] a heuristic to detect the REPL + if (global.settings.exposeEmptyPackage.value) { + macroLogVerbose("macro classloader: initializing from a REPL classloader".format(global.classPath.asURLs)) + import scala.tools.nsc.interpreter._ + val virtualDirectory = global.settings.outputDirs.getSingleOutput.get + new AbstractFileClassLoader(virtualDirectory, loader) {} + } else { loader } } - /** Fallback classloader that is used to resolve and run macro implementations when `primaryClassloader` fails. - * Loads classes from -Xmacro-fallback-classpath. - */ - private lazy val fallbackClassloader: ClassLoader = { - if (global.forMSIL) - throw new UnsupportedOperationException("Scala reflection not available on this platform") - - macroLogVerbose("fallback macro classloader: initializing from -Xmacro-fallback-classpath: %s".format(settings.XmacroFallbackClasspath.value)) - val classpath = toURLs(settings.XmacroFallbackClasspath.value) - ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader) - } - /** Produces a function that can be used to invoke macro implementation for a given macro definition: * 1) Looks up macro implementation symbol in this universe. - * 2) Loads its enclosing class from the primary classloader. - * 3) Loads the companion of that enclosing class from the primary classloader. + * 2) Loads its enclosing class from the macro classloader. + * 3) Loads the companion of that enclosing class from the macro classloader. * 4) Resolves macro implementation within the loaded companion. - * 5) If 2-4 fails, repeats them for the fallback classloader. * * @return Some(runtime) if macro implementation can be loaded successfully from either of the mirrors, * None otherwise. @@ -742,25 +723,10 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } } - val primary = loadMacroImpl(primaryClassloader) - primary match { - case Some((implObj, implMeth)) => + loadMacroImpl(macroClassloader) map { + case (implObj, implMeth) => def runtime(args: List[Any]) = implMeth.invoke(implObj, (args map (_.asInstanceOf[AnyRef])): _*).asInstanceOf[Any] - Some(runtime _) - case None => - if (settings.XmacroFallbackClasspath.value != "") { - macroLogVerbose("trying to load macro implementation from the fallback mirror: %s".format(settings.XmacroFallbackClasspath.value)) - val fallback = loadMacroImpl(fallbackClassloader) - fallback match { - case Some((implObj, implMeth)) => - def runtime(args: List[Any]) = implMeth.invoke(implObj, (args map (_.asInstanceOf[AnyRef])): _*).asInstanceOf[Any] - Some(runtime _) - case None => - None - } - } else { - None - } + runtime _ } } @@ -913,7 +879,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { } /** Keeps track of macros in-flight. - * See more informations in comments to ``openMacros'' in ``scala.reflect.makro.Context''. + * See more informations in comments to ``openMacros'' in ``scala.reflect.macros.Context''. */ var openMacros = List[MacroContext]() def enclosingMacroPosition = openMacros map (_.macroApplication.pos) find (_ ne NoPosition) getOrElse NoPosition @@ -1147,9 +1113,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { val macroDef = expandee.symbol def notFound() = { typer.context.error(expandee.pos, "macro implementation not found: " + macroDef.name + " " + - "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)\n" + - "if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath " + - "in the second phase pointing to the output of the first phase") + "(the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)") None } def fallBackToOverridden(tree: Tree): Option[Tree] = { @@ -1191,7 +1155,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces { // [Eugene] any ideas about how to improve this one? val realex = ReflectionUtils.unwrapThrowable(ex) realex match { - case realex: reflect.makro.runtime.AbortMacroException => + case realex: reflect.macros.runtime.AbortMacroException => macroLogVerbose("macro expansion has failed: %s".format(realex.msg)) fail(typer, expandee) // error has been reported by abort case err: TypeError => diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 7bd5f4caeb..bd2808d049 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -70,11 +70,8 @@ trait MethodSynthesis { // [Eugene++->Martin] now this compiles, will soon check it out def newMethodType[F](owner: Symbol)(implicit t: TT[F]): Type = { val fnSymbol = compilerSymbolFromTag(t) - assert(fnSymbol isSubClass FunctionClass(t.tpe.typeArguments.size - 1), (owner, t)) - // [Eugene++ to Paul] needs review!! - // val symbols = m.typeArguments map (m => manifestToSymbol(m)) - // val formals = symbols.init map (_.typeConstructor) val formals = compilerTypeFromTag(t).typeArguments + assert(fnSymbol isSubClass FunctionClass(formals.size - 1), (owner, t)) val params = owner newSyntheticValueParams formals MethodType(params, formals.last) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index dc9f07cad9..44712ba286 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -983,15 +983,10 @@ trait Namers extends MethodSynthesis { } addDefaultGetters(meth, vparamss, tparams, overriddenSymbol) - // macro defs need to be typechecked in advance - // because @macroImpl annotation only gets assigned during typechecking - // otherwise we might find ourselves in the situation when we specified -Xmacro-fallback-classpath - // but macros still don't expand - // that might happen because macro def doesn't have its link a macro impl yet - if (ddef.symbol.isTermMacro) { - val pt = resultPt.substSym(tparamSyms, tparams map (_.symbol)) - typer.computeMacroDefType(ddef, pt) - } + // fast track macros, i.e. macros defined inside the compiler, are hardcoded + // hence we make use of that and let them have whatever right-hand side they need + // (either "macro ???" as they used to or just "???" to maximally simplify their compilation) + if (fastTrack contains ddef.symbol) ddef.symbol setFlag MACRO thisMethodType({ val rt = ( diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 3518316fbb..9501998152 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -122,7 +122,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R val defaultGetters = clazz.info.findMembers(0L, DEFAULTPARAM) val defaultMethodNames = defaultGetters map (sym => nme.defaultGetterToMethod(sym.name)) - defaultMethodNames.distinct foreach { name => + defaultMethodNames.toList.distinct foreach { name => val methods = clazz.info.findMember(name, 0L, METHOD, false).alternatives val haveDefaults = methods filter (sym => sym.hasParamWhich(_.hasDefault) && !nme.isProtectedAccessorName(sym.name)) @@ -628,7 +628,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R matchingArity match { // So far so good: only one candidate method - case concrete :: Nil => + case Scope(concrete) => val mismatches = abstractParams zip concrete.tpe.paramTypes filterNot { case (x, y) => x =:= y } mismatches match { // Only one mismatched parameter: say something useful. diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala index 190b18711c..64c5b41638 100644 --- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala +++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala @@ -4,7 +4,7 @@ package typechecker trait StdAttachments { self: Analyzer => - type UnaffiliatedMacroContext = scala.reflect.makro.runtime.Context + type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type } case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext]) }
\ No newline at end of file diff --git a/src/compiler/scala/tools/nsc/typechecker/Tags.scala b/src/compiler/scala/tools/nsc/typechecker/Tags.scala index 052484e8e1..f82e009be8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Tags.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Tags.scala @@ -61,7 +61,7 @@ trait Tags { */ def resolveTypeTag(pos: Position, pre: Type, tp: Type, concrete: Boolean, allowMaterialization: Boolean = true): Tree = { val tagSym = if (concrete) TypeTagClass else AbsTypeTagClass - val tagTp = if (pre == NoType) TypeRef(BaseUniverseClass.asTypeConstructor, tagSym, List(tp)) else singleType(pre, pre member tagSym.name) + val tagTp = if (pre == NoType) TypeRef(BaseUniverseClass.toTypeConstructor, tagSym, List(tp)) else singleType(pre, pre member tagSym.name) val taggedTp = appliedType(tagTp, List(tp)) resolveTag(pos, taggedTp, allowMaterialization) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e57cae00e0..b06ea639b0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5089,7 +5089,7 @@ trait Typers extends Modes with Adaptations with Tags { // convert new Array^N[T](len) for N > 1 to evidence[ClassTag[Array[...Array[T]...]]].newArray(len), where Array HK gets applied (N-1) times // [Eugene] no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions) val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe) - val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.asType, List(tpe))).last + val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.toTypeConstructor, List(tpe))).last val newArrayApp = atPos(tree.pos) { val tag = resolveClassTag(tree.pos, tagType) if (tag.isEmpty) MissingClassTagError(tree, tagType) diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index 237ef813c7..e093c64c72 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -38,7 +38,7 @@ trait FastTrack { MacroInternal_materializeClassTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeClassTag(u, tt.tpe) } MacroInternal_materializeAbsTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, EmptyTree, tt.tpe, concrete = false) } MacroInternal_materializeTypeTag bindTo { case (c, Apply(TypeApply(_, List(tt)), List(u))) => c.materializeTypeTag(u, EmptyTree, tt.tpe, concrete = true) } - ApiUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) } + BaseUniverseReify bindTo { case (c, Apply(TypeApply(_, List(tt)), List(expr))) => c.materializeExpr(c.prefix.tree, EmptyTree, expr) } ReflectRuntimeCurrentMirror bindTo { case (c, _) => scala.reflect.runtime.Macros.currentMirror(c).tree } StringContext_f bindTo { case (c, app@Apply(Select(Apply(_, parts), _), args)) => c.macro_StringInterpolation_f(parts, args, app.pos) } registry diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala index e1b959cefa..40ceefcc70 100644 --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala @@ -1,7 +1,7 @@ package scala.tools.reflect -import scala.reflect.makro.{ReificationError, UnexpectedReificationError} -import scala.reflect.makro.runtime.Context +import scala.reflect.macros.{ReificationError, UnexpectedReificationError} +import scala.reflect.macros.runtime.Context import scala.collection.mutable.ListBuffer import scala.collection.mutable.Stack @@ -25,9 +25,9 @@ abstract class MacroImplementations { c.abort(args(parts.length-1).pos, "too many arguments for interpolated string") } - val stringParts = parts map { + val stringParts = parts map { case Literal(Constant(s: String)) => s; - case _ => throw new IllegalArgumentException("argument parts must be a list of string literals") + case _ => throw new IllegalArgumentException("argument parts must be a list of string literals") } val pi = stringParts.iterator diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala index 25a42a82cd..0704189ddc 100644 --- a/src/compiler/scala/tools/reflect/StdTags.scala +++ b/src/compiler/scala/tools/reflect/StdTags.scala @@ -20,7 +20,7 @@ trait StdTags { def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = { val u = m.universe val pre = u.ThisType(m.staticPackage("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol]) - u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.asTypeConstructor)) + u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.toTypeConstructor)) } }) @@ -29,7 +29,7 @@ trait StdTags { m, new TypeCreator { def apply[U <: BaseUniverse with Singleton](m: MirrorOf[U]): U # Type = - m.staticClass(classTag[T].runtimeClass.getName).asTypeConstructor.asInstanceOf[U # Type] + m.staticClass(classTag[T].runtimeClass.getName).toTypeConstructor.asInstanceOf[U # Type] }) lazy val tagOfInt = u.TypeTag.Int lazy val tagOfString = tagOfStaticClass[String] @@ -52,7 +52,7 @@ object StdRuntimeTags extends StdTags { } abstract class StdContextTags extends StdTags { - val tc: scala.reflect.makro.Context + val tc: scala.reflect.macros.Context val u: tc.universe.type = tc.universe val m = tc.mirror } diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala index edd22c60f4..2505c1afb7 100644 --- a/src/compiler/scala/tools/reflect/ToolBox.scala +++ b/src/compiler/scala/tools/reflect/ToolBox.scala @@ -24,40 +24,46 @@ trait ToolBox[U <: Universe] { /** Typechecks a tree using this ToolBox. * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. * - * If the tree has unresolved type variables (represented as instances of ``FreeTypeSymbol'' symbols), - * then they might, might be partially or might not be specified in the ``freeTypes'' parameter. + * If the tree has unresolved type variables (represented as instances of `FreeTypeSymbol` symbols), + * then they all have to be resolved first using `Tree.substituteTypes`, or an error occurs. * - * 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. + * 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 -Ydebug. * * Typechecking can be steered with the following optional parameters: - * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false - * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + * `withImplicitViewsDisabled` recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * `withMacrosDisabled` recursively prohibits macro expansions and macro-based implicits, default value is false */ - def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, freeTypes: Map[u.FreeTypeSymbol, u.Type] = Map[u.FreeTypeSymbol, u.Type](), silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree + def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree - - /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. + /** Infers an implicit value of the expected type `pt` in top-level context. + * Optional `pos` parameter provides a position that will be associated with the implicit search. + * + * As mentioned in https://groups.google.com/forum/#!topic/scala-internals/ta-vbUT6JE8 + * this API won't take into account the lexical context of the callsite, because + * currently it's impossible to reify it. * - * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * If `silent` is false, `TypeError` will be thrown in case of an inference 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 -Xlog-implicits. - * Unlike in ``typeCheck'', ``silent'' is true by default. + * Unlike in `typeCheck`, `silent` is true by default. */ - def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false): u.Tree + def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree - /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + /** Infers an implicit view from the provided tree `tree` from the type `from` to the type `to` in the toplevel context. + * Optional `pos` parameter provides a position that will be associated with the implicit search. * - * Otional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. - * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. + * As mentioned in https://groups.google.com/forum/#!topic/scala-internals/ta-vbUT6JE8 + * this API won't take into account the lexical context of the callsite, because + * currently it's impossible to reify it. * - * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * If `silent` is false, `TypeError` will be thrown in case of an inference 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 -Xlog-implicits. - * Unlike in ``typeCheck'', ``silent'' is true by default. + * Unlike in `typeCheck`, `silent` is true by default. */ - def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true): u.Tree + def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree /** Recursively resets symbols and types in a given tree. * @@ -78,14 +84,14 @@ trait ToolBox[U <: Universe] { /** Compiles and runs a tree using this ToolBox. * - * If the tree has unresolved type variables (represented as instances of ``FreeTypeSymbol'' symbols), - * then they all have to be specified in the ``freeTypes'' parameter or an error occurs. + * If the tree has unresolved type variables (represented as instances of `FreeTypeSymbol` symbols), + * then they all have to be resolved first using `Tree.substituteTypes`, or an error occurs. * * This spawns the compiler at the Namer phase, and pipelines the tree through that compiler. - * Currently ``runExpr'' does not accept trees that already typechecked, because typechecking isn't idempotent. + * Currently `runExpr` does not accept trees that already typechecked, because typechecking isn't idempotent. * For more info, take a look at https://issues.scala-lang.org/browse/SI-5464. */ - def runExpr(tree: u.Tree, freeTypes: Map[u.FreeTypeSymbol, u.Type] = Map[u.FreeTypeSymbol, u.Type]()): Any + def runExpr(tree: u.Tree): Any } /** Represents an error during toolboxing diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 589c5c7eb0..9987931cf3 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -85,7 +85,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => if (tree.hasSymbol && tree.symbol.isFreeTerm) { tree match { case Ident(_) => - val freeTermRef = Ident(freeTermNames(tree.symbol.asFreeTermSymbol)) + val freeTermRef = Ident(freeTermNames(tree.symbol.asFreeTerm)) if (wrapFreeTermRefs) Apply(freeTermRef, List()) else freeTermRef case _ => throw new Error("internal error: %s (%s, %s) is not supported".format(tree, tree.productPrefix, tree.getClass)) @@ -97,7 +97,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => (expr, freeTermNames) } - def typeCheckExpr(expr0: Tree, pt: Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree = { + def transformDuringTyper(expr0: Tree, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean)(transform: (analyzer.Typer, Tree) => Tree): Tree = { verifyExpr(expr0) // need to wrap the expr, because otherwise you won't be able to typecheck macros against something that contains free vars @@ -121,34 +121,56 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => currentTyper.context.setReportErrors() // need to manually set context mode, otherwise typer.silent will throw exceptions reporter.reset() - trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) - wrapper(currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { - case analyzer.SilentResultValue(result) => - trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) - var (dummies, unwrapped) = result match { - case Block(dummies, unwrapped) => (dummies, unwrapped) - case unwrapped => (Nil, unwrapped) + val expr1 = wrapper(transform(currentTyper, expr)) + var (dummies1, unwrapped) = expr1 match { + case Block(dummies, unwrapped) => (dummies, unwrapped) + case unwrapped => (Nil, unwrapped) + } + var invertedIndex = freeTerms map (_.swap) + // todo. also fixup singleton types + unwrapped = new Transformer { + override def transform(tree: Tree): Tree = + tree match { + case Ident(name) if invertedIndex contains name => + Ident(invertedIndex(name)) setType tree.tpe + case _ => + super.transform(tree) } - var invertedIndex = freeTerms map (_.swap) - // todo. also fixup singleton types - unwrapped = new Transformer { - override def transform(tree: Tree): Tree = - tree match { - case Ident(name) if invertedIndex contains name => - Ident(invertedIndex(name)) setType tree.tpe - case _ => - super.transform(tree) - } - }.transform(unwrapped) - new TreeTypeSubstituter(dummies map (_.symbol), dummies map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name)))).traverse(unwrapped) - unwrapped - case error @ analyzer.SilentTypeError(_) => - trace("failed: ")(error.err.errMsg) - if (!silent) throw ToolBoxError("reflective typecheck has failed: %s".format(error.err.errMsg)) - EmptyTree - }) + }.transform(unwrapped) + new TreeTypeSubstituter(dummies1 map (_.symbol), dummies1 map (dummy => SingleType(NoPrefix, invertedIndex(dummy.symbol.name)))).traverse(unwrapped) + unwrapped } + def typeCheckExpr(expr: Tree, pt: Type, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree = + transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( + (currentTyper, expr) => { + trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymkinds.value)) + currentTyper.silent(_.typed(expr, analyzer.EXPRmode, pt)) match { + case analyzer.SilentResultValue(result) => + trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) + result + case error @ analyzer.SilentTypeError(_) => + trace("failed: ")(error.err.errMsg) + if (!silent) throw ToolBoxError("reflective typecheck has failed: %s".format(error.err.errMsg)) + EmptyTree + } + }) + + def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree = + transformDuringTyper(tree, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)( + (currentTyper, tree) => { + trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymkinds.value)) + val context = currentTyper.context + analyzer.inferImplicit(tree, pt, reportAmbiguous = true, isView = isView, context = context, saveAmbiguousDivergent = !silent, pos = pos) match { + case failure if failure.tree.isEmpty => + trace("implicit search has failed. to find out the reason, turn on -Xlog-implicits: ")(failure.tree) + if (context.hasErrors) throw ToolBoxError("reflective implicit search has failed: %s".format(context.errBuffer.head.errMsg)) + EmptyTree + case success => + success.tree + } + }) + def compileExpr(expr: Tree): (Object, java.lang.reflect.Method) = { verifyExpr(expr) @@ -254,7 +276,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => } } - def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = { + def showAttributed(artifact: Any, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = { val saved1 = settings.printtypes.value val saved2 = settings.uniqid.value val saved3 = settings.Yshowsymkinds.value @@ -262,7 +284,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => settings.printtypes.value = printTypes settings.uniqid.value = printIds settings.Yshowsymkinds.value = printKinds - tree.toString + artifact.toString } finally { settings.printtypes.value = saved1 settings.uniqid.value = saved2 @@ -312,29 +334,37 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => lazy val exporter = importer.reverse lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, mirror.classLoader) - def typeCheck(tree: u.Tree, expectedType: u.Type, freeTypes: Map[u.FreeTypeSymbol, u.Type], silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): u.Tree = { - if (compiler.settings.verbose.value) println("typing "+tree+", expectedType = "+expectedType+", freeTypes = "+freeTypes) + def typeCheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = { + if (compiler.settings.verbose.value) println("importing "+tree+", expectedType = "+expectedType) var ctree: compiler.Tree = importer.importTree(tree) var cexpectedType: compiler.Type = importer.importType(expectedType) - if (compiler.settings.verbose.value) println("substituting "+ctree+", expectedType = "+expectedType) - val cfreeTypes: Map[compiler.FreeTypeSymbol, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeTypeSymbol], importer.importType(v)) } - ctree = ctree.substituteTypes(cfreeTypes.keys.toList, cfreeTypes.values.toList) - cexpectedType = cexpectedType.substituteTypes(cfreeTypes.keys.toList, cfreeTypes.values.toList) - if (compiler.settings.verbose.value) println("typing "+ctree+", expectedType = "+expectedType) val ttree: compiler.Tree = compiler.typeCheckExpr(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) val uttree = exporter.importTree(ttree) uttree } - def inferImplicitValue(pt: u.Type, silent: Boolean, withMacrosDisabled: Boolean): u.Tree = - // todo. implement this - ??? + def inferImplicitValue(pt: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree = { + inferImplicit(u.EmptyTree, pt, isView = false, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) + } + + def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: u.Position = u.NoPosition): u.Tree = { + val viewTpe = u.appliedType(u.definitions.FunctionClass(1).toTypeConstructor, List(from, to)) + inferImplicit(tree, viewTpe, isView = true, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = pos) + } - def inferImplicitView(tree: u.Tree, from: u.Type, to: u.Type, silent: Boolean, withMacrosDisabled: Boolean, reportAmbiguous: Boolean): u.Tree = - // todo. implement this - ??? + private def inferImplicit(tree: u.Tree, pt: u.Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: u.Position): u.Tree = { + if (compiler.settings.verbose.value) println("importing "+pt, ", tree = "+tree+", pos = "+pos) + var ctree: compiler.Tree = importer.importTree(tree) + var cpt: compiler.Type = importer.importType(pt) + var cpos: compiler.Position = importer.importPosition(pos) + + if (compiler.settings.verbose.value) println("inferring implicit %s of type %s, macros = %s".format(if (isView) "view" else "value", pt, !withMacrosDisabled)) + val itree: compiler.Tree = compiler.inferImplicit(ctree, cpt, isView = isView, silent = silent, withMacrosDisabled = withMacrosDisabled, pos = cpos) + val uitree = exporter.importTree(itree) + uitree + } def resetAllAttrs(tree: u.Tree): u.Tree = { val ctree: compiler.Tree = importer.importTree(tree) @@ -360,14 +390,10 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => utree } - def runExpr(tree: u.Tree, freeTypes: Map[u.FreeTypeSymbol, u.Type]): Any = { - if (compiler.settings.verbose.value) println("running "+tree+", freeTypes = "+freeTypes) + def runExpr(tree: u.Tree): Any = { + if (compiler.settings.verbose.value) println("importing "+tree) var ctree: compiler.Tree = importer.importTree(tree) - if (compiler.settings.verbose.value) println("substituting "+ctree) - val cfreeTypes: Map[compiler.FreeTypeSymbol, compiler.Type] = freeTypes map { case (k, v) => (importer.importSymbol(k).asInstanceOf[compiler.FreeTypeSymbol], importer.importType(v)) } - ctree = ctree.substituteTypes(cfreeTypes.keys.toList, cfreeTypes.values.toList) - if (compiler.settings.verbose.value) println("running "+ctree) compiler.runExpr(ctree) } diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala index 5f4e6d58c3..d89ebcb2a3 100644 --- a/src/compiler/scala/tools/util/PathResolver.scala +++ b/src/compiler/scala/tools/util/PathResolver.scala @@ -194,7 +194,7 @@ class PathResolver(settings: Settings, context: JavaContext) { def scalaBootClassPath = cmdLineOrElse("bootclasspath", Defaults.scalaBootClassPath) def scalaExtDirs = cmdLineOrElse("extdirs", Defaults.scalaExtDirs) /** Scaladoc doesn't need any bootstrapping, otherwise will create errors such as: - * [scaladoc] ../scala-trunk/src/reflect/scala/reflect/makro/Reifiers.scala:89: error: object api is not a member of package reflect + * [scaladoc] ../scala-trunk/src/reflect/scala/reflect/macros/Reifiers.scala:89: error: object api is not a member of package reflect * [scaladoc] case class ReificationError(val pos: reflect.api.PositionApi, val msg: String) extends Throwable(msg) * [scaladoc] ^ * because the bootstrapping will look at the sourcepath and create package "reflect" in "<root>" diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala index 7d37fa4aa1..723d95a499 100644 --- a/src/library/scala/StringContext.scala +++ b/src/library/scala/StringContext.scala @@ -8,8 +8,6 @@ package scala -import language.experimental.macros - /** A class to support string interpolation. * This class supports string interpolation as outlined in Scala SIP-11. * It needs to be fully documented once the SIP is accepted. @@ -99,7 +97,7 @@ case class StringContext(parts: String*) { * format specifier `%%`. */ // The implementation is magically hardwired into `scala.tools.reflect.MacroImplementations.macro_StringInterpolation_f` - def f(args: Any*): String = macro ??? + def f(args: Any*): String = ??? // macro } object StringContext { diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala index 53854f160d..714fd365ef 100644 --- a/src/library/scala/reflect/base/Base.scala +++ b/src/library/scala/reflect/base/Base.scala @@ -1,7 +1,6 @@ package scala.reflect package base -import language.experimental.macros import java.io.PrintWriter import scala.annotation.switch import scala.ref.WeakReference @@ -62,7 +61,9 @@ class Base extends Universe { self => class TypeSymbol(val owner: Symbol, override val name: TypeName, flags: FlagSet) extends Symbol(name, flags) with TypeSymbolBase { - override val asTypeConstructor = TypeRef(ThisType(owner), this, Nil) + override def toTypeConstructor = TypeRef(ThisType(owner), this, Nil) + override def toType = TypeRef(ThisType(owner), this, Nil) + override def toTypeIn(site: Type) = TypeRef(ThisType(owner), this, Nil) } implicit val TypeSymbolTag = ClassTag[TypeSymbol](classOf[TypeSymbol]) @@ -170,12 +171,17 @@ class Base extends Universe { self => object BoundedWildcardType extends BoundedWildcardTypeExtractor implicit val BoundedWildcardTypeTag = ClassTag[BoundedWildcardType](classOf[BoundedWildcardType]) - type Scope = Iterable[Symbol] + class Scope(elems: Iterable[Symbol]) extends ScopeBase with MemberScopeBase { + def iterator = elems.iterator + def sorted = elems.toList + } + type MemberScope = Scope implicit val ScopeTag = ClassTag[Scope](classOf[Scope]) + implicit val MemberScopeTag = ClassTag[MemberScope](classOf[MemberScope]) - def newScope = newScopeWith() - def newNestedScope(outer: Iterable[Symbol]) = newScope - def newScopeWith(elems: Symbol*): Scope = elems + def newScope: Scope = newScopeWith() + def newNestedScope(outer: Scope): Scope = newScope + def newScopeWith(elems: Symbol*): Scope = new Scope(elems) abstract class Name(str: String) extends NameBase { override def toString = str @@ -229,7 +235,6 @@ class Base extends Universe { self => override val privateWithin: Name, override val annotations: List[Tree]) extends ModifiersBase { def hasFlag(flags: FlagSet) = (this.flags & flags) != 0 - def hasAllFlags(flags: FlagSet) = (flags & ~this.flags) == 0 } implicit val ModifiersTag = ClassTag[Modifiers](classOf[Modifiers]) @@ -291,16 +296,16 @@ class Base extends Universe { self => object build extends BuildBase { def selectType(owner: Symbol, name: String): TypeSymbol = { val clazz = new ClassSymbol(owner, newTypeName(name), NoFlags) - cached(clazz.fullName)(clazz).asTypeSymbol + cached(clazz.fullName)(clazz).asType } def selectTerm(owner: Symbol, name: String): TermSymbol = { val valu = new MethodSymbol(owner, newTermName(name), NoFlags) - cached(valu.fullName)(valu).asTermSymbol + cached(valu.fullName)(valu).asTerm } def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = - selectTerm(owner, name).asMethodSymbol + selectTerm(owner, name).asMethod def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = if (name.isTypeName) @@ -380,7 +385,7 @@ class Base extends Universe { self => object definitions extends DefinitionsBase { lazy val ScalaPackage = staticModule("scala") - lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClassSymbol + lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClass lazy val AnyClass = staticClass("scala.Any") lazy val AnyValClass = staticClass("scala.Any") @@ -461,6 +466,8 @@ class Base extends Universe { self => def treeToString(tree: Tree) = s"<tree ${tree.getClass}>" + def treeType(tree: Tree) = NoType + trait TermTree extends Tree trait TypTree extends Tree diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala index 8b2a3b4ea8..8e429afb21 100644 --- a/src/reflect/scala/reflect/api/Exprs.scala +++ b/src/library/scala/reflect/base/Exprs.scala @@ -4,9 +4,7 @@ */ package scala.reflect -package api - -import scala.reflect.base.TreeCreator +package base trait Exprs { self: Universe => @@ -46,7 +44,7 @@ trait Exprs { self: Universe => // !!! remove when we have improved type inference for singletons // search for .type] to find other instances lazy val staticTpe: Type = implicitly[AbsTypeTag[T]].tpe - def actualTpe: Type = tree.tpe + def actualTpe: Type = treeType(tree) def splice: T = throw new UnsupportedOperationException(""" |the function you're calling has not been spliced by the compiler. @@ -58,5 +56,24 @@ trait Exprs { self: Universe => |if you want to splice the underlying expression, use `<your expr>.splice`. |if you want to get a value of the underlying expression, add scala-compiler.jar to the classpath, |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin) + + private def writeReplace(): AnyRef = new SerializedExpr(treec, implicitly[AbsTypeTag[T]].in(scala.reflect.basis.rootMirror)) + } +} + +private[scala] class SerializedExpr(var treec: TreeCreator, var tag: scala.reflect.basis.AbsTypeTag[_]) extends Serializable { + private def writeObject(out: java.io.ObjectOutputStream): Unit = { + out.writeObject(treec) + out.writeObject(tag) + } + + private def readObject(in: java.io.ObjectInputStream): Unit = { + treec = in.readObject().asInstanceOf[TreeCreator] + tag = in.readObject().asInstanceOf[scala.reflect.basis.AbsTypeTag[_]] + } + + private def readResolve(): AnyRef = { + import scala.reflect.basis._ + Expr(rootMirror, treec)(tag) } }
\ No newline at end of file diff --git a/src/library/scala/reflect/base/FlagSets.scala b/src/library/scala/reflect/base/FlagSets.scala index 57946d0f27..43de9970c0 100644 --- a/src/library/scala/reflect/base/FlagSets.scala +++ b/src/library/scala/reflect/base/FlagSets.scala @@ -13,5 +13,11 @@ trait FlagSets { self: Universe => /** The empty set of flags */ val NoFlags: FlagSet + + /** The base API all flag bearers support */ + trait HasFlagsBase { + def flags: FlagSet + def hasFlag(flags: FlagSet): Boolean + } } diff --git a/src/library/scala/reflect/base/Scopes.scala b/src/library/scala/reflect/base/Scopes.scala index a5db01c0ce..a388fdc392 100644 --- a/src/library/scala/reflect/base/Scopes.scala +++ b/src/library/scala/reflect/base/Scopes.scala @@ -3,13 +3,33 @@ package base trait Scopes { self: Universe => - type Scope >: Null <: Iterable[Symbol] + type Scope >: Null <: ScopeBase + + /** The base API that all scopes support */ + trait ScopeBase extends Iterable[Symbol] /** A tag that preserves the identity of the `Scope` abstract type from erasure. * Can be used for pattern matching, instance tests, serialization and likes. */ implicit val ScopeTag: ClassTag[Scope] + type MemberScope >: Null <: Scope with MemberScopeBase + + /** The base API that all member scopes support */ + trait MemberScopeBase extends ScopeBase { + /** Sorts the symbols included in this scope so that: + * 1) Symbols appear the linearization order of their owners. + * 2) Symbols with the same owner appear in reverse order of their declarations. + * 3) Synthetic members (e.g. getters/setters for vals/vars) might appear in arbitrary order. + */ + def sorted: List[Symbol] + } + + /** A tag that preserves the identity of the `MemberScope` abstract type from erasure. + * Can be used for pattern matching, instance tests, serialization and likes. + */ + implicit val MemberScopeTag: ClassTag[MemberScope] + /** Create a new scope */ def newScope: Scope diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala index ced1f33395..45f7c0c1bd 100644 --- a/src/library/scala/reflect/base/Symbols.scala +++ b/src/library/scala/reflect/base/Symbols.scala @@ -80,10 +80,6 @@ trait Symbols { self: Universe => /** The base API that all symbols support */ trait SymbolBase { this: Symbol => - /** An id number which is unique for all symbols in this universe */ - // [Eugene++ to Martin] do we leave this here? - def id: Int - /** The owner of this symbol. This is the symbol * that directly contains the current symbol's definition. * The `NoSymbol` symbol does not have an owner, and calling this method @@ -112,18 +108,6 @@ trait Symbols { self: Universe => */ def fullName: String - /** If this symbol is a class, this symbol; otherwise the next enclosing - * class, or `NoSymbol` if none exists. - */ - def enclosingClass: Symbol = - if (isClass || this == NoSymbol) this else owner.enclosingClass - - /** If this symbol is a method, this symbol; otherwise the next enclosing - * method, or `NoSymbol` if none exists. - */ - def enclosingMethod: Symbol = - if (isMethod || this == NoSymbol) this else owner.enclosingMethod - /** Does this symbol represent the definition of a type? * Note that every symbol is either a term or a type. * So for every symbol `sym`, either `sym.isTerm` is true @@ -134,7 +118,7 @@ trait Symbols { self: Universe => /** This symbol cast to a TypeSymbol. * Returns ClassCastException if `isType` is false. */ - def asTypeSymbol: TypeSymbol = throw new ClassCastException(toString) + def asType: TypeSymbol = throw new ClassCastException(toString) /** Does this symbol represent the definition of a term? * Note that every symbol is either a term or a term. @@ -146,7 +130,7 @@ trait Symbols { self: Universe => /** This symbol cast to a TermSymbol. * Returns ClassCastException if `isTerm` is false. */ - def asTermSymbol: TermSymbol = throw new ClassCastException(toString) + def asTerm: TermSymbol = throw new ClassCastException(toString) /** Does this symbol represent the definition of a method? * If yes, `isTerm` is also guaranteed to be true. @@ -156,7 +140,7 @@ trait Symbols { self: Universe => /** This symbol cast to a MethodSymbol. * Returns ClassCastException if `isMethod` is false. */ - def asMethodSymbol: MethodSymbol = throw new ClassCastException(toString) + def asMethod: MethodSymbol = throw new ClassCastException(toString) /** Does this symbol represent the definition of a module (i.e. it * results from an object definition?). @@ -167,7 +151,7 @@ trait Symbols { self: Universe => /** This symbol cast to a ModuleSymbol defined by an object definition. * Returns ClassCastException if `isModule` is false. */ - def asModuleSymbol: ModuleSymbol = throw new ClassCastException(toString) + def asModule: ModuleSymbol = throw new ClassCastException(toString) /** Does this symbol represent the definition of a class or trait? * If yes, `isType` is also guaranteed to be true. @@ -183,7 +167,7 @@ trait Symbols { self: Universe => /** This symbol cast to a ClassSymbol representing a class or trait. * Returns ClassCastException if `isClass` is false. */ - def asClassSymbol: ClassSymbol = throw new ClassCastException(toString) + def asClass: ClassSymbol = throw new ClassCastException(toString) /** Does this symbol represent a free term captured by reification? * If yes, `isTerm` is also guaranteed to be true. @@ -193,7 +177,7 @@ trait Symbols { self: Universe => /** This symbol cast to a free term symbol. * Returns ClassCastException if `isFreeTerm` is false. */ - def asFreeTermSymbol: FreeTermSymbol = throw new ClassCastException(toString) + def asFreeTerm: FreeTermSymbol = throw new ClassCastException(toString) /** Does this symbol represent a free type captured by reification? * If yes, `isType` is also guaranteed to be true. @@ -203,7 +187,7 @@ trait Symbols { self: Universe => /** This symbol cast to a free type symbol. * Returns ClassCastException if `isFreeType` is false. */ - def asFreeTypeSymbol: FreeTypeSymbol = throw new ClassCastException(toString) + def asFreeType: FreeTypeSymbol = throw new ClassCastException(toString) def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) @@ -219,16 +203,34 @@ trait Symbols { self: Universe => final type NameType = TypeName /** The type constructor corresponding to this type symbol. - * This is different from `asType` in that type parameters - * are part of results of `asType`, but not of `asTypeConstructor`. + * This is different from `toType` in that type parameters + * are part of results of `toType`, but not of `toTypeConstructor`. * * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol - * `C`. Then `C.asType` is the type `C[T]`, but `C.asTypeConstructor` is `C`. + * `C`. Then `C.toType` is the type `C[T]`, but `C.toTypeConstructor` is `C`. + */ + def toTypeConstructor: Type + + /** A type reference that refers to this type symbol seen + * as a member of given type `site`. */ - def asTypeConstructor: Type + def toTypeIn(site: Type): Type + + /** A type reference that refers to this type symbol + * Note if symbol is a member of a class, one almost always is interested + * in `asTypeIn` with a site type instead. + * + * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol + * `C`. Then `C.toType` is the type `C[T]`. + * + * By contrast, `C.typeSignature` would be a type signature of form + * `PolyType(ClassInfoType(...))` that describes type parameters, value + * parameters, parent types, and members of `C`. + */ + def toType: Type override def isType = true - override def asTypeSymbol = this + override def asType = this } /** The base API that all term symbols support */ @@ -238,13 +240,13 @@ trait Symbols { self: Universe => final type NameType = TermName final override def isTerm = true - final override def asTermSymbol = this + final override def asTerm = this } /** The base API that all method symbols support */ trait MethodSymbolBase extends TermSymbolBase { this: MethodSymbol => final override def isMethod = true - final override def asMethodSymbol = this + final override def asMethod = this } /** The base API that all module symbols support */ @@ -257,24 +259,24 @@ trait Symbols { self: Universe => // [Eugene++] when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life final override def isModule = true - final override def asModuleSymbol = this + final override def asModule = this } /** The base API that all class symbols support */ trait ClassSymbolBase extends TypeSymbolBase { this: ClassSymbol => final override def isClass = true - final override def asClassSymbol = this + final override def asClass = this } /** The base API that all free type symbols support */ trait FreeTypeSymbolBase extends TypeSymbolBase { this: FreeTypeSymbol => final override def isFreeType = true - final override def asFreeTypeSymbol = this + final override def asFreeType = this } /** The base API that all free term symbols support */ trait FreeTermSymbolBase extends TermSymbolBase { this: FreeTermSymbol => final override def isFreeTerm = true - final override def asFreeTermSymbol = this + final override def asFreeTerm = this } } diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala index 2814450ae3..4e8a520625 100644 --- a/src/library/scala/reflect/base/Trees.scala +++ b/src/library/scala/reflect/base/Trees.scala @@ -34,6 +34,9 @@ trait Trees { self: Universe => /** Obtains string representation of a tree */ protected def treeToString(tree: Tree): String + /** Obtains the type of the tree (we intentionally don't expose `tree.tpe` in base) */ + protected def treeType(tree: Tree): Type + /** Tree is the basis for scala's abstract syntax. The nodes are * implemented as case classes, and the parameters which initialize * a given tree are immutable: however Trees have several mutable @@ -1356,10 +1359,7 @@ trait Trees { self: Universe => implicit val ModifiersTag: ClassTag[Modifiers] /** ... */ - abstract class ModifiersBase { - def flags: FlagSet - def hasFlag(flags: FlagSet): Boolean - def hasAllFlags(flags: FlagSet): Boolean + abstract class ModifiersBase extends HasFlagsBase { def privateWithin: Name // default: EmptyTypeName def annotations: List[Tree] // default: List() def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = diff --git a/src/library/scala/reflect/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala index 05b1a079d7..3f7024366e 100644 --- a/src/library/scala/reflect/base/TypeTags.scala +++ b/src/library/scala/reflect/base/TypeTags.scala @@ -169,6 +169,7 @@ trait TypeTags { self: Universe => val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]] otherMirror.universe.AbsTypeTag[T](otherMirror1, tpec) } + private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = false) } /** @@ -233,13 +234,18 @@ trait TypeTags { self: Universe => val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]] otherMirror.universe.TypeTag[T](otherMirror1, tpec) } + private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true) } - private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends TypeTagImpl[T](rootMirror, null) { + private class PredefTypeCreator[T](copyIn: Universe => Universe # TypeTag[T]) extends TypeCreator { + def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type = { + copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe + } + } + + private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends TypeTagImpl[T](rootMirror, new PredefTypeCreator(copyIn)) { override lazy val tpe: Type = _tpe - override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = - copyIn(otherMirror.universe).asInstanceOf[U # TypeTag[T]] - private def readResolve() = copyIn(self) + private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true) } // incantations @@ -248,3 +254,21 @@ trait TypeTags { self: Universe => // big thanks to Viktor Klang for this brilliant idea! def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe } + +private[scala] class SerializedTypeTag(var tpec: TypeCreator, var concrete: Boolean) extends Serializable { + private def writeObject(out: java.io.ObjectOutputStream): Unit = { + out.writeObject(tpec) + out.writeBoolean(concrete) + } + + private def readObject(in: java.io.ObjectInputStream): Unit = { + tpec = in.readObject().asInstanceOf[TypeCreator] + concrete = in.readBoolean() + } + + private def readResolve(): AnyRef = { + import scala.reflect.basis._ + if (concrete) TypeTag(rootMirror, tpec) + else AbsTypeTag(rootMirror, tpec) + } +}
\ No newline at end of file diff --git a/src/library/scala/reflect/base/Universe.scala b/src/library/scala/reflect/base/Universe.scala index 93ddcb9f55..6f37214fa8 100644 --- a/src/library/scala/reflect/base/Universe.scala +++ b/src/library/scala/reflect/base/Universe.scala @@ -10,9 +10,57 @@ abstract class Universe extends Symbols with Constants with AnnotationInfos with Positions + with Exprs with TypeTags with TagInterop with StandardDefinitions with StandardNames with BuildUtils - with Mirrors
\ No newline at end of file + with Mirrors +{ + /** Given an expression, generate a tree that when compiled and executed produces the original tree. + * The produced tree will be bound to the Universe it was called from. + * + * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression: + * + * {{{ + * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) + * }}} + * + * The reifier transforms it to the following expression: + * + * {{{ + * <[ + * val $u: u.type = u // where u is a reference to the Universe that calls the reify + * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1)))))) + * ]> + * }}} + * + * Reification performs expression splicing (when processing Expr.splice) + * and type splicing (for every type T that has a TypeTag[T] implicit in scope): + * + * {{{ + * val two = mirror.reify(2) // Literal(Constant(2)) + * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) + * + * def macroImpl[T](c: Context) = { + * ... + * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion + * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl) + * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation + * val factory = c.reify{ new Queryable[T] } + * ... + * } + * }}} + * + * The transformation looks mostly straightforward, but it has its tricky parts: + * * Reifier retains symbols and types defined outside the reified tree, however + * locally defined entities get erased and replaced with their original trees + * * Free variables are detected and wrapped in symbols of the type FreeVar + * * Mutable variables that are accessed from a local function are wrapped in refs + * * Since reified trees can be compiled outside of the scope they've been created in, + * special measures are taken to ensure that all members accessed in the reifee remain visible + */ + // implementation is magically hardwired to `scala.reflect.reify.Taggers` + def reify[T](expr: T): Expr[T] = ??? // macro +}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/internal/macroImpl.scala b/src/library/scala/reflect/macros/internal/macroImpl.scala index 0dfa8d1654..a7b2bf482c 100644 --- a/src/library/scala/reflect/makro/internal/macroImpl.scala +++ b/src/library/scala/reflect/macros/internal/macroImpl.scala @@ -1,4 +1,4 @@ -package scala.reflect.makro +package scala.reflect.macros package internal /** Links macro definitions with their implementation. diff --git a/src/library/scala/reflect/makro/internal/package.scala b/src/library/scala/reflect/macros/internal/package.scala index 78cb0ffb10..912db53ed4 100644 --- a/src/library/scala/reflect/makro/internal/package.scala +++ b/src/library/scala/reflect/macros/internal/package.scala @@ -1,8 +1,7 @@ -package scala.reflect -package makro +package scala.reflect.macros -import language.experimental.macros import scala.reflect.base.{Universe => BaseUniverse} +import scala.reflect.ClassTag // anchors for materialization macros emitted during tag materialization in Implicits.scala // implementation is magically hardwired into `scala.reflect.reify.Taggers` @@ -10,7 +9,7 @@ import scala.reflect.base.{Universe => BaseUniverse} // todo. once we have implicit macros for tag generation, we can remove these anchors // [Eugene++] how do I hide this from scaladoc? package object internal { - private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = macro ??? - private[scala] def materializeAbsTypeTag[T](u: BaseUniverse): u.AbsTypeTag[T] = macro ??? - private[scala] def materializeTypeTag[T](u: BaseUniverse): u.TypeTag[T] = macro ??? + private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = ??? // macro + private[scala] def materializeAbsTypeTag[T](u: BaseUniverse): u.AbsTypeTag[T] = ??? // macro + private[scala] def materializeTypeTag[T](u: BaseUniverse): u.TypeTag[T] = ??? // macro } diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala index 969176d641..6d105c9d20 100644 --- a/src/reflect/scala/reflect/api/FlagSets.scala +++ b/src/reflect/scala/reflect/api/FlagSets.scala @@ -9,8 +9,7 @@ trait FlagSets { self: Universe => trait FlagOps extends Any { def | (right: FlagSet): FlagSet - def & (right: FlagSet): FlagSet - def containsAll (right: FlagSet): Boolean + def hasFlag(flags: FlagSet): Boolean } implicit def addFlagOps(left: FlagSet): FlagOps @@ -19,8 +18,6 @@ trait FlagSets { self: Universe => type FlagValues >: Null <: FlagValuesApi - // [Eugene++] any other flags we would like to expose? - trait FlagValuesApi { /** Flag indicating that symbol or tree represents a trait */ @@ -100,13 +97,5 @@ trait FlagSets { self: Universe => /** Flag indicating that parameter has a default value */ val DEFAULTPARAM: FlagSet - - /** Flag indicating that trait has neither method implementations nor fields. - * This means the trait can be represented as a Java interface. */ - val INTERFACE: FlagSet - - def union(flags: FlagSet*): FlagSet - def intersection(flag: FlagSet*): FlagSet - def containsAll(superset: FlagSet, subset: FlagSet): Boolean } } diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala index 69d6414f4f..de540a9605 100644 --- a/src/reflect/scala/reflect/api/Importers.scala +++ b/src/reflect/scala/reflect/api/Importers.scala @@ -17,5 +17,7 @@ trait Importers { self: Universe => def importType(tpe: from.Type): Type def importTree(tree: from.Tree): Tree + + def importPosition(pos: from.Position): Position } }
\ No newline at end of file diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala index 27176a2a2d..a4d86cf1fd 100644 --- a/src/reflect/scala/reflect/api/Mirrors.scala +++ b/src/reflect/scala/reflect/api/Mirrors.scala @@ -34,7 +34,7 @@ trait Mirrors { self: Universe => * that can be used to get and, if appropriate, set the value of the field. * * To get a field symbol by the name of the field you would like to reflect, - * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the field>)).asTermSymbol`. + * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the field>)).asTerm.accessed`. * For further information about member lookup refer to `Symbol.typeSignature`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). @@ -54,7 +54,7 @@ trait Mirrors { self: Universe => * that can be used to invoke the method provided. * * To get a method symbol by the name of the method you would like to reflect, - * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the method>)).asMethodSymbol`. + * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the method>)).asMethod`. * For further information about member lookup refer to `Symbol.typeSignature`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). @@ -66,7 +66,7 @@ trait Mirrors { self: Universe => * that can be used to create instances of the class, inspect its companion object or perform further reflections. * * To get a class symbol by the name of the class you would like to reflect, - * use `<this mirror>.symbol.typeSignature.member(newTypeName(<name of the class>)).asClassSymbol`. + * use `<this mirror>.symbol.typeSignature.member(newTypeName(<name of the class>)).asClass`. * For further information about member lookup refer to `Symbol.typeSignature`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). @@ -78,7 +78,7 @@ trait Mirrors { self: Universe => * that can be used to get the instance of the object or inspect its companion class. * * To get a module symbol by the name of the object you would like to reflect, - * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the object>)).asModuleSymbol`. + * use `<this mirror>.symbol.typeSignature.member(newTermName(<name of the object>)).asModule`. * For further information about member lookup refer to `Symbol.typeSignature`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). @@ -201,7 +201,7 @@ trait Mirrors { self: Universe => * that can be used to invoke it and construct instances of this mirror's symbols. * * To get a constructor symbol you would like to reflect, - * use `<this mirror>.symbol.typeSignature.member(nme.CONSTRUCTOR).asMethodSymbol`. + * use `<this mirror>.symbol.typeSignature.member(nme.CONSTRUCTOR).asMethod`. * For further information about member lookup refer to `Symbol.typeSignature`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index c94c796279..13f5f743f1 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -12,15 +12,8 @@ trait Symbols extends base.Symbols { self: Universe => override type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi override type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi - trait HasFlagsApi { - def flags: FlagSet - def hasFlag(fs: FlagSet): Boolean - def hasAllFlags(fs: FlagSet): Boolean - def flagString: String - } - /** The API of symbols */ - trait SymbolApi extends SymbolBase with HasFlagsApi { this: Symbol => + trait SymbolApi extends SymbolBase with HasFlagsBase { this: Symbol => /** The position of this symbol */ @@ -50,22 +43,52 @@ trait Symbols extends base.Symbols { self: Universe => */ def hasAnnotation(sym: Symbol): Boolean - /** ... + /** For a class: the module or case class factory with the same name in the same package. + * For a module: the class with the same name in the same package. + * For all others: NoSymbol */ - def orElse(alt: => Symbol): Symbol + def companionSymbol: Symbol - /** ... + /** The type signature of this symbol seen as a member of given type `site`. */ - def filter(cond: Symbol => Boolean): Symbol + def typeSignatureIn(site: Type): Type - /** If this is a NoSymbol, returns NoSymbol, otherwise - * returns the result of applying `f` to this symbol. + /** The type signature of this symbol. + * Note if the symbol is a member of a class, one almost always is interested + * in `typeSignatureIn` with a site type instead. */ - def map(f: Symbol => Symbol): Symbol + def typeSignature: Type - /** ... + /******************* tests *******************/ + + /** Does this symbol represent a synthetic (i.e. a compiler-generated) entity? + * Examples of synthetic entities are accessors for vals and vars + * or mixin constructors in trait implementation classes. */ - def suchThat(cond: Symbol => Boolean): Symbol + def isSynthetic: Boolean + + /** Does this symbol represent a local declaration or definition? + * + * If yes, either `isPrivate` or `isProtected` are guaranteed to be true. + * Local symbols can only be accessed from the same object instance. + * + * If yes, `privateWithin` might tell more about this symbol's visibility scope. + */ + def isLocal: Boolean + + /** Does this symbol represent a private declaration or definition? + * If yes, `privateWithin` might tell more about this symbol's visibility scope. + */ + def isPrivate: Boolean + + /** Does this symbol represent a protected declaration or definition? + * If yes, `privateWithin` might tell more about this symbol's visibility scope. + */ + def isProtected: Boolean + + /** Does this symbol represent a public declaration or definition? + */ + def isPublic: Boolean /** * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. @@ -94,24 +117,77 @@ trait Symbols extends base.Symbols { self: Universe => */ def privateWithin: Symbol - /** For a class: the module or case class factory with the same name in the same package. - * For a module: the class with the same name in the same package. - * For all others: NoSymbol + /** Does this symbol represent the definition of a package? + * If yes, `isTerm` is also guaranteed to be true. */ - def companionSymbol: Symbol + def isPackage: Boolean + + /** Does this symbol represent a package class? + * If yes, `isClass` is also guaranteed to be true. + */ + def isPackageClass: Boolean + + /** Does this symbol or its underlying type represent a typechecking error? + */ + def isErroneous : Boolean + + /** Can this symbol be loaded by a reflective mirror? + * + * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. + * Such annotations (also called "pickles") are applied on top-level classes and include information + * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) + * are typically unreachable and information about them gets lost. + * + * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. + * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. + */ + def isLocatable: Boolean - /** If this symbol is a package class, this symbol; otherwise the next enclosing - * package class, or `NoSymbol` if none exists. + /** Is this symbol static (i.e. with no outer instance)? + * Q: When exactly is a sym marked as STATIC? + * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep. + * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6 + */ + def isStatic: Boolean + + /** Is this symbol final? + */ + def isFinal: Boolean + + /** Is this symbol overriding something? */ - def enclosingPackageClass: Symbol + def isOverride: Boolean - /** If this symbol is a top-level class, this symbol; otherwise the next enclosing - * top-level class, or `NoSymbol` if none exists. + /** Is this symbol a macro? */ - def enclosingTopLevelClass: Symbol + def isMacro: Boolean + /******************* helpers *******************/ + + /** ... + */ + def orElse(alt: => Symbol): Symbol + + /** ... + */ + def filter(cond: Symbol => Boolean): Symbol + + /** If this is a NoSymbol, returns NoSymbol, otherwise + * returns the result of applying `f` to this symbol. + */ + def map(f: Symbol => Symbol): Symbol + + /** ... + */ + def suchThat(cond: Symbol => Boolean): Symbol + + /** The string discriminator of this symbol; useful for debugging */ + def kind: String + } + + /** The API of term symbols */ + trait TermSymbolApi extends SymbolApi with TermSymbolBase { this: TermSymbol => /** Does this symbol represent a value, i.e. not a module and not a method? - * If yes, `isTerm` is also guaranteed to be true. * [Eugene++] I need a review of the implementation */ def isValue: Boolean @@ -120,7 +196,6 @@ trait Symbols extends base.Symbols { self: Universe => def isStable: Boolean /** Does this symbol represent a mutable value? - * If yes, `isTerm` and `isValue` are also guaranteed to be true. */ def isVariable: Boolean @@ -129,154 +204,131 @@ trait Symbols extends base.Symbols { self: Universe => def isAccessor: Boolean /** Does this symbol represent a getter of a field? - * If yes, `isTerm` and `isMethod` are also guaranteed to be true. + * If yes, `isMethod` is also guaranteed to be true. */ def isGetter: Boolean /** Does this symbol represent a setter of a field? - * If yes, `isTerm` and `isMethod` are also guaranteed to be true. + * If yes, `isMethod` is also guaranteed to be true. */ def isSetter: Boolean - /** Does this symbol represent the definition of a package? - * If yes, `isTerm` is also guaranteed to be true. + /** Does this symbol represent an overloaded method? + * If yes, `isMethod` is false, and the list of the enclosed alternatives can be found out via `alternatives`. */ - def isPackage: Boolean + def isOverloaded : Boolean - /** Does this symbol represent a package class? - * If yes, `isClass` is also guaranteed to be true. + /** Does this symbol represent an implicit value, definition or parameter? */ - def isPackageClass: Boolean + def isImplicit: Boolean - /** Is this symbol an overloaded method? + /** Does this symbol represent a lazy value? */ - def isOverloaded : Boolean + def isLazy: Boolean - /** Does this symbol represent the definition of a primitive class? - * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], - * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? + /** The overloaded alternatives of this symbol */ + def alternatives: List[Symbol] + + /** Backing field for an accessor method, NoSymbol for all other term symbols. */ - def isPrimitiveValueClass: Boolean + def accessed: Symbol - /** Does this symbol represent the definition of a numeric value class? - * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], - * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? + /** Getter method for a backing field of a val or a val, NoSymbol for all other term symbols. */ - def isNumericValueClass: Boolean + def getter: Symbol - /** Does this symbol represent the definition of a custom value class? - * Namely, is AnyVal among its parent classes? - * TODO: Why not just have in reflect.internal? - * [Eugene++] because it's useful for macros + /** Setter method for a backing field of a val or a val, NoSymbol for all other term symbols. */ - def isDerivedValueClass: Boolean + def setter: Symbol + } + + /** The API of type symbols */ + trait TypeSymbolApi extends SymbolApi with TypeSymbolBase { this: TypeSymbol => + /** Is the type parameter represented by this symbol contravariant? + */ + def isContravariant : Boolean + + /** Is the type parameter represented by this symbol contravariant? + */ + def isCovariant : Boolean + + /** Does this symbol represent the definition of a skolem? + * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. + */ + def isSkolem : Boolean /** Does this symbol represent the definition of a type alias? - * If yes, `isType` is also guaranteed to be true. */ def isAliasType : Boolean /** Does this symbol represent the definition of an abstract type? - * If yes, `isType` is also guaranteed to be true. */ def isAbstractType : Boolean /** Does this symbol represent an existentially bound type? - * If yes, `isType` is also guaranteed to be true. */ def isExistential : Boolean - /** Does this symbol represent a free type captured by reification? - */ - def isFreeType : Boolean + /** For a polymorphic type, its type parameters, the empty list for all other types */ + def typeParams: List[Symbol] + } - /** Does this symbol or its underlying type represent a typechecking error? - */ - def isErroneous : Boolean + /** The API of method symbols */ + trait MethodSymbolApi extends TermSymbolApi with MethodSymbolBase { this: MethodSymbol => + /** For a polymorphic method, its type parameters, the empty list for all other methods */ + def typeParams: List[Symbol] - /** Can this symbol be loaded by a reflective mirror? - * - * Scalac relies on `ScalaSignature' annotation to retain symbols across compilation runs. - * Such annotations (also called "pickles") are applied on top-level classes and include information - * about all symbols reachable from the annotee. However, local symbols (e.g. classes or definitions local to a block) - * are typically unreachable and information about them gets lost. + /** All parameter lists of the method. * - * This method is useful for macro writers who wish to save certain ASTs to be used at runtime. - * With `isLocatable' it's possible to check whether a tree can be retained as is, or it needs special treatment. + * Can be used to distinguish nullary methods and methods with empty parameter lists. + * For a nullary method, returns the empty list (i.e. `List()`). + * For a method with an empty parameter list, returns a list that contains the empty list (i.e. `List(List())`). */ - def isLocatable: Boolean + def params: List[List[Symbol]] - /** Is this symbol static (i.e. with no outer instance)? - * Q: When exactly is a sym marked as STATIC? - * A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep. - * http://groups.google.com/group/scala-internals/browse_thread/thread/d385bcd60b08faf6 - */ - def isStatic: Boolean - - /** The type signature of this symbol seen as a member of given type `site`. - */ - def typeSignatureIn(site: Type): Type - - /** The type signature of this symbol. - * Note if the symbol is a member of a class, one almost always is interested - * in `typeSignatureIn` with a site type instead. - */ - def typeSignature: Type - - /** The string discriminator of this symbol; useful for debugging */ - def kind: String + /** The return type of the method */ + def returnType: Type } - /** The API of term symbols */ - trait TermSymbolApi extends SymbolApi with HasFlagsApi with TermSymbolBase { this: TermSymbol => - /** The overloaded alternatives of this symbol */ - def alternatives: List[Symbol] - + /** The API of module symbols */ + trait ModuleSymbolApi extends TermSymbolApi with ModuleSymbolBase { this: ModuleSymbol => } - /** The API of type symbols */ - trait TypeSymbolApi extends SymbolApi with HasFlagsApi with TypeSymbolBase { this: TypeSymbol => - /** Is the type parameter represented by this symbol contravariant? + /** The API of class symbols */ + trait ClassSymbolApi extends TypeSymbolApi with ClassSymbolBase { this: ClassSymbol => + /** Does this symbol represent the definition of a primitive class? + * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? */ - def isContravariant : Boolean + def isPrimitive: Boolean - /** Is the type parameter represented by this symbol contravariant? + /** Does this symbol represent the definition of a numeric value class? + * Namely, is it one of [[scala.Double]], [[scala.Float]], [[scala.Long]], [[scala.Int]], [[scala.Char]], + * [[scala.Short]], [[scala.Byte]], [[scala.Unit]] or [[scala.Boolean]]? */ - def isCovariant : Boolean + def isNumeric: Boolean - /** Does this symbol represent the definition of a skolem? - * Skolems are used during typechecking to represent type parameters viewed from inside their scopes. - * If yes, `isType` is also guaranteed to be true. + /** Does this symbol represent the definition of a custom value class? + * Namely, is AnyVal among its parent classes? */ - def isSkolem : Boolean + def isDerivedValueClass: Boolean - /** A type reference that refers to this type symbol seen - * as a member of given type `site`. - */ - def asTypeIn(site: Type): Type - - /** A type reference that refers to this type symbol - * Note if symbol is a member of a class, one almost always is interested - * in `asTypeIn` with a site type instead. - * - * Example: Given a class declaration `class C[T] { ... } `, that generates a symbol - * `C`. Then `C.asType` is the type `C[T]`. - * - * By contrast, `C.typeSignature` would be a type signature of form - * `PolyType(ClassInfoType(...))` that describes type parameters, value - * parameters, parent types, and members of `C`. - */ - def asType: Type // !!! Same as typeSignature. - } + /** Does this symbol represent a trait? + */ + def isTrait: Boolean - /** The API of method symbols */ - type MethodSymbolApi = MethodSymbolBase + /** Does this symbol represent an abstract class? + */ + def isAbstractClass: Boolean - /** The API of module symbols */ - type ModuleSymbolApi = ModuleSymbolBase + /** Does this symbol represent a case class? + */ + def isCaseClass: Boolean + + /** Does this symbol represent a sealed class? + */ + def isSealed: Boolean - /** The API of class symbols */ - trait ClassSymbolApi extends TypeSymbolApi with ClassSymbolBase { this: ClassSymbol => /** If this symbol is a class or trait, its self type, otherwise the type * of the symbol itself. */ @@ -284,6 +336,9 @@ trait Symbols extends base.Symbols { self: Universe => /** The type `C.this`, where `C` is the current class */ def thisPrefix: Type + + /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait */ + def typeParams: List[Symbol] } /** The API of free term symbols */ diff --git a/src/reflect/scala/reflect/api/TagInterop.scala b/src/reflect/scala/reflect/api/TagInterop.scala index f1938083b5..4d2254cb9f 100644 --- a/src/reflect/scala/reflect/api/TagInterop.scala +++ b/src/reflect/scala/reflect/api/TagInterop.scala @@ -27,8 +27,8 @@ trait TagInterop { self: JavaUniverse => val jm = mirror.asInstanceOf[ju.Mirror] val sym = jm.classSymbol(manifest.erasure) val tpe = - if (manifest.typeArguments.isEmpty) sym.asType - else ju.appliedType(sym.asTypeConstructor, manifest.typeArguments map (targ => ju.manifestToTypeTag(jm, targ)) map (_.in(jm).tpe)) + if (manifest.typeArguments.isEmpty) sym.toType + else ju.appliedType(sym.toTypeConstructor, manifest.typeArguments map (targ => ju.manifestToTypeTag(jm, targ)) map (_.in(jm).tpe)) tpe.asInstanceOf[U # Type] case u => u.manifestToTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index 2d130daa4e..06c7ddeda4 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -109,6 +109,8 @@ trait Trees extends base.Trees { self: Universe => def duplicate: this.type } + override protected def treeType(tree: Tree) = tree.tpe + override type TermTree >: Null <: Tree with TermTreeApi /** The API that all term trees support */ @@ -640,8 +642,16 @@ trait Trees extends base.Trees { self: Universe => abstract class Transformer { val treeCopy: TreeCopier = newLazyTreeCopier protected[scala] var currentOwner: Symbol = rootMirror.RootClass - protected def currentMethod = currentOwner.enclosingMethod - protected def currentClass = currentOwner.enclosingClass + protected def currentMethod = { + def enclosingMethod(sym: Symbol): Symbol = + if (sym.isMethod || sym == NoSymbol) sym else enclosingMethod(sym.owner) + enclosingMethod(currentOwner) + } + protected def currentClass = { + def enclosingClass(sym: Symbol): Symbol = + if (sym.isClass || sym == NoSymbol) sym else enclosingClass(sym.owner) + enclosingClass(currentOwner) + } // protected def currentPackage = currentOwner.enclosingTopLevelClass.owner def transform(tree: Tree): Tree = itransform(this, tree) @@ -683,7 +693,7 @@ trait Trees extends base.Trees { self: Universe => type Modifiers >: Null <: ModifiersApi - abstract class ModifiersApi extends ModifiersBase with HasFlagsApi + abstract class ModifiersApi extends ModifiersBase } diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index 01de5fa9a7..199cf9b9e5 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -24,73 +24,35 @@ trait Types extends base.Types { self: Universe => */ def declaration(name: Name): Symbol - /** The collection of declarations in this type - * [Eugene++] why not List? + /** A `Scope` containing directly declared members of this type. + * Unlike `members` this method doesn't returns inherited members. + * + * Members in the returned scope might appear in arbitrary order. + * Use `declarations.sorted` to get an ordered list of members. */ - def declarations: Iterable[Symbol] + def declarations: MemberScope /** The member with given name, either directly declared or inherited, * an OverloadedSymbol if several exist, NoSymbol if none exist. */ def member(name: Name): Symbol - /** The non-private member with given name, either directly declared or inherited, - * an OverloadedSymbol if several exist, NoSymbol if none exist. - */ - def nonPrivateMember(name: Name): Symbol - - /** An iterable containing all members of this type (directly declared or inherited) - * Members appear in the linearization order of their owners. - * Members with the same owner appear in reverse order of their declarations. - * [Eugene++] the order needs to be reversed back, at least in the public API - */ - def members: Iterable[Symbol] - - /** An iterable containing all non-private members of this type (directly declared or inherited) - * Members appear in the linearization order of their owners. - * Members with the same owner appear in reverse order of their declarations. - */ - def nonPrivateMembers: Iterable[Symbol] - - /** Substitute symbols in `to` for corresponding occurrences of references to - * symbols `from` in this type. - */ - def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type - - /** Substitute types in `to` for corresponding occurrences of references to - * symbols `from` in this type. - */ - def substituteTypes(from: List[Symbol], to: List[Type]): Type - - /** If this is a parameterized types, the type arguments. - * Otherwise the empty list + /** A `Scope` containing all members of this type (directly declared or inherited). + * Unlike `declarations` this method also returns inherited members. + * + * Members in the returned scope might appear in arbitrary order. + * Use `declarations.sorted` to get an ordered list of members. */ - def typeArguments: List[Type] - - /** For a (potentially wrapped) poly type, its type parameters, - * the empty list for all other types */ - def typeParams: List[Symbol] - - /** For a (nullary) method or poly type, its direct result type, - * the type itself for all other types. */ - def resultType: Type + def members: MemberScope /** Is this type a type constructor that is missing its type arguments? */ - def isHigherKinded: Boolean // !!! This should be called "isTypeConstructor", no? + def takesTypeArgs: Boolean /** Returns the corresponding type constructor (e.g. List for List[T] or List[String]) */ def typeConstructor: Type - /** Does this type refer to spliceable types or is a spliceable type? - */ - def isConcrete: Boolean - - /** Is this type an abstract type that needs to be resolved? - */ - def isSpliceable: Boolean - /** * Expands type aliases and converts higher-kinded TypeRefs to PolyTypes. * Functions on types are also implemented as PolyTypes. @@ -99,7 +61,7 @@ trait Types extends base.Types { self: Universe => * TypeRef(pre, <List>, List()) is replaced by * PolyType(X, TypeRef(pre, <List>, List(X))) */ - def normalize: Type // !!! Alternative name? "normalize" is used to mean too many things. + def normalize: Type /** Does this type conform to given type argument `that`? */ def <:< (that: Type): Boolean @@ -111,7 +73,7 @@ trait Types extends base.Types { self: Universe => * in reverse linearization order, starting with the class itself and ending * in class Any. */ - def baseClasses: List[Symbol] // !!! Alternative name, perhaps linearization? + def baseClasses: List[Symbol] /** The least type instance of given class which is a supertype * of this type. Example: @@ -141,36 +103,7 @@ trait Types extends base.Types { self: Universe => /** The erased type corresponding to this type after * all transformations from Scala to Java have been performed. */ - def erasure: Type // !!! "erasedType", compare with "widen" (so "erase") or "underlying" (so "erased") - // why not name it "erasure"? - - /** Apply `f` to each part of this type, returning - * a new type. children get mapped before their parents */ - def map(f: Type => Type): Type - - /** Apply `f` to each part of this type, for side effects only */ - def foreach(f: Type => Unit) - - /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p`, - * or None if none exists. - */ - def find(p: Type => Boolean): Option[Type] - - /** Is there part of this type which satisfies predicate `p`? */ - def exists(p: Type => Boolean): Boolean - - /** Does this type contain a reference to given symbol? */ - def contains(sym: Symbol): Boolean - - /** If this is a compound type, the list of its parent types; - * otherwise the empty list - */ - def parents: List[Type] - - /** If this is a singleton type, returns the type underlying it; - * otherwise returns this type itself. - */ - def underlying: Type + def erasure: Type /** If this is a singleton type, widen it to its nearest underlying non-singleton * base type by applying one or more `underlying` dereferences. @@ -193,6 +126,36 @@ trait Types extends base.Types { self: Universe => */ def narrow: Type + /******************* helpers *******************/ + + /** Substitute symbols in `to` for corresponding occurrences of references to + * symbols `from` in this type. + */ + def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type + + /** Substitute types in `to` for corresponding occurrences of references to + * symbols `from` in this type. + */ + def substituteTypes(from: List[Symbol], to: List[Type]): Type + + /** Apply `f` to each part of this type, returning + * a new type. children get mapped before their parents */ + def map(f: Type => Type): Type + + /** Apply `f` to each part of this type, for side effects only */ + def foreach(f: Type => Unit) + + /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p`, + * or None if none exists. + */ + def find(p: Type => Boolean): Option[Type] + + /** Is there part of this type which satisfies predicate `p`? */ + def exists(p: Type => Boolean): Boolean + + /** Does this type contain a reference to given symbol? */ + def contains(sym: Symbol): Boolean + /** The string discriminator of this type; useful for debugging */ def kind: String } diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala index 85d8adc44f..3dce0f218e 100644 --- a/src/reflect/scala/reflect/api/Universe.scala +++ b/src/reflect/scala/reflect/api/Universe.scala @@ -1,8 +1,6 @@ package scala.reflect package api -import language.experimental.macros - abstract class Universe extends base.Universe with Symbols with Types @@ -16,53 +14,4 @@ abstract class Universe extends base.Universe with StandardDefinitions with StandardNames with Importers - with Exprs with AnnotationInfos -{ - - /** Given an expression, generate a tree that when compiled and executed produces the original tree. - * The produced tree will be bound to the Universe it was called from. - * - * For instance, given the abstract syntax tree representation of the <[ x + 1 ]> expression: - * - * {{{ - * Apply(Select(Ident("x"), "+"), List(Literal(Constant(1)))) - * }}} - * - * The reifier transforms it to the following expression: - * - * {{{ - * <[ - * val $u: u.type = u // where u is a reference to the Universe that calls the reify - * $u.Expr[Int]($u.Apply($u.Select($u.Ident($u.newFreeVar("x", <Int>, x), "+"), List($u.Literal($u.Constant(1)))))) - * ]> - * }}} - * - * Reification performs expression splicing (when processing Expr.splice) - * and type splicing (for every type T that has a TypeTag[T] implicit in scope): - * - * {{{ - * val two = mirror.reify(2) // Literal(Constant(2)) - * val four = mirror.reify(two.splice + two.splice) // Apply(Select(two.tree, newTermName("$plus")), List(two.tree)) - * - * def macroImpl[T](c: Context) = { - * ... - * // T here is just a type parameter, so the tree produced by reify won't be of much use in a macro expansion - * // however, if T were annotated with c.TypeTag (which would declare an implicit parameter for macroImpl) - * // then reification would subtitute T with the TypeTree that was used in a TypeApply of this particular macro invocation - * val factory = c.reify{ new Queryable[T] } - * ... - * } - * }}} - * - * The transformation looks mostly straightforward, but it has its tricky parts: - * * Reifier retains symbols and types defined outside the reified tree, however - * locally defined entities get erased and replaced with their original trees - * * Free variables are detected and wrapped in symbols of the type FreeVar - * * Mutable variables that are accessed from a local function are wrapped in refs - * * Since reified trees can be compiled outside of the scope they've been created in, - * special measures are taken to ensure that all members accessed in the reifee remain visible - */ - // implementation is magically hardwired to `scala.reflect.reify.Taggers` - def reify[T](expr: T): Expr[T] = macro ??? -}
\ No newline at end of file diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala index ad59605760..74b9442076 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/BuildUtils.scala @@ -8,11 +8,11 @@ trait BuildUtils extends base.BuildUtils { self: SymbolTable => class BuildImpl extends BuildBase { def selectType(owner: Symbol, name: String): TypeSymbol = - select(owner, newTypeName(name)).asTypeSymbol + select(owner, newTypeName(name)).asType def selectTerm(owner: Symbol, name: String): TermSymbol = { - val result = select(owner, newTermName(name)).asTermSymbol - if (result.isOverloaded) result.suchThat(!_.isMethod).asTermSymbol + val result = select(owner, newTermName(name)).asTerm + if (result.isOverloaded) result.suchThat(!_.isMethod).asTerm else result } @@ -26,7 +26,7 @@ trait BuildUtils extends base.BuildUtils { self: SymbolTable => def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = { val result = owner.info.decl(newTermName(name)).alternatives(index) - if (result ne NoSymbol) result.asMethodSymbol + if (result ne NoSymbol) result.asMethod else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName)) } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 90aa0b732c..bc2120a738 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -20,21 +20,21 @@ trait Definitions extends api.StandardDefinitions { object definitions extends DefinitionsClass // [Eugene] find a way to make these non-lazy - lazy val ByteTpe = definitions.ByteClass.asType - lazy val ShortTpe = definitions.ShortClass.asType - lazy val CharTpe = definitions.CharClass.asType - lazy val IntTpe = definitions.IntClass.asType - lazy val LongTpe = definitions.LongClass.asType - lazy val FloatTpe = definitions.FloatClass.asType - lazy val DoubleTpe = definitions.DoubleClass.asType - lazy val BooleanTpe = definitions.BooleanClass.asType - lazy val UnitTpe = definitions.UnitClass.asType - lazy val AnyTpe = definitions.AnyClass.asType - lazy val ObjectTpe = definitions.ObjectClass.asType - lazy val AnyValTpe = definitions.AnyValClass.asType - lazy val AnyRefTpe = definitions.AnyRefClass.asType - lazy val NothingTpe = definitions.NothingClass.asType - lazy val NullTpe = definitions.NullClass.asType + lazy val ByteTpe = definitions.ByteClass.toTypeConstructor + lazy val ShortTpe = definitions.ShortClass.toTypeConstructor + lazy val CharTpe = definitions.CharClass.toTypeConstructor + lazy val IntTpe = definitions.IntClass.toTypeConstructor + lazy val LongTpe = definitions.LongClass.toTypeConstructor + lazy val FloatTpe = definitions.FloatClass.toTypeConstructor + lazy val DoubleTpe = definitions.DoubleClass.toTypeConstructor + lazy val BooleanTpe = definitions.BooleanClass.toTypeConstructor + lazy val UnitTpe = definitions.UnitClass.toTypeConstructor + lazy val AnyTpe = definitions.AnyClass.toTypeConstructor + lazy val ObjectTpe = definitions.ObjectClass.toTypeConstructor + lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor + lazy val AnyRefTpe = definitions.AnyRefClass.toTypeConstructor + lazy val NothingTpe = definitions.NothingClass.toTypeConstructor + lazy val NullTpe = definitions.NullClass.toTypeConstructor /** Since both the value parameter types and the result type may * require access to the type parameter symbols, we model polymorphic @@ -183,11 +183,11 @@ trait Definitions extends api.StandardDefinitions { // It becomes tricky to create dedicated objects for other symbols because // of initialization order issues. lazy val JavaLangPackage = getRequiredPackage(sn.JavaLang) - lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClassSymbol + lazy val JavaLangPackageClass = JavaLangPackage.moduleClass.asClass lazy val ScalaPackage = getRequiredPackage(nme.scala_) - lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClassSymbol + lazy val ScalaPackageClass = ScalaPackage.moduleClass.asClass lazy val RuntimePackage = getRequiredPackage("scala.runtime") - lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClassSymbol + lazy val RuntimePackageClass = RuntimePackage.moduleClass.asClass lazy val JavaLangEnumClass = requiredClass[java.lang.Enum[_]] @@ -471,11 +471,11 @@ trait Definitions extends api.StandardDefinitions { lazy val OptManifestClass = requiredClass[scala.reflect.OptManifest[_]] lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type] - lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful - lazy val ExprClass = if (ExprsClass != NoSymbol) getMemberClass(ExprsClass, tpnme.Expr) else NoSymbol - def ExprSplice = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.splice) else NoSymbol - def ExprValue = if (ExprsClass != NoSymbol) getMemberMethod(ExprClass, nme.value) else NoSymbol - lazy val ExprModule = if (ExprsClass != NoSymbol) getMemberModule(ExprsClass, nme.Expr) else NoSymbol + lazy val ExprsClass = requiredClass[scala.reflect.base.Exprs] + lazy val ExprClass = getMemberClass(ExprsClass, tpnme.Expr) + def ExprSplice = getMemberMethod(ExprClass, nme.splice) + def ExprValue = getMemberMethod(ExprClass, nme.value) + lazy val ExprModule = getMemberModule(ExprsClass, nme.Expr) lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] @@ -486,8 +486,7 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeTagModule = getMemberModule(TypeTagsClass, nme.TypeTag) lazy val BaseUniverseClass = requiredClass[scala.reflect.base.Universe] - lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful - def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol + def BaseUniverseReify = getMemberMethod(BaseUniverseClass, nme.reify) lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful lazy val MirrorOfClass = requiredClass[scala.reflect.base.MirrorOf[_]] @@ -495,13 +494,13 @@ trait Definitions extends api.StandardDefinitions { lazy val TypeCreatorClass = requiredClass[scala.reflect.base.TypeCreator] lazy val TreeCreatorClass = requiredClass[scala.reflect.base.TreeCreator] - lazy val MacroContextClass = getClassIfDefined("scala.reflect.makro.Context") // defined in scala-reflect.jar, so we need to be careful + lazy val MacroContextClass = getClassIfDefined("scala.reflect.macros.Context") // defined in scala-reflect.jar, so we need to be careful def MacroContextPrefix = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.prefix) else NoSymbol def MacroContextPrefixType = if (MacroContextClass != NoSymbol) getMemberType(MacroContextClass, tpnme.PrefixType) else NoSymbol def MacroContextUniverse = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.universe) else NoSymbol def MacroContextMirror = if (MacroContextClass != NoSymbol) getMemberMethod(MacroContextClass, nme.mirror) else NoSymbol - lazy val MacroImplAnnotation = requiredClass[scala.reflect.makro.internal.macroImpl] - lazy val MacroInternalPackage = getPackageObject("scala.reflect.makro.internal") + lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] + lazy val MacroInternalPackage = getPackageObject("scala.reflect.macros.internal") def MacroInternal_materializeClassTag = getMemberMethod(MacroInternalPackage, nme.materializeClassTag) def MacroInternal_materializeAbsTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeAbsTypeTag) def MacroInternal_materializeTypeTag = getMemberMethod(MacroInternalPackage, nme.materializeTypeTag) @@ -1045,7 +1044,7 @@ trait Definitions extends api.StandardDefinitions { // System.err.println("isMethod = " + result.isMethod) // System.err.println("isTerm = " + result.isTerm) // System.err.println("isValue = " + result.isValue) - // result.asMethodSymbol + // result.asMethod // // prints this: // @@ -1074,8 +1073,8 @@ trait Definitions extends api.StandardDefinitions { // [scalacfork] // [scalacfork] uncaught exception during compilation: java.lang.ClassCastException // [scalacfork] error: java.lang.ClassCastException: value apply - // [scalacfork] at scala.reflect.base.Symbols$SymbolBase$class.asMethodSymbol(Symbols.scala:118) - // [scalacfork] at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethodSymbol(Symbols.scala:63) + // [scalacfork] at scala.reflect.base.Symbols$SymbolBase$class.asMethod(Symbols.scala:118) + // [scalacfork] at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethod(Symbols.scala:63) // [scalacfork] at scala.reflect.internal.Definitions$DefinitionsClass.Symbol_apply(Definitions.scala:381) // [Eugene++] should be a ClassCastException instead? diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala index 0354d2513c..6e77741355 100644 --- a/src/reflect/scala/reflect/internal/FlagSets.scala +++ b/src/reflect/scala/reflect/internal/FlagSets.scala @@ -13,8 +13,7 @@ trait FlagSets extends api.FlagSets { self: SymbolTable => private class FlagOpsImpl(left: Long) extends FlagOps { def | (right: Long): Long = left | right - def & (right: Long): Long = left & right - def containsAll (right: Long): Boolean = (right & ~left) == 0 + def hasFlag(right: Long): Boolean = (left & right) != 0 } val NoFlags: FlagSet = 0L @@ -47,20 +46,5 @@ trait FlagSets extends api.FlagSets { self: SymbolTable => val CONTRAVARIANT : FlagSet = Flags.CONTRAVARIANT val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM val INTERFACE : FlagSet = Flags.INTERFACE - - def union(flags: FlagSet*): FlagSet = { - var acc = 0L - for (flag <- flags) acc |= flag - acc - } - - def intersection(flags: FlagSet*): FlagSet = { - var acc = -1L - for (flag <- flags) acc &= flag - acc - } - - def containsAll(superset: FlagSet, subset: FlagSet): Boolean = - (subset & ~superset) == 0 } } diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index 431d9819a5..00017e087a 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -14,6 +14,7 @@ trait Importers { self: SymbolTable => def importSymbol(sym: from.Symbol) = sym.asInstanceOf[self.Symbol] def importType(tpe: from.Type) = tpe.asInstanceOf[self.Type] def importTree(tree: from.Tree) = tree.asInstanceOf[self.Tree] + def importPosition(pos: from.Position) = pos.asInstanceOf[self.Position] } } else { // todo. fix this loophole diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 18f9928124..8571ac1110 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -670,7 +670,7 @@ trait Printers extends api.Printers { self: SymbolTable => if (flags == NoFlags) nme.NoFlags.toString else { val s_flags = new collection.mutable.ListBuffer[String] - for (i <- 0 to 63 if (flags containsAll (1L << i))) + for (i <- 0 to 63 if (flags hasFlag (1L << i))) s_flags += flagToString(1L << i).replace("<", "").replace(">", "").toUpperCase s_flags mkString " | " } diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala index 89e3c52de6..ed390b5a3b 100644 --- a/src/reflect/scala/reflect/internal/Scopes.scala +++ b/src/reflect/scala/reflect/internal/Scopes.scala @@ -41,9 +41,9 @@ trait Scopes extends api.Scopes { self: SymbolTable => * This is necessary because when run from reflection every scope needs to have a * SynchronizedScope as mixin. */ - class Scope protected[Scopes] (initElems: ScopeEntry = null, initFingerPrints: Long = 0L) extends Iterable[Symbol] { - - /** A bitset containing the last 6 bits of the start value of every name + class Scope protected[Scopes] (initElems: ScopeEntry = null, initFingerPrints: Long = 0L) extends ScopeBase with MemberScopeBase { + + /** A bitset containing the last 6 bits of the start value of every name * stored in this scope. */ var fingerPrints: Long = initFingerPrints @@ -118,10 +118,10 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param sym ... */ - def enter[T <: Symbol](sym: T): T = { + def enter[T <: Symbol](sym: T): T = { fingerPrints |= sym.name.fingerPrint - enterEntry(newScopeEntry(sym, this)) - sym + enterEntry(newScopeEntry(sym, this)) + sym } /** enter a symbol, asserting that no symbol with same name exists in scope @@ -282,6 +282,10 @@ trait Scopes extends api.Scopes { self: SymbolTable => elemsCache } + /** Vanilla scope - symbols are stored in declaration order. + */ + def sorted: List[Symbol] = toList + /** Return the nesting level of this scope, i.e. the number of times this scope * was nested in another */ def nestingLevel = nestinglevel @@ -324,14 +328,46 @@ trait Scopes extends api.Scopes { self: SymbolTable => toList.map(_.defString).mkString(start, sep, end) override def toString(): String = mkString("Scope{\n ", ";\n ", "\n}") - } implicit val ScopeTag = ClassTag[Scope](classOf[Scope]) + type MemberScope = Scope + + implicit val MemberScopeTag = ClassTag[MemberScope](classOf[MemberScope]) + /** Create a new scope */ def newScope: Scope = new Scope() + /** Create a new scope to be used in `findMembers`. + * + * But why do we need a special scope for `findMembers`? + * Let me tell you a story. + * + * `findMembers` creates a synthetic scope and then iterates over + * base classes in linearization order, and for every scrutinized class + * iterates over `decls`, the collection of symbols declared in that class. + * Declarations that fit the filter get appended to the created scope. + * + * The problem is that `decls` returns a Scope, and to iterate a scope performantly + * one needs to go from its end to its beginning. + * + * Hence the `findMembers` scope is populated in a wicked order: + * symbols that belong to the same declaring class come in reverse order of their declaration, + * however, the scope itself is ordered w.r.t the linearization of the target type. + * + * Once `members` became a public API, this has been confusing countless numbers of users. + * Therefore we introduce a special flavor of scopes to accommodate this quirk of `findMembers` + */ + private[scala] def newFindMemberScope: Scope = new Scope() { + override def sorted = { + val members = toList + val owners = members.map(_.owner).distinct + val grouped = members groupBy (_.owner) + owners.flatMap(owner => grouped(owner).reverse) + } + } + /** Create a new scope nested in another one with which it shares its elements */ def newNestedScope(outer: Scope): Scope = new Scope(outer) diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 75962ff9d0..67456cf86b 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -616,7 +616,6 @@ trait StdNames { val apply: NameType = "apply" val applyDynamic: NameType = "applyDynamic" val applyDynamicNamed: NameType = "applyDynamicNamed" - val applyImpl: NameType = "applyImpl" val applyOrElse: NameType = "applyOrElse" val args : NameType = "args" val argv : NameType = "argv" @@ -628,14 +627,13 @@ trait StdNames { val array_length : NameType = "array_length" val array_update : NameType = "array_update" val arraycopy: NameType = "arraycopy" - val asTermSymbol: NameType = "asTermSymbol" - val asModuleSymbol: NameType = "asModuleSymbol" - val asMethodSymbol: NameType = "asMethodSymbol" - val asTypeSymbol: NameType = "asTypeSymbol" - val asClassSymbol: NameType = "asClassSymbol" + val asTerm: NameType = "asTerm" + val asModule: NameType = "asModule" + val asMethod: NameType = "asMethod" + val asType: NameType = "asType" + val asClass: NameType = "asClass" val asInstanceOf_ : NameType = "asInstanceOf" val asInstanceOf_Ob : NameType = "$asInstanceOf" - val asTypeConstructor: NameType = "asTypeConstructor" val assert_ : NameType = "assert" val assume_ : NameType = "assume" val basis : NameType = "basis" @@ -767,6 +765,7 @@ trait StdNames { val toObjectArray : NameType = "toObjectArray" val toSeq: NameType = "toSeq" val toString_ : NameType = if (forMSIL) "ToString" else "toString" + val toTypeConstructor: NameType = "toTypeConstructor" val tpe : NameType = "tpe" val tree : NameType = "tree" val true_ : NameType = "true" diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 5ae8f22c64..dfb434300d 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -9,7 +9,7 @@ package internal import scala.collection.{ mutable, immutable } import util._ -abstract class SymbolTable extends makro.Universe +abstract class SymbolTable extends macros.Universe with Collections with Names with Symbols diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index e6a9cb46c6..304caa74d4 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -75,15 +75,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => def typeSignature: Type = info def typeSignatureIn(site: Type): Type = site memberInfo this - def asType: Type = tpe - def asTypeIn(site: Type): Type = site.memberType(this) - def asTypeConstructor: Type = typeConstructor + def toType: Type = tpe + def toTypeIn(site: Type): Type = site.memberType(this) + def toTypeConstructor: Type = typeConstructor def setFlags(flags: FlagSet): this.type = setInternalFlags(flags) def setInternalFlags(flag: Long): this.type = { setFlag(flag); this } def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this } def getAnnotations: List[AnnotationInfo] = { initialize; annotations } def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this } + def getter: Symbol = getter(owner) + def setter: Symbol = setter(owner) } /** The class for all symbols */ @@ -454,6 +456,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isAliasType = false def isAbstractType = false def isSkolem = false + def isMacro = this hasFlag MACRO /** A Type, but not a Class. */ def isNonClassType = false @@ -2484,6 +2487,19 @@ trait Symbols extends api.Symbols { self: SymbolTable => mtpeResult = res res } + + override def params: List[List[Symbol]] = paramss + + override def returnType: Type = { + def loop(tpe: Type): Type = + tpe match { + case NullaryMethodType(ret) => loop(ret) + case MethodType(_, ret) => loop(ret) + case PolyType(_, tpe) => loop(tpe) + case tpe => tpe + } + loop(info) + } } implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol]) @@ -2747,8 +2763,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isJavaInterface = hasAllFlags(JAVA | TRAIT) override def isNestedClass = !owner.isPackageClass override def isNumericValueClass = definitions.isNumericValueClass(this) + override def isNumeric = isNumericValueClass override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE) override def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) + override def isPrimitive = isPrimitiveValueClass // The corresponding interface is the last parent by convention. private def lastParent = if (tpe.parents.isEmpty) NoSymbol else tpe.parents.last.typeSymbol @@ -2890,7 +2908,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => private[this] var typeOfThisCache: Type = _ private[this] var typeOfThisPeriod = NoPeriod - private var implicitMembersCacheValue: List[Symbol] = Nil + private var implicitMembersCacheValue: Scope = EmptyScope private var implicitMembersCacheKey1: Type = NoType private var implicitMembersCacheKey2: ScopeEntry = null @@ -2909,7 +2927,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => typeOfThisCache } - def implicitMembers: List[Symbol] = { + def implicitMembers: Scope = { val tp = info if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) { // Skip a package object class, because the members are also in diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 285700f9ff..d160695e67 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -1,7 +1,7 @@ package scala.reflect package internal -abstract class TreeGen extends makro.TreeBuilder { +abstract class TreeGen extends macros.TreeBuilder { val global: SymbolTable import global._ diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 619e3bc170..ddc40b2e9f 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1024,14 +1024,14 @@ trait Trees extends api.Trees { self: SymbolTable => } } - + /** Delegate for a TypeTree symbol. This operation is unsafe because * it may trigger type checking when forcing the type symbol of the * underlying type. */ protected def typeTreeSymbol(tree: TypeTree): Symbol = if (tree.tpe == null) null else tree.tpe.typeSymbol - + // --- generic traversers and transformers override protected def itraverse(traverser: Traverser, tree: Tree): Unit = { @@ -1266,7 +1266,7 @@ trait Trees extends api.Trees { self: SymbolTable => } } - private def mclass(sym: Symbol) = sym map (_.asModuleSymbol.moduleClass) + private def mclass(sym: Symbol) = sym map (_.asModule.moduleClass) // --- specific traversers and transformers diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 8972dfa828..442a91774d 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -323,6 +323,7 @@ trait Types extends api.Types { self: SymbolTable => /** Is this type higher-kinded, i.e., is it a type constructor @M */ def isHigherKinded: Boolean = false + def takesTypeArgs: Boolean = this.isHigherKinded /** Does this type denote a stable reference (i.e. singleton type)? */ def isStable: Boolean = false @@ -612,21 +613,21 @@ trait Types extends api.Types { self: SymbolTable => * Members appear in linearization order of their owners. * Members with the same owner appear in reverse order of their declarations. */ - def members: List[Symbol] = membersBasedOnFlags(0, 0) + def members: Scope = membersBasedOnFlags(0, 0) /** A list of all non-private members of this type (defined or inherited) */ - def nonPrivateMembers: List[Symbol] = membersBasedOnFlags(BridgeAndPrivateFlags, 0) + def nonPrivateMembers: Scope = membersBasedOnFlags(BridgeAndPrivateFlags, 0) /** A list of all non-private members of this type (defined or inherited), * admitting members with given flags `admit` */ - def nonPrivateMembersAdmitting(admit: Long): List[Symbol] = membersBasedOnFlags(BridgeAndPrivateFlags & ~admit, 0) + def nonPrivateMembersAdmitting(admit: Long): Scope = membersBasedOnFlags(BridgeAndPrivateFlags & ~admit, 0) /** A list of all implicit symbols of this type (defined or inherited) */ - def implicitMembers: List[Symbol] = membersBasedOnFlags(BridgeFlags, IMPLICIT) + def implicitMembers: Scope = membersBasedOnFlags(BridgeFlags, IMPLICIT) /** A list of all deferred symbols of this type (defined or inherited) */ - def deferredMembers: List[Symbol] = membersBasedOnFlags(BridgeFlags, DEFERRED) + def deferredMembers: Scope = membersBasedOnFlags(BridgeFlags, DEFERRED) /** The member with given name, * an OverloadedSymbol if several exist, NoSymbol if none exist */ @@ -642,12 +643,12 @@ trait Types extends api.Types { self: SymbolTable => /** All members with the given flags, excluding bridges. */ - def membersWithFlags(requiredFlags: Long): List[Symbol] = + def membersWithFlags(requiredFlags: Long): Scope = membersBasedOnFlags(BridgeFlags, requiredFlags) /** All non-private members with the given flags, excluding bridges. */ - def nonPrivateMembersWithFlags(requiredFlags: Long): List[Symbol] = + def nonPrivateMembersWithFlags(requiredFlags: Long): Scope = membersBasedOnFlags(BridgeAndPrivateFlags, requiredFlags) /** The non-private member with given name, admitting members with given flags `admit`. @@ -668,7 +669,7 @@ trait Types extends api.Types { self: SymbolTable => /** Members excluding and requiring the given flags. * Note: unfortunately it doesn't work to exclude DEFERRED this way. */ - def membersBasedOnFlags(excludedFlags: Long, requiredFlags: Long): List[Symbol] = + def membersBasedOnFlags(excludedFlags: Long, requiredFlags: Long): Scope = findMembers(excludedFlags, requiredFlags) // findMember(nme.ANYNAME, excludedFlags, requiredFlags, false).alternatives @@ -1020,7 +1021,7 @@ trait Types extends api.Types { self: SymbolTable => else (baseClasses.head.newOverloaded(this, alts)) } - def findMembers(excludedFlags: Long, requiredFlags: Long): List[Symbol] = { + def findMembers(excludedFlags: Long, requiredFlags: Long): Scope = { // if this type contains type variables, put them to sleep for a while -- don't just wipe them out by // replacing them by the corresponding type parameter, as that messes up (e.g.) type variables in type refinements // without this, the matchesType call would lead to type variables on both sides @@ -1054,7 +1055,7 @@ trait Types extends api.Types { self: SymbolTable => (bcs eq bcs0) || (flags & PrivateLocal) != PrivateLocal || (bcs0.head.hasTransOwner(bcs.head)))) { - if (members eq null) members = newScope + if (members eq null) members = newFindMemberScope var others: ScopeEntry = members.lookupEntry(sym.name) var symtpe: Type = null while ((others ne null) && { @@ -1083,7 +1084,7 @@ trait Types extends api.Types { self: SymbolTable => } // while (continue) Statistics.popTimer(typeOpsStack, start) if (suspension ne null) suspension foreach (_.suspended = false) - if (members eq null) Nil else members.toList + if (members eq null) EmptyScope else members } /** diff --git a/src/reflect/scala/reflect/makro/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala index 4bd246572f..46b7066902 100644 --- a/src/reflect/scala/reflect/makro/Aliases.scala +++ b/src/reflect/scala/reflect/macros/Aliases.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Aliases { self: Context => diff --git a/src/reflect/scala/reflect/makro/CapturedVariables.scala b/src/reflect/scala/reflect/macros/CapturedVariables.scala index 592e28b3b2..60ed6f5e7b 100644 --- a/src/reflect/scala/reflect/makro/CapturedVariables.scala +++ b/src/reflect/scala/reflect/macros/CapturedVariables.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait CapturedVariables { self: Context => diff --git a/src/reflect/scala/reflect/makro/Context.scala b/src/reflect/scala/reflect/macros/Context.scala index f093016a38..37c8f9057e 100644 --- a/src/reflect/scala/reflect/makro/Context.scala +++ b/src/reflect/scala/reflect/macros/Context.scala @@ -1,11 +1,9 @@ package scala.reflect -package makro - -import language.experimental.macros +package macros // todo. introduce context hierarchy // the most lightweight context should just expose the stuff from the SIP -// the full context should include all traits from scala.reflect.makro (and probably reside in scala-compiler.jar) +// the full context should include all traits from scala.reflect.macros (and probably reside in scala-compiler.jar) trait Context extends Aliases with CapturedVariables diff --git a/src/reflect/scala/reflect/makro/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala index ff5c13a785..a07ff85a08 100644 --- a/src/reflect/scala/reflect/makro/Enclosures.scala +++ b/src/reflect/scala/reflect/macros/Enclosures.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Enclosures { self: Context => diff --git a/src/reflect/scala/reflect/makro/Evals.scala b/src/reflect/scala/reflect/macros/Evals.scala index 4e5fc2f97f..3837d749da 100644 --- a/src/reflect/scala/reflect/makro/Evals.scala +++ b/src/reflect/scala/reflect/macros/Evals.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Evals { self: Context => diff --git a/src/reflect/scala/reflect/makro/ExprUtils.scala b/src/reflect/scala/reflect/macros/ExprUtils.scala index c3e5cc6bc1..adcdc78c78 100644 --- a/src/reflect/scala/reflect/makro/ExprUtils.scala +++ b/src/reflect/scala/reflect/macros/ExprUtils.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait ExprUtils { self: Context => diff --git a/src/reflect/scala/reflect/makro/Exprs.scala b/src/reflect/scala/reflect/macros/Exprs.scala index 91d3dafbf2..ceaab06d12 100644 --- a/src/reflect/scala/reflect/makro/Exprs.scala +++ b/src/reflect/scala/reflect/macros/Exprs.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Exprs { self: Context => diff --git a/src/reflect/scala/reflect/makro/FrontEnds.scala b/src/reflect/scala/reflect/macros/FrontEnds.scala index 5087f90174..d15db0725f 100644 --- a/src/reflect/scala/reflect/makro/FrontEnds.scala +++ b/src/reflect/scala/reflect/macros/FrontEnds.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait FrontEnds extends scala.reflect.api.FrontEnds { self: Context => diff --git a/src/reflect/scala/reflect/makro/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala index e6bfe33366..1f1bd160a1 100644 --- a/src/reflect/scala/reflect/makro/Infrastructure.scala +++ b/src/reflect/scala/reflect/macros/Infrastructure.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Infrastructure { self: Context => diff --git a/src/reflect/scala/reflect/makro/Names.scala b/src/reflect/scala/reflect/macros/Names.scala index 909976d83c..fab9bbbca5 100644 --- a/src/reflect/scala/reflect/makro/Names.scala +++ b/src/reflect/scala/reflect/macros/Names.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Names { self: Context => diff --git a/src/reflect/scala/reflect/makro/Parsers.scala b/src/reflect/scala/reflect/macros/Parsers.scala index 9866b7e491..ea87c5842e 100644 --- a/src/reflect/scala/reflect/makro/Parsers.scala +++ b/src/reflect/scala/reflect/macros/Parsers.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Parsers { self: Context => diff --git a/src/reflect/scala/reflect/makro/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala index f39f56f935..1bee17d548 100644 --- a/src/reflect/scala/reflect/makro/Reifiers.scala +++ b/src/reflect/scala/reflect/macros/Reifiers.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Reifiers { self: Context => diff --git a/src/reflect/scala/reflect/makro/Settings.scala b/src/reflect/scala/reflect/macros/Settings.scala index c6c7e5870b..8d166056c3 100644 --- a/src/reflect/scala/reflect/makro/Settings.scala +++ b/src/reflect/scala/reflect/macros/Settings.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Settings { self: Context => diff --git a/src/reflect/scala/reflect/makro/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala index c4179b9c80..06f5caf68b 100644 --- a/src/reflect/scala/reflect/makro/TreeBuilder.scala +++ b/src/reflect/scala/reflect/macros/TreeBuilder.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros // [Eugene] I added some stuff that was necessary for typetag materialization macros // but we should think it over and pick other generally useful stuff diff --git a/src/reflect/scala/reflect/makro/TypeTags.scala b/src/reflect/scala/reflect/macros/TypeTags.scala index 53a9b116e3..8f590d1de4 100644 --- a/src/reflect/scala/reflect/makro/TypeTags.scala +++ b/src/reflect/scala/reflect/macros/TypeTags.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait TypeTags { self: Context => diff --git a/src/reflect/scala/reflect/makro/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala index 2610d7dd50..eef6507418 100644 --- a/src/reflect/scala/reflect/makro/Typers.scala +++ b/src/reflect/scala/reflect/macros/Typers.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros trait Typers { self: Context => @@ -10,8 +10,8 @@ trait Typers { * Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion. * * Is also priceless for emitting sane error messages for macros that are called by other macros on synthetic (i.e. position-less) trees. - * In that dire case navigate the ``openMacros'' stack, and it will most likely contain at least one macro with a position-ful macro application. - * See ``enclosingPosition'' for a default implementation of this logic. + * In that dire case navigate the `openMacros` stack, and it will most likely contain at least one macro with a position-ful macro application. + * See `enclosingPosition` for a default implementation of this logic. * * Unlike `enclosingMacros`, this is a def, which means that it gets recalculated on every invocation, * so it might change depending on what is going on during macro expansion. @@ -26,41 +26,38 @@ trait Typers { */ def openImplicits: List[(Type, Tree)] - /** Typechecks the provided tree against the expected type ``pt'' in the macro callsite context. + /** Typechecks the provided tree against the expected type `pt` in the macro callsite context. * - * 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. + * 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-verbose. - * Unlike in ``inferImplicitValue'' and ``inferImplicitView'', ``silent'' is false by default. + * Unlike in `inferImplicitValue` and `inferImplicitView`, `silent` is false by default. * * Typechecking can be steered with the following optional parameters: - * ``withImplicitViewsDisabled'' recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false - * ``withMacrosDisabled'' recursively prohibits macro expansions and macro-based implicits, default value is false + * `withImplicitViewsDisabled` recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false + * `withMacrosDisabled` recursively prohibits macro expansions and macro-based implicits, default value is false */ def typeCheck(tree: Tree, pt: Type = WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree - /** Infers an implicit value of the expected type ``pt'' in the macro callsite context. - * Optional ``pos'' parameter provides a position that will be associated with the implicit search. + /** Infers an implicit value of the expected type `pt` in the macro callsite context. + * Optional `pos` parameter provides a position that will be associated with the implicit search. * - * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * If `silent` is false, `TypeError` will be thrown in case of an inference 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 -Xlog-implicits. - * Unlike in ``typeCheck'', ``silent'' is true by default. + * Unlike in `typeCheck`, `silent` is true by default. */ def inferImplicitValue(pt: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree - /** Infers an implicit view from the provided tree ``tree'' from the type ``from'' to the type ``to'' in the macro callsite context. + /** Infers an implicit view from the provided tree `tree` of the type `from` to the type `to` in the macro callsite context. + * Optional `pos` parameter provides a position that will be associated with the implicit search. * - * Optional ``pos'' parameter provides a position that will be associated with the implicit search. - * Another optional parameter, ``reportAmbiguous`` controls whether ambiguous implicit errors should be reported. - * If we search for a view simply to find out whether one type is coercible to another, it might be desirable to set this flag to ``false''. - * - * If ``silent'' is false, ``TypeError'' will be thrown in case of an inference error. - * If ``silent'' is true, the typecheck is silent and will return ``EmptyTree'' if an error occurs. + * If `silent` is false, `TypeError` will be thrown in case of an inference 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 -Xlog-implicits. - * Unlike in ``typeCheck'', ``silent'' is true by default. + * Unlike in `typeCheck`, `silent` is true by default. */ - def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, reportAmbiguous: Boolean = true, pos: Position = enclosingPosition): Tree + def inferImplicitView(tree: Tree, from: Type, to: Type, silent: Boolean = true, withMacrosDisabled: Boolean = false, pos: Position = enclosingPosition): Tree /** Recursively resets symbols and types in a given tree. * diff --git a/src/reflect/scala/reflect/makro/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala index d88e7e0bb8..4074dd9e93 100644 --- a/src/reflect/scala/reflect/makro/Universe.scala +++ b/src/reflect/scala/reflect/macros/Universe.scala @@ -1,5 +1,5 @@ package scala.reflect -package makro +package macros abstract class Universe extends scala.reflect.api.Universe { diff --git a/src/reflect/scala/reflect/makro/package.scala b/src/reflect/scala/reflect/macros/package.scala index 3c0e51030e..06ce0b3244 100644 --- a/src/reflect/scala/reflect/makro/package.scala +++ b/src/reflect/scala/reflect/macros/package.scala @@ -1,6 +1,6 @@ package scala.reflect -package object makro { +package object macros { type MirrorOf[U <: base.Universe with Singleton] = base.MirrorOf[U] } diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 0878801715..64c47a5502 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -150,7 +150,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym def classSymbol(rtcls: RuntimeClass): ClassSymbol = classToScala(rtcls) - def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol = classToScala(rtcls).companionModule.asModuleSymbol + def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol = classToScala(rtcls).companionModule.asModule private def checkMemberOf(wannabe: Symbol, owner: Symbol) = if (!owner.info.member(wannabe.name).alternatives.contains(wannabe)) ErrorNotMember(wannabe, owner) @@ -166,7 +166,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym if (field.isGetter) nme.getterToLocal(field.name) else if (field.isSetter) nme.getterToLocal(nme.setterToGetter(field.name)) else field.name - val field1 = (field.owner.info decl name).asTermSymbol + val field1 = (field.owner.info decl name).asTerm try fieldToJava(field1) catch { case _: NoSuchFieldException => ErrorNonExistentField(field1) @@ -187,6 +187,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym checkMemberOf(mod, symbol) new JavaModuleMirror(instance, mod) } + override def toString = s"instance mirror for $obj" } private class JavaFieldMirror(val receiver: AnyRef, val symbol: TermSymbol) @@ -201,6 +202,32 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym if (!symbol.isMutable) ErrorSetImmutableField(symbol) jfield.set(receiver, value) } + override def toString = s"field mirror for ${symbol.fullName} (bound to $receiver)" + } + + private def showMethodSig(symbol: MethodSymbol): String = { + var sig = s"${symbol.fullName}" + if (symbol.typeParams.nonEmpty) { + def showTparam(tparam: Symbol) = + tparam.typeSignature match { + case tpe @ TypeBounds(_, _) => s"${tparam.name}$tpe" + case _ => tparam.name + } + def showTparams(tparams: List[Symbol]) = "[" + (tparams map showTparam mkString ", ") + "]" + sig += showTparams(symbol.typeParams) + } + if (symbol.params.nonEmpty) { + def showParam(param: Symbol) = s"${param.name}: ${param.typeSignature}" + def showParams(params: List[Symbol]) = { + val s_mods = if (params.nonEmpty && params(0).hasFlag(IMPLICIT)) "implicit " else "" + val s_params = params map showParam mkString ", " + "(" + s_mods + s_params + ")" + } + def showParamss(paramss: List[List[Symbol]]) = paramss map showParams mkString "" + sig += showParamss(symbol.params) + } + sig += s": ${symbol.returnType}" + sig } private class JavaMethodMirror(val receiver: AnyRef, val symbol: MethodSymbol) @@ -220,6 +247,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym } else jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*) + override def toString = s"method mirror for ${showMethodSig(symbol)} (bound to $receiver)" } private class JavaConstructorMirror(val outer: AnyRef, val symbol: MethodSymbol) @@ -236,9 +264,9 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym else outer +: args.asInstanceOf[Seq[AnyRef]] jconstr.newInstance(effectiveArgs: _*) } + override def toString = s"constructor mirror for ${showMethodSig(symbol)} (bound to $outer)" } - private abstract class JavaTemplateMirror extends TemplateMirror { def outer: AnyRef @@ -256,11 +284,12 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym case module: ModuleSymbol => Some(new JavaModuleMirror(outer, module)) case _ => None } + override def toString = s"class mirror for ${symbol.fullName} (bound to $outer)" } private class JavaModuleMirror(val outer: AnyRef, val symbol: ModuleSymbol) extends JavaTemplateMirror with ModuleMirror { - def erasure = symbol.moduleClass.asClassSymbol + def erasure = symbol.moduleClass.asClass def isStatic = true def instance = { if (!symbol.owner.isPackageClass) throw new Error("inner and nested modules are not supported yet") @@ -270,6 +299,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym case cls: ClassSymbol => Some(new JavaClassMirror(outer, cls)) case _ => None } + override def toString = s"module mirror for ${symbol.fullName} (bound to $outer)" } // -------------------- Java to Scala ----------------------------------- @@ -629,7 +659,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym val preOwner = classToScala(jOwner) val owner = followStatic(preOwner, jmeth.getModifiers) (lookup(owner, jmeth.getName) suchThat (erasesTo(_, jmeth)) orElse jmethodAsScala(jmeth)) - .asMethodSymbol + .asMethod } /** @@ -643,7 +673,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym private def constructorToScala1(jconstr: jConstructor[_]): MethodSymbol = { val owner = followStatic(classToScala(jconstr.getDeclaringClass), jconstr.getModifiers) (lookup(owner, jconstr.getName) suchThat (erasesTo(_, jconstr)) orElse jconstrAsScala(jconstr)) - .asMethodSymbol + .asMethod } /** @@ -657,8 +687,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym private def fieldToScala1(jfield: jField): TermSymbol = { val owner = followStatic(classToScala(jfield.getDeclaringClass), jfield.getModifiers) - (lookup(owner, jfield.getName) suchThat (!_.isMethod) orElse jfieldAsScala(jfield)) - .asTermSymbol + (lookup(owner, jfield.getName) suchThat (!_.isMethod) orElse jfieldAsScala(jfield)).asTerm } /** @@ -691,7 +720,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym val name = (fullname: TermName) drop split + 1 val opkg = owner.info decl name if (opkg.isPackage) - opkg.asModuleSymbol + opkg.asModule else if (opkg == NoSymbol) { val pkg = owner.newPackage(name) pkg.moduleClass setInfo new LazyPackageType @@ -758,7 +787,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym s"""${if (cls == NoSymbol) "not a type: symbol" else "no symbol could be"} | loaded from $jclazz in $owner with name $simpleName and classloader $classLoader""".stripMargin) - cls.asClassSymbol + cls.asClass } } @@ -773,7 +802,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym private def typeParamToScala1(jparam: jTypeVariable[_ <: GenericDeclaration]): TypeSymbol = { val owner = genericDeclarationToScala(jparam.getGenericDeclaration) owner.info match { - case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get.asTypeSymbol + case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get.asType } } @@ -941,7 +970,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym else if (clazz.owner.isPackageClass) javaClass(clazz.javaClassName) else if (clazz.owner.isClass) - classToJava(clazz.owner.asClassSymbol) + classToJava(clazz.owner.asClass) .getDeclaredClasses .find(_.getSimpleName == clazz.name.toString) .getOrElse(noClass) @@ -957,7 +986,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym * @param meth The Scala field. */ def fieldToJava(fld: TermSymbol): jField = fieldCache.toJava(fld) { - val jclazz = classToJava(fld.owner.asClassSymbol) + val jclazz = classToJava(fld.owner.asClass) val jname = nme.dropLocalSuffix(fld.name).toString try jclazz getDeclaredField jname catch { @@ -969,7 +998,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym * @param meth The Scala method */ def methodToJava(meth: MethodSymbol): jMethod = methodCache.toJava(meth) { - val jclazz = classToJava(meth.owner.asClassSymbol) + val jclazz = classToJava(meth.owner.asClass) val paramClasses = transformedType(meth).paramTypes map typeToJavaClass val jname = nme.dropLocalSuffix(meth.name).toString try jclazz getDeclaredMethod (jname, paramClasses: _*) @@ -983,7 +1012,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym * @param constr The Scala constructor */ def constructorToJava(constr: MethodSymbol): jConstructor[_] = constructorCache.toJava(constr) { - val jclazz = classToJava(constr.owner.asClassSymbol) + val jclazz = classToJava(constr.owner.asClass) val paramClasses = transformedType(constr).paramTypes map typeToJavaClass val effectiveParamClasses = if (!constr.owner.owner.isStaticOwner) jclazz.getEnclosingClass +: paramClasses @@ -1001,7 +1030,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym def typeToJavaClass(tpe: Type): jClass[_] = tpe match { case ExistentialType(_, rtpe) => typeToJavaClass(rtpe) case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe)) - case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClassSymbol) + case TypeRef(_, sym: ClassSymbol, _) => classToJava(sym.asClass) case tpe @ TypeRef(_, sym: AliasTypeSymbol, _) => typeToJavaClass(tpe.dealias) case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found") } diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala index 3b28ddf42c..c65357b652 100644 --- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala +++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala @@ -110,6 +110,8 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => trait SynchronizedMethodSymbol extends MethodSymbol with SynchronizedTermSymbol { override def typeAsMemberOf(pre: Type): Type = synchronized { super.typeAsMemberOf(pre) } + override def params: List[List[Symbol]] = synchronized { super.params } + override def returnType: Type = synchronized { super.returnType } } trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol { @@ -134,7 +136,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable => override def sourceModule = synchronized { super.sourceModule } // [Eugene++ to Martin] doesn't override anything. no longer necessary? // def sourceModule_=(module: ModuleSymbol) = synchronized { super.sourceModule_=(module) } - override def implicitMembers: List[Symbol] = synchronized { super.implicitMembers } + override def implicitMembers: Scope = synchronized { super.implicitMembers } } } diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala index a5809a2629..2cb72d3824 100644 --- a/src/reflect/scala/reflect/runtime/package.scala +++ b/src/reflect/scala/reflect/runtime/package.scala @@ -1,7 +1,5 @@ package scala.reflect -import language.experimental.macros - package object runtime { // type is api.JavaUniverse because we only want to expose the `scala.reflect.api.*` subset of reflection @@ -9,12 +7,13 @@ package object runtime { // [Eugene++ to Martin] removed `mirrorOfLoader`, because one can use `universe.runtimeMirror` instead - def currentMirror: universe.Mirror = macro Macros.currentMirror + // implementation magically hardwired to the `currentMirror` method below + def currentMirror: universe.Mirror = ??? // macro } package runtime { object Macros { - def currentMirror(c: scala.reflect.makro.Context): c.Expr[universe.Mirror] = { + def currentMirror(c: scala.reflect.macros.Context): c.Expr[universe.Mirror] = { import c.universe._ val runtimeClass = c.reifyEnclosingRuntimeClass if (runtimeClass.isEmpty) c.abort(c.enclosingPosition, "call site does not have an enclosing class") |