diff options
31 files changed, 284 insertions, 148 deletions
diff --git a/src/compiler/scala/reflect/macros/compiler/Errors.scala b/src/compiler/scala/reflect/macros/compiler/Errors.scala index 45bb87fc47..30ba082a81 100644 --- a/src/compiler/scala/reflect/macros/compiler/Errors.scala +++ b/src/compiler/scala/reflect/macros/compiler/Errors.scala @@ -12,6 +12,8 @@ trait Errors extends Traces { import definitions._ import typer.TyperErrorGen._ import typer.infer.InferErrorGen._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions._ def globalSettings = global.settings // sanity check errors diff --git a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala index 49a5c01ad7..9c4db1990b 100644 --- a/src/compiler/scala/reflect/macros/compiler/Resolvers.scala +++ b/src/compiler/scala/reflect/macros/compiler/Resolvers.scala @@ -12,6 +12,8 @@ trait Resolvers { import definitions.{EmptyPackageClass => _, _} import treeInfo._ import gen._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions.{Predef_???, _} /** Determines the type of context implied by the macro def. */ diff --git a/src/compiler/scala/reflect/macros/compiler/Validators.scala b/src/compiler/scala/reflect/macros/compiler/Validators.scala index b3e8131e34..088b108844 100644 --- a/src/compiler/scala/reflect/macros/compiler/Validators.scala +++ b/src/compiler/scala/reflect/macros/compiler/Validators.scala @@ -11,6 +11,8 @@ trait Validators { import global._ import analyzer._ import definitions._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions.{Predef_???, _} def validateMacroImplRef() = { sanityCheck() diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala index dd23b0fc32..bb4f2055ad 100644 --- a/src/compiler/scala/reflect/macros/util/Helpers.scala +++ b/src/compiler/scala/reflect/macros/util/Helpers.scala @@ -23,6 +23,9 @@ trait Helpers { * or to streamline creation of the list of macro arguments. */ def transformTypeTagEvidenceParams(macroImplRef: Tree, transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + val MacroContextUniverse = definitions.MacroContextUniverse val treeInfo.MacroImplReference(isBundle, _, macroImpl, _) = macroImplRef val paramss = macroImpl.paramss @@ -51,15 +54,25 @@ trait Helpers { * * @see Metalevels.scala for more information and examples about metalevels */ - def increaseMetalevel(pre: Type, tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) { - case tp => typeRef(pre, MacroContextExprClass, List(tp)) + def increaseMetalevel(pre: Type, tp: Type): Type = { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + + transparentShallowTransform(RepeatedParamClass, tp) { + case tp => typeRef(pre, MacroContextExprClass, List(tp)) + } } /** Transforms c.Expr[T] types into c.Tree and leaves the rest unchanged. */ - def untypeMetalevel(tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) { - case ExprClassOf(_) => typeRef(tp.prefix, TreesTreeType, Nil) - case tp => tp + def untypeMetalevel(tp: Type): Type = { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + + transparentShallowTransform(RepeatedParamClass, tp) { + case ExprClassOf(_) => typeRef(tp.prefix, TreesTreeType, Nil) + case tp => tp + } } /** Decreases metalevel of the type, i.e. transforms: @@ -68,8 +81,12 @@ trait Helpers { * * @see Metalevels.scala for more information and examples about metalevels */ - def decreaseMetalevel(tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) { - case ExprClassOf(runtimeType) => runtimeType - case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference + def decreaseMetalevel(tp: Type): Type = { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + transparentShallowTransform(RepeatedParamClass, tp) { + case ExprClassOf(runtimeType) => runtimeType + case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference + } } -}
\ No newline at end of file +} diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala index 74949fce6d..ad0632f93e 100644 --- a/src/compiler/scala/reflect/reify/Reifier.scala +++ b/src/compiler/scala/reflect/reify/Reifier.scala @@ -20,6 +20,8 @@ abstract class Reifier extends States val global: Global import global._ import definitions._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions._ val typer: global.analyzer.Typer val universe: Tree @@ -110,7 +112,7 @@ abstract class Reifier extends States // maybe try `resetLocalAttrs` once the dust settles var importantSymbols = Set[Symbol]( NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass, - ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror) + ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, runDefinitions.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 0bffe55403..0c7831b592 100644 --- a/src/compiler/scala/reflect/reify/Taggers.scala +++ b/src/compiler/scala/reflect/reify/Taggers.scala @@ -8,6 +8,8 @@ abstract class Taggers { import c.universe._ import definitions._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions._ val coreTags = Map( ByteTpe -> nme.Byte, diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index 6c94726231..99b968be3b 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -6,6 +6,8 @@ trait GenTypes { import global._ import definitions._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions.{ReflectRuntimeUniverse, ReflectRuntimeCurrentMirror, _} /** * Reify a type. diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 30cfec8e2a..eea63d8f28 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -63,11 +63,11 @@ package object reify { tpe.dealiasWiden match { case TypeRef(_, ArrayClass, componentTpe :: Nil) => val componentErasure = reifyRuntimeClass(global)(typer0, componentTpe, concrete) - gen.mkMethodCall(arrayClassMethod, List(componentErasure)) + gen.mkMethodCall(currentRun.runDefinitions.arrayClassMethod, List(componentErasure)) case _ => var erasure = tpe.erasure if (tpe.typeSymbol.isDerivedValueClass && global.phase.id < global.currentRun.erasurePhase.id) erasure = tpe - gen.mkNullaryCall(Predef_classOf, List(erasure)) + gen.mkNullaryCall(currentRun.runDefinitions.Predef_classOf, List(erasure)) } } diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index fff6978653..6c073c0b4c 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -9,6 +9,8 @@ trait Reshape { import global._ import definitions._ import treeInfo.Unapplied + private val runDefinitions = currentRun.runDefinitions + import runDefinitions._ /** * Rolls back certain changes that were introduced during typechecking of the reifee. diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index a80fee876e..d44e7a9312 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -702,7 +702,7 @@ abstract class GenICode extends SubComponent { } genLoadApply3 - case Apply(fun @ _, List(expr)) if (definitions.isBox(fun.symbol)) => + case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) => def genLoadApply4 = { debuglog("BOX : " + fun.symbol.fullName) val ctx1 = genLoad(expr, ctx, toTypeKind(expr.tpe)) @@ -721,7 +721,7 @@ abstract class GenICode extends SubComponent { } genLoadApply4 - case Apply(fun @ _, List(expr)) if (definitions.isUnbox(fun.symbol)) => + case Apply(fun @ _, List(expr)) if (currentRun.runDefinitions.isUnbox(fun.symbol)) => debuglog("UNBOX : " + fun.symbol.fullName) val ctx1 = genLoad(expr, ctx, toTypeKind(expr.tpe)) val boxType = toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 3bacc26a3a..c166b0bb7e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -623,14 +623,14 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { abort(s"Cannot instantiate $tpt of kind: $generatedType") } - case Apply(fun @ _, List(expr)) if definitions.isBox(fun.symbol) => + case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) => val nativeKind = tpeTK(expr) genLoad(expr, nativeKind) val MethodNameAndType(mname, mdesc) = asmBoxTo(nativeKind) bc.invokestatic(BoxesRunTime.getInternalName, mname, mdesc) generatedType = boxResultType(fun.symbol) // was toTypeKind(fun.symbol.tpe.resultType) - case Apply(fun @ _, List(expr)) if definitions.isUnbox(fun.symbol) => + case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isUnbox(fun.symbol) => genLoad(expr) val boxType = unboxResultType(fun.symbol) // was toTypeKind(fun.symbol.owner.linkedClassOfClass.tpe) generatedType = boxType diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala index 39fea9a486..916d118b6e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeTypes.scala @@ -90,11 +90,11 @@ abstract class BCodeTypes extends BCodeIdiomatic { ) boxResultType = - for(Pair(csym, msym) <- definitions.boxMethod) + for(Pair(csym, msym) <- currentRun.runDefinitions.boxMethod) yield (msym -> classLiteral(primitiveTypeMap(csym))) unboxResultType = - for(Pair(csym, msym) <- definitions.unboxMethod) + for(Pair(csym, msym) <- currentRun.runDefinitions.unboxMethod) yield (msym -> primitiveTypeMap(csym)) // boxed classes are looked up in the `exemplars` map by jvmWiseLUB(). diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 0135190256..3ecce8d7b1 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -168,7 +168,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) def cacheRHS = ((REF(methodCache) DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) BLOCK( - REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), + REF(methodSym) === (REF(currentRun.runDefinitions.ensureAccessibleMethod) APPLY (methodSymRHS)), REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), Return(REF(methodSym)) ) @@ -181,11 +181,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def testForName(name: Name): Tree => Tree = t => ( if (nme.CommonOpNames(name)) - gen.mkMethodCall(Boxes_isNumberOrBool, t :: Nil) + gen.mkMethodCall(currentRun.runDefinitions.Boxes_isNumberOrBool, t :: Nil) else if (nme.BooleanOpNames(name)) t IS_OBJ BoxedBooleanClass.tpe else - gen.mkMethodCall(Boxes_isNumber, t :: Nil) + gen.mkMethodCall(currentRun.runDefinitions.Boxes_isNumber, t :: Nil) ) /* The Tree => Tree function in the return is necessary to prevent the original qual @@ -219,6 +219,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL { /* ### CALLING THE APPLY ### */ def callAsReflective(paramTypes: List[Type], resType: Type): Tree = { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + gen.evalOnce(qual, currentOwner, unit) { qual1 => /* Some info about the type of the method being called. */ val methSym = ad.symbol @@ -518,7 +521,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { // // See SI-6611; we must *only* do this for literal vararg arrays. case Apply(appMeth, List(Apply(wrapRefArrayMeth, List(arg @ StripCast(ArrayValue(_, _)))), _)) - if wrapRefArrayMeth.symbol == Predef_wrapRefArray && appMeth.symbol == ArrayModule_genericApply => + if wrapRefArrayMeth.symbol == currentRun.runDefinitions.Predef_wrapRefArray && appMeth.symbol == ArrayModule_genericApply => super.transform(arg) case Apply(appMeth, List(elem0, Apply(wrapArrayMeth, List(rest @ ArrayValue(elemtpt, _))))) if wrapArrayMeth.symbol == Predef_wrapArray(elemtpt.tpe) && appMeth.symbol == ArrayModule_apply(elemtpt.tpe) => diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 2ec7e97ac5..b97b1e3527 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -362,6 +362,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { * be an error to pass it to array_update(.., .., Object). */ def rewriteArrayUpdate(tree: Tree): Tree = { + val arrayUpdateMethod = currentRun.runDefinitions.arrayUpdateMethod val adapter = new Transformer { override def transform(t: Tree): Tree = t match { case Apply(fun @ Select(receiver, method), List(xs, idx, v)) if fun.symbol == arrayUpdateMethod => diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 4cf3bef939..1723c69180 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -101,6 +101,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private val concreteSpecMethods = perRunCaches.newWeakSet[Symbol]() private def specializedOn(sym: Symbol): List[Symbol] = { + val GroupOfSpecializable = currentRun.runDefinitions.GroupOfSpecializable sym getAnnotation SpecializedClass match { case Some(AnnotationInfo(_, Nil, _)) => specializableTypes.map(_.typeSymbol) case Some(ann @ AnnotationInfo(_, args, _)) => { diff --git a/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala b/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala index 41b8461c46..f83b6f857e 100644 --- a/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala +++ b/src/compiler/scala/tools/nsc/transform/TypeAdaptingTransformer.scala @@ -25,7 +25,7 @@ trait TypeAdaptingTransformer { } private def isSafelyRemovableUnbox(fn: Tree, arg: Tree): Boolean = { - isUnbox(fn.symbol) && { + currentRun.runDefinitions.isUnbox(fn.symbol) && { val cls = arg.tpe.typeSymbol (cls == definitions.NullClass) || isBoxedValueClass(cls) } @@ -75,7 +75,7 @@ trait TypeAdaptingTransformer { log(s"boxing an unbox: ${tree.symbol} -> ${arg.tpe}") arg case _ => - (REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectTpe + (REF(currentRun.runDefinitions.boxMethod(x)) APPLY tree) setPos (tree.pos) setType ObjectTpe } } } @@ -123,7 +123,7 @@ trait TypeAdaptingTransformer { case x => assert(x != ArrayClass) // don't `setType pt` the Apply tree, as the Apply's fun won't be typechecked if the Apply tree already has a type - Apply(unboxMethod(pt.typeSymbol), tree) + Apply(currentRun.runDefinitions.unboxMethod(pt.typeSymbol), tree) } } typer.typedPos(tree.pos)(tree1) @@ -184,4 +184,4 @@ trait TypeAdaptingTransformer { cast(tree, pt) } } -}
\ No newline at end of file +} diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala index c8dbbb02bb..06b39b035a 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchCodeGen.scala @@ -72,7 +72,7 @@ trait MatchCodeGen extends Interface { // for name-based matching, but this was an expedient route for the basics. def drop(tgt: Tree)(n: Int): Tree = { def callDirect = fn(tgt, nme.drop, LIT(n)) - def callRuntime = Apply(REF(traversableDropMethod), tgt :: LIT(n) :: Nil) + def callRuntime = Apply(REF(currentRun.runDefinitions.traversableDropMethod), tgt :: LIT(n) :: Nil) def needsRuntime = (tgt.tpe ne null) && (typeOfMemberNamedDrop(tgt.tpe) == NoType) if (needsRuntime) callRuntime else callDirect diff --git a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala index 567d5d0ecd..0b5b0759b2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Adaptations.scala @@ -24,6 +24,8 @@ trait Adaptations { trait Adaptation { self: Typer => + import runDefinitions._ + def checkValidAdaptation(t: Tree, args: List[Tree]): Boolean = { def applyArg = t match { case Apply(_, arg :: Nil) => arg diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index dc60631421..b1a48f7478 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -338,7 +338,7 @@ trait Implicits { val wildPt = approximate(pt) private val runDefintions = currentRun.runDefinitions - import runDefintions.{ TagMaterializers, TagSymbols, Predef_conforms, PartialManifestClass, ManifestSymbols } + import runDefintions._ def undet_s = if (undetParams.isEmpty) "" else undetParams.mkString(" inferring ", ", ", "") def tree_s = typeDebug ptTree tree diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index d1045757a5..02fb70f3e5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -104,7 +104,10 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { targs: List[Tree]) { // Was this binding derived from a `def ... = macro ???` definition? - def is_??? = className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded + def is_??? = { + val Predef_??? = currentRun.runDefinitions.Predef_??? + className == Predef_???.owner.javaClassName && methName == Predef_???.name.encoded + } } /** Macro def -> macro impl bindings are serialized into a `macroImpl` annotation @@ -146,6 +149,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { } def pickle(macroImplRef: Tree): Tree = { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ val MacroImplReference(isBundle, owner, macroImpl, targs) = macroImplRef // todo. refactor when fixing SI-5498 @@ -311,7 +316,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers { def fail() = { if (macroDef != null) macroDef setFlag IS_ERROR; macroDdef setType ErrorType; EmptyTree } def success(macroImplRef: Tree) = { bindMacroImpl(macroDef, macroImplRef); macroImplRef } - if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) { + if (!typer.checkFeature(macroDdef.pos, currentRun.runDefinitions.MacrosFeature, immediate = true)) { macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled") fail() } else { diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 36f889f8a4..84531608e0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -945,7 +945,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } def checkImplicitViewOptionApply(pos: Position, fn: Tree, args: List[Tree]): Unit = if (settings.lint) (fn, args) match { - case (tap@TypeApply(fun, targs), List(view: ApplyImplicitView)) if fun.symbol == Option_apply => + case (tap@TypeApply(fun, targs), List(view: ApplyImplicitView)) if fun.symbol == currentRun.runDefinitions.Option_apply => unit.warning(pos, s"Suspicious application of an implicit view (${view.fun}) in the argument to Option.apply.") // SI-6567 case _ => } diff --git a/src/compiler/scala/tools/nsc/typechecker/Tags.scala b/src/compiler/scala/tools/nsc/typechecker/Tags.scala index 32a66aa4dd..90ec3a89b8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Tags.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Tags.scala @@ -10,6 +10,9 @@ trait Tags { trait Tag { self: Typer => + private val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + private def resolveTag(pos: Position, taggedTp: Type, allowMaterialization: Boolean) = enteringTyper { def wrapper (tree: => Tree): Tree = if (allowMaterialization) (context.withMacrosEnabled[Tree](tree)) else (context.withMacrosDisabled[Tree](tree)) wrapper(inferImplicit( diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c385e7533a..a9bb81c691 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -115,6 +115,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper import context0.unit import typeDebug.{ ptTree, ptBlock, ptLine, inGreen, inRed } import TyperErrorGen._ + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ val infer = new Inferencer(context0) { // See SI-3281 re undoLog @@ -3847,7 +3849,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (sameLength(tparams, args)) { val targs = args map (_.tpe) checkBounds(tree, NoPrefix, NoSymbol, tparams, targs, "") - if (fun.symbol == Predef_classOf) + if (isPredefClassOf(fun.symbol)) typedClassOf(tree, args.head, noGen = true) else { if (!isPastTyper && fun.symbol == Any_isInstanceOf && targs.nonEmpty) { @@ -4807,7 +4809,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper typed1(This(sym.owner) setPos tree.pos, mode, pt) // Inferring classOf type parameter from expected type. Otherwise an // actual call to the stubbed classOf method is generated, returning null. - else if (isPredefMemberNamed(sym, nme.classOf) && pt.typeSymbol == ClassClass && pt.typeArgs.nonEmpty) + else if (isPredefClassOf(sym) && pt.typeSymbol == ClassClass && pt.typeArgs.nonEmpty) typedClassOf(tree, TypeTree(pt.typeArgs.head)) else { val pre1 = if (sym.isTopLevel) sym.owner.thisType else if (qual == EmptyTree) NoPrefix else qual.tpe diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index ad1d4c896b..dd92e14602 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -37,14 +37,19 @@ trait FastTrack { } /** A map from a set of pre-established macro symbols to their implementations. */ - lazy val fastTrack = Map[Symbol, FastTrackEntry]( - make( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) }, - make( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) }, - make( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) }, - make( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }, - make( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) }, - make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree }, - make( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote }, - make(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote } - ) + def fastTrack: Map[Symbol, FastTrackEntry] = fastTrackCache() + private val fastTrackCache = perRunCaches.newGeneric[Map[Symbol, FastTrackEntry]] { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + Map[Symbol, FastTrackEntry]( + make( materializeClassTag) { case Applied(_, ttag :: Nil, _) => _.materializeClassTag(ttag.tpe) }, + make( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) }, + make( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) }, + make( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }, + make( StringContext_f) { case Applied(Select(Apply(_, ps), _), _, args) => c => c.macro_StringInterpolation_f(ps, args.flatten, c.expandee.pos) }, + make(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree }, + make( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote }, + make(QuasiquoteClass_api_unapply) { case _ => _.expandQuasiquote } + ) + } } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 9a382649d9..7cb051c63d 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -68,7 +68,7 @@ trait Definitions extends api.StandardDefinitions { tpnme.Unit -> VOID_TAG ) - private def catastrophicFailure() = + private[Definitions] def catastrophicFailure() = abort("Could not find value classes! This is a catastrophic failure. scala " + scala.util.Properties.versionString) @@ -78,16 +78,8 @@ trait Definitions extends api.StandardDefinitions { case _ => catastrophicFailure() } } - private def valueClassCompanion(name: TermName): ModuleSymbol = { - getMember(ScalaPackageClass, name) match { - case x: ModuleSymbol => x - case _ => catastrophicFailure() - } - } - private def valueCompanionMember(className: Name, methodName: TermName): TermSymbol = - getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName) - private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) + private[Definitions] def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f) private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = mapFrom(syms)(x => f(x.name)) private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f) @@ -99,8 +91,6 @@ trait Definitions extends api.StandardDefinitions { lazy val boxedClass = classesMap(x => getClassByName(boxedName(x))) lazy val refClass = classesMap(x => getRequiredClass("scala.runtime." + x + "Ref")) lazy val volatileRefClass = classesMap(x => getRequiredClass("scala.runtime.Volatile" + x + "Ref")) - lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box)) - lazy val unboxMethod = classesMap(x => valueCompanionMember(x, nme.unbox)) def isNumericSubClass(sub: Symbol, sup: Symbol) = ( (numericWeight contains sub) @@ -125,9 +115,9 @@ trait Definitions extends api.StandardDefinitions { lazy val FloatClass = valueClassSymbol(tpnme.Float) lazy val DoubleClass = valueClassSymbol(tpnme.Double) lazy val BooleanClass = valueClassSymbol(tpnme.Boolean) - lazy val Boolean_and = getMemberMethod(BooleanClass, nme.ZAND) - lazy val Boolean_or = getMemberMethod(BooleanClass, nme.ZOR) - lazy val Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!) + def Boolean_and = getMemberMethod(BooleanClass, nme.ZAND) + def Boolean_or = getMemberMethod(BooleanClass, nme.ZOR) + def Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!) lazy val UnitTpe = UnitClass.tpe lazy val ByteTpe = ByteClass.tpe @@ -356,14 +346,9 @@ trait Definitions extends api.StandardDefinitions { // Those modules and their module classes lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass) - lazy val PredefModule = requiredModule[scala.Predef.type] - def Predef_classOf = getMemberMethod(PredefModule, nme.classOf) - def Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray) - def Predef_wrapArray(tp: Type) = getMemberMethod(PredefModule, wrapArrayMethodName(tp)) - def Predef_??? = getMemberMethod(PredefModule, nme.???) - def Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly) - - @deprecated("use sym = currentRun.runDefinitions.Predef_xxx", "2.11.0") + lazy val PredefModule = requiredModule[scala.Predef.type] + def Predef_wrapArray(tp: Type) = getMemberMethod(PredefModule, wrapArrayMethodName(tp)) + def Predef_??? = getMemberMethod(PredefModule, nme.???) def isPredefMemberNamed(sym: Symbol, name: Name) = ( (sym.name == name) && (sym.owner == PredefModule.moduleClass) ) @@ -371,24 +356,13 @@ trait Definitions extends api.StandardDefinitions { /** Specialization. */ lazy val SpecializableModule = requiredModule[Specializable] - lazy val GroupOfSpecializable = getMemberClass(SpecializableModule, tpnme.Group) lazy val ScalaRunTimeModule = requiredModule[scala.runtime.ScalaRunTime.type] lazy val SymbolModule = requiredModule[scala.Symbol.type] - lazy val Symbol_apply = getMemberMethod(SymbolModule, nme.apply) - - def arrayApplyMethod = getMemberMethod(ScalaRunTimeModule, nme.array_apply) - def arrayUpdateMethod = getMemberMethod(ScalaRunTimeModule, nme.array_update) - def arrayLengthMethod = getMemberMethod(ScalaRunTimeModule, nme.array_length) - def arrayCloneMethod = getMemberMethod(ScalaRunTimeModule, nme.array_clone) - def ensureAccessibleMethod = getMemberMethod(ScalaRunTimeModule, nme.ensureAccessible) - def arrayClassMethod = getMemberMethod(ScalaRunTimeModule, nme.arrayClass) - def traversableDropMethod = getMemberMethod(ScalaRunTimeModule, nme.drop) + def Symbol_apply = getMemberMethod(SymbolModule, nme.apply) // classes with special meanings lazy val StringAddClass = requiredClass[scala.runtime.StringAdd] - lazy val ArrowAssocClass = getRequiredClass("scala.Predef.ArrowAssoc") // SI-5731 - lazy val StringAdd_+ = getMemberMethod(StringAddClass, nme.PLUS) lazy val ScalaNumberClass = requiredClass[scala.math.ScalaNumber] lazy val TraitSetterAnnotationClass = requiredClass[scala.runtime.TraitSetter] lazy val DelayedInitClass = requiredClass[scala.DelayedInit] @@ -450,7 +424,6 @@ trait Definitions extends api.StandardDefinitions { def isReferenceArray(tp: Type) = elementTest(ArrayClass, tp)(_ <:< AnyRefTpe) def isArrayOfSymbol(tp: Type, elem: Symbol) = elementTest(ArrayClass, tp)(_.typeSymbol == elem) def elementType(container: Symbol, tp: Type): Type = elementExtract(container, tp) - object ExprClassOf { def unapply(tp: Type): Option[Type] = elementExtractOption(ExprClass, tp) } // collections classes lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]] @@ -462,7 +435,7 @@ trait Definitions extends api.StandardDefinitions { lazy val TraversableClass = requiredClass[scala.collection.Traversable[_]] lazy val ListModule = requiredModule[scala.collection.immutable.List.type] - lazy val List_apply = getMemberMethod(ListModule, nme.apply) + def List_apply = getMemberMethod(ListModule, nme.apply) lazy val NilModule = requiredModule[scala.collection.immutable.Nil.type] lazy val SeqModule = requiredModule[scala.collection.Seq.type] @@ -503,28 +476,17 @@ trait Definitions extends api.StandardDefinitions { lazy val NoManifest = requiredModule[scala.reflect.NoManifest.type] lazy val TreesClass = getClassIfDefined("scala.reflect.api.Trees") // defined in scala-reflect.jar, so we need to be careful - lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree)) - object TreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain contains TreesTreeType } - object SubtreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain exists (_.tpe <:< TreesTreeType.tpe) } lazy val ExprsClass = getClassIfDefined("scala.reflect.api.Exprs") // defined in scala-reflect.jar, so we need to be careful - lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) + def ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr)) def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice)) def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value)) lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]] lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]] lazy val TypeTagsClass = getClassIfDefined("scala.reflect.api.TypeTags") // defined in scala-reflect.jar, so we need to be careful - lazy val WeakTypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.WeakTypeTag)) - lazy val WeakTypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.WeakTypeTag)) - lazy val TypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.TypeTag)) - lazy val TypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.TypeTag)) - def materializeClassTag = getMemberMethod(ReflectPackage, nme.materializeClassTag) - def materializeWeakTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeWeakTypeTag)) - def materializeTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeTypeTag)) lazy val ApiUniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful - def ApiUniverseReify = ApiUniverseClass.map(sym => getMemberMethod(sym, nme.reify)) lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful lazy val MirrorClass = getClassIfDefined("scala.reflect.api.Mirror") // defined in scala-reflect.jar, so we need to be careful @@ -545,7 +507,6 @@ trait Definitions extends api.StandardDefinitions { lazy val MacroImplAnnotation = requiredClass[scala.reflect.macros.internal.macroImpl] lazy val StringContextClass = requiredClass[scala.StringContext] - def StringContext_f = getMemberMethod(StringContextClass, nme.f) lazy val QuasiquoteClass = if (ApiUniverseClass != NoSymbol) getMember(ApiUniverseClass, tpnme.Quasiquote) else NoSymbol lazy val QuasiquoteClass_api = if (QuasiquoteClass != NoSymbol) getMember(QuasiquoteClass, tpnme.api) else NoSymbol @@ -558,7 +519,6 @@ trait Definitions extends api.StandardDefinitions { // Option classes lazy val OptionClass: ClassSymbol = requiredClass[Option[_]] lazy val OptionModule: ModuleSymbol = requiredModule[scala.Option.type] - lazy val Option_apply = getMemberMethod(OptionModule, nme.apply) lazy val SomeClass: ClassSymbol = requiredClass[Some[_]] lazy val NoneModule: ModuleSymbol = requiredModule[scala.None.type] lazy val SomeModule: ModuleSymbol = requiredModule[scala.Some.type] @@ -566,10 +526,6 @@ trait Definitions extends api.StandardDefinitions { def compilerTypeFromTag(tt: ApiUniverse # WeakTypeTag[_]): Type = tt.in(rootMirror).tpe def compilerSymbolFromTag(tt: ApiUniverse # WeakTypeTag[_]): Symbol = tt.in(rootMirror).tpe.typeSymbol - // The given symbol represents either String.+ or StringAdd.+ - def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ - def isArrowAssoc(sym: Symbol) = sym.owner == ArrowAssocClass - // The given symbol is a method with the right name and signature to be a runnable java program. def isJavaMainMethod(sym: Symbol) = (sym.name == nme.main) && (sym.info match { case MethodType(p :: Nil, restpe) => isArrayOfSymbol(p.tpe, StringClass) && restpe.typeSymbol == UnitClass @@ -590,6 +546,9 @@ trait Definitions extends api.StandardDefinitions { else appliedType(apply(arity), args ++ others: _*) } } + // would be created synthetically for the default args. We call all objects in this method from the generated code + // in JavaUniverseForce, so it is clearer to define this explicitly define this in source. + object VarArityClass val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22 @@ -1083,9 +1042,6 @@ trait Definitions extends api.StandardDefinitions { lazy val BoxedFloatClass = requiredClass[java.lang.Float] lazy val BoxedDoubleClass = requiredClass[java.lang.Double] - lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean) - lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber) - lazy val BoxedUnitClass = requiredClass[scala.runtime.BoxedUnit] lazy val BoxedUnitModule = getRequiredModule("scala.runtime.BoxedUnit") def BoxedUnit_UNIT = getMemberValue(BoxedUnitModule, nme.UNIT) @@ -1143,14 +1099,6 @@ trait Definitions extends api.StandardDefinitions { // Language features lazy val languageFeatureModule = getRequiredModule("scala.languageFeature") - lazy val experimentalModule = getMemberModule(languageFeatureModule, nme.experimental) - lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule) - lazy val DynamicsFeature = getLanguageFeature("dynamics") - lazy val PostfixOpsFeature = getLanguageFeature("postfixOps") - lazy val ReflectiveCallsFeature = getLanguageFeature("reflectiveCalls") - lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions") - lazy val HigherKindsFeature = getLanguageFeature("higherKinds") - lazy val ExistentialsFeature = getLanguageFeature("existentials") def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || ( // Trying to allow for deprecated locations @@ -1291,9 +1239,6 @@ trait Definitions extends api.StandardDefinitions { newPolyMethod(1, owner, name, flags)(tparams => (Some(Nil), createFn(tparams.head))) } - lazy val isUnbox = unboxMethod.values.toSet[Symbol] - lazy val isBox = boxMethod.values.toSet[Symbol] - /** Is symbol a phantom class for which no runtime representation exists? */ lazy val isPhantomClass = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass) /** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ @@ -1413,16 +1358,97 @@ trait Definitions extends api.StandardDefinitions { def universeMemberType(name: TypeName) = universe.tpe.memberType(getTypeMember(universe.symbol, name)) } - /** Efficient access to member symbols which must be looked up each run. Access via `currentRun.runRefinitions` */ + /** Efficient access to member symbols which must be looked up each run. Access via `currentRun.runDefinitions` */ final class RunDefinitions { + lazy val StringAdd_+ = getMemberMethod(StringAddClass, nme.PLUS) + + // The given symbol represents either String.+ or StringAdd.+ + def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ + + lazy val StringContext_f = getMemberMethod(StringContextClass, nme.f) + + lazy val ArrowAssocClass = getMemberClass(PredefModule, TypeName("ArrowAssoc")) // SI-5731 + def isArrowAssoc(sym: Symbol) = sym.owner == ArrowAssocClass + + lazy val Boxes_isNumberOrBool = getDecl(BoxesRunTimeClass, nme.isBoxedNumberOrBoolean) + lazy val Boxes_isNumber = getDecl(BoxesRunTimeClass, nme.isBoxedNumber) + + private def valueClassCompanion(name: TermName): ModuleSymbol = { + getMember(ScalaPackageClass, name) match { + case x: ModuleSymbol => x + case _ => catastrophicFailure() + } + } + + private def valueCompanionMember(className: Name, methodName: TermName): TermSymbol = + getMemberMethod(valueClassCompanion(className.toTermName).moduleClass, methodName) + + lazy val boxMethod = classesMap(x => valueCompanionMember(x, nme.box)) + lazy val unboxMethod = classesMap(x => valueCompanionMember(x, nme.unbox)) + lazy val isUnbox = unboxMethod.values.toSet[Symbol] + lazy val isBox = boxMethod.values.toSet[Symbol] + + lazy val Option_apply = getMemberMethod(OptionModule, nme.apply) + lazy val List_apply = DefinitionsClass.this.List_apply + + /** + * Is the given symbol `List.apply`? + * To to avoid bootstrapping cycles, this return false if the given symbol or List itself is not initialized. + */ + def isListApply(sym: Symbol) = sym.isInitialized && ListModule.hasCompleteInfo && sym == List_apply + def isPredefClassOf(sym: Symbol) = if (PredefModule.hasCompleteInfo) sym == Predef_classOf else isPredefMemberNamed(sym, nme.classOf) + lazy val TagMaterializers = Map[Symbol, Symbol]( ClassTagClass -> materializeClassTag, WeakTypeTagClass -> materializeWeakTypeTag, TypeTagClass -> materializeTypeTag ) lazy val TagSymbols = TagMaterializers.keySet - lazy val Predef_conforms = getMemberMethod(PredefModule, nme.conforms) - lazy val Predef_classOf = DefinitionsClass.this.Predef_classOf + lazy val Predef_conforms = getMemberMethod(PredefModule, nme.conforms) + lazy val Predef_classOf = getMemberMethod(PredefModule, nme.classOf) + lazy val Predef_implicitly = getMemberMethod(PredefModule, nme.implicitly) + lazy val Predef_wrapRefArray = getMemberMethod(PredefModule, nme.wrapRefArray) + lazy val Predef_??? = DefinitionsClass.this.Predef_??? + + lazy val arrayApplyMethod = getMemberMethod(ScalaRunTimeModule, nme.array_apply) + lazy val arrayUpdateMethod = getMemberMethod(ScalaRunTimeModule, nme.array_update) + lazy val arrayLengthMethod = getMemberMethod(ScalaRunTimeModule, nme.array_length) + lazy val arrayCloneMethod = getMemberMethod(ScalaRunTimeModule, nme.array_clone) + lazy val ensureAccessibleMethod = getMemberMethod(ScalaRunTimeModule, nme.ensureAccessible) + lazy val arrayClassMethod = getMemberMethod(ScalaRunTimeModule, nme.arrayClass) + lazy val traversableDropMethod = getMemberMethod(ScalaRunTimeModule, nme.drop) + + lazy val GroupOfSpecializable = getMemberClass(SpecializableModule, tpnme.Group) + + lazy val WeakTypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.WeakTypeTag)) + lazy val WeakTypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.WeakTypeTag)) + lazy val TypeTagClass = TypeTagsClass.map(sym => getMemberClass(sym, tpnme.TypeTag)) + lazy val TypeTagModule = TypeTagsClass.map(sym => getMemberModule(sym, nme.TypeTag)) + lazy val MacroContextUniverse = DefinitionsClass.this.MacroContextUniverse + + lazy val materializeClassTag = getMemberMethod(ReflectPackage, nme.materializeClassTag) + lazy val materializeWeakTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeWeakTypeTag)) + lazy val materializeTypeTag = ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeTypeTag)) + + lazy val experimentalModule = getMemberModule(languageFeatureModule, nme.experimental) + lazy val MacrosFeature = getLanguageFeature("macros", experimentalModule) + lazy val DynamicsFeature = getLanguageFeature("dynamics") + lazy val PostfixOpsFeature = getLanguageFeature("postfixOps") + lazy val ReflectiveCallsFeature = getLanguageFeature("reflectiveCalls") + lazy val ImplicitConversionsFeature = getLanguageFeature("implicitConversions") + lazy val HigherKindsFeature = getLanguageFeature("higherKinds") + lazy val ExistentialsFeature = getLanguageFeature("existentials") + + lazy val ApiUniverseReify = ApiUniverseClass.map(sym => getMemberMethod(sym, nme.reify)) + + lazy val ReflectRuntimeUniverse = DefinitionsClass.this.ReflectRuntimeUniverse + lazy val ReflectRuntimeCurrentMirror = DefinitionsClass.this.ReflectRuntimeCurrentMirror + + lazy val TreesTreeType = TreesClass.map(sym => getTypeMember(sym, tpnme.Tree)) + object TreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain contains TreesTreeType } + object SubtreeType { def unapply(tpe: Type): Boolean = tpe.typeSymbol.overrideChain exists (_.tpe <:< TreesTreeType.tpe) } + + object ExprClassOf { def unapply(tp: Type): Option[Type] = elementExtractOption(ExprClass, tp) } lazy val PartialManifestClass = getTypeMember(ReflectPackage, tpnme.ClassManifest) lazy val ManifestSymbols = Set[Symbol](PartialManifestClass, FullManifestClass, OptManifestClass) diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 8386d02b7c..4998580a7d 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -358,6 +358,21 @@ abstract class SymbolTable extends macros.Universe def newMap[K, V]() = recordCache(mutable.HashMap[K, V]()) def newSet[K]() = recordCache(mutable.HashSet[K]()) def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]()) + def newGeneric[T](f: => T): () => T = { + val NoCached: T = null.asInstanceOf[T] + var cached: T = NoCached + var cachedRunId = NoRunId + caches += new Clearable { + def clear(): Unit = cached = NoCached + } + () => { + if (currentRunId != cachedRunId || cached == NoCached) { + cached = f + cachedRunId = currentRunId + } + cached + } + } } /** The set of all installed infotransformers. */ diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 8e822ca4f0..7cc5176507 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -60,6 +60,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val universe: thisUniverse.type = thisUniverse import definitions._ + private[reflect] lazy val runDefinitions = new definitions.RunDefinitions // only one "run" in the reflection universe + import runDefinitions._ override lazy val RootPackage = new RootPackage with SynchronizedTermSymbol override lazy val RootClass = new RootClass with SynchronizedModuleClassSymbol @@ -306,7 +308,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni lazy val bytecodefulObjectMethods = Set[Symbol](Object_clone, Object_equals, Object_finalize, Object_hashCode, Object_toString, Object_notify, Object_notifyAll) ++ ObjectClass.info.member(nme.wait_).asTerm.alternatives.map(_.asMethod) private def isBytecodelessMethod(meth: MethodSymbol): Boolean = { - if (isGetClass(meth) || isStringConcat(meth) || meth.owner.isPrimitiveValueClass || meth == Predef_classOf || meth.isMacro) return true + if (isGetClass(meth) || isStringConcat(meth) || meth.owner.isPrimitiveValueClass || meth == runDefinitions.Predef_classOf || meth.isMacro) return true bytecodelessMethodOwners(meth.owner) && !bytecodefulObjectMethods(meth) } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 1f1f07c09a..4d69a6673c 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -254,13 +254,9 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.UnqualifiedOwners definitions.PredefModule definitions.SpecializableModule - definitions.GroupOfSpecializable definitions.ScalaRunTimeModule definitions.SymbolModule - definitions.Symbol_apply definitions.StringAddClass - definitions.ArrowAssocClass - definitions.StringAdd_$plus definitions.ScalaNumberClass definitions.TraitSetterAnnotationClass definitions.DelayedInitClass @@ -276,7 +272,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.ByNameParamClass definitions.JavaRepeatedParamClass definitions.RepeatedParamClass - definitions.ExprClassOf definitions.ConsClass definitions.IteratorClass definitions.IterableClass @@ -285,7 +280,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.StringBuilderClass definitions.TraversableClass definitions.ListModule - definitions.List_apply definitions.NilModule definitions.SeqModule definitions.ArrayModule @@ -310,18 +304,10 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.OptManifestClass definitions.NoManifest definitions.TreesClass - definitions.TreesTreeType - definitions.TreeType - definitions.SubtreeType definitions.ExprsClass - definitions.ExprClass definitions.ClassTagModule definitions.ClassTagClass definitions.TypeTagsClass - definitions.WeakTypeTagClass - definitions.WeakTypeTagModule - definitions.TypeTagClass - definitions.TypeTagModule definitions.ApiUniverseClass definitions.JavaUniverseClass definitions.MirrorClass @@ -340,7 +326,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.ScalaLongSignatureAnnotation definitions.OptionClass definitions.OptionModule - definitions.Option_apply definitions.SomeClass definitions.NoneModule definitions.SomeModule @@ -384,8 +369,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.BoxedLongClass definitions.BoxedFloatClass definitions.BoxedDoubleClass - definitions.Boxes_isNumberOrBool - definitions.Boxes_isNumber definitions.BoxedUnitClass definitions.BoxedUnitModule definitions.AnnotationClass @@ -432,18 +415,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.MethodTargetClass definitions.LanguageFeatureAnnot definitions.languageFeatureModule - definitions.experimentalModule - definitions.MacrosFeature - definitions.DynamicsFeature - definitions.PostfixOpsFeature - definitions.ReflectiveCallsFeature - definitions.ImplicitConversionsFeature - definitions.HigherKindsFeature - definitions.ExistentialsFeature definitions.metaAnnotations definitions.AnnotationDefaultAttr - definitions.isUnbox - definitions.isBox definitions.isPhantomClass definitions.syntheticCoreClasses definitions.syntheticCoreMethods @@ -457,8 +430,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.boxedClass definitions.refClass definitions.volatileRefClass - definitions.boxMethod - definitions.unboxMethod definitions.UnitClass definitions.ByteClass definitions.ShortClass @@ -468,9 +439,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.FloatClass definitions.DoubleClass definitions.BooleanClass - definitions.Boolean_and - definitions.Boolean_or - definitions.Boolean_not definitions.UnitTpe definitions.ByteTpe definitions.ShortTpe diff --git a/test/files/presentation/t7678.check b/test/files/presentation/t7678.check new file mode 100644 index 0000000000..f06434b322 --- /dev/null +++ b/test/files/presentation/t7678.check @@ -0,0 +1 @@ +reload: TypeTag.scala diff --git a/test/files/presentation/t7678/Runner.scala b/test/files/presentation/t7678/Runner.scala new file mode 100644 index 0000000000..14d6dc2a70 --- /dev/null +++ b/test/files/presentation/t7678/Runner.scala @@ -0,0 +1,62 @@ +import scala.tools.nsc.interactive.tests._ +import scala.reflect.internal.util._ + +object Test extends InteractiveTest { + + import compiler._, definitions._ + + override def runDefaultTests() { + def resolveTypeTagHyperlink() { + val sym = compiler.askForResponse(() => compiler.currentRun.runDefinitions.TypeTagClass).get.left.get + val r = new Response[Position] + compiler.askLinkPos(sym, new BatchSourceFile("", source), r) + r.get + } + + def checkTypeTagSymbolConsistent() { + compiler.askForResponse { + () => { + val runDefinitions = currentRun.runDefinitions + import runDefinitions._ + assert(TypeTagsClass.map(sym => getMemberClass(sym, tpnme.TypeTag)) == TypeTagClass) + assert(TypeTagsClass.map(sym => getMemberClass(sym, tpnme.WeakTypeTag)) == WeakTypeTagClass) + assert(TypeTagsClass.map(sym => getMemberModule(sym, nme.WeakTypeTag)) == WeakTypeTagModule) + assert(getMemberMethod(ReflectPackage, nme.materializeClassTag) == materializeClassTag) + assert(ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeWeakTypeTag)) == materializeWeakTypeTag) + assert(ReflectApiPackage.map(sym => getMemberMethod(sym, nme.materializeTypeTag)) == materializeTypeTag) + () + } + }.get match { + case Right(t) => t.printStackTrace + case Left(_) => + } + } + resolveTypeTagHyperlink() + // The presentation compiler loads TypeTags from source; we'll get new symbols for its members. + // Need to make sure we didn't cache the old ones in Definitions. + checkTypeTagSymbolConsistent() + } + + def source = + """ + |package scala + |package reflect + |package api + | + |trait TypeTags { self: Universe => + | import definitions._ + | + | @annotation.implicitNotFound(msg = "No WeakTypeTag available for ${T}") + | trait WeakTypeTag[T] extends Equals with Serializable { + | val mirror: Mirror + | def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # WeakTypeTag[T] + | def tpe: Type + | } + | object WeakTypeTag + | + | trait TypeTag[T] extends WeakTypeTag[T] with Equals with Serializable { + | } + | object TypeTag + | + """.stripMargin +} diff --git a/test/files/presentation/t7678/src/TypeTag.scala b/test/files/presentation/t7678/src/TypeTag.scala new file mode 100644 index 0000000000..0b222f8851 --- /dev/null +++ b/test/files/presentation/t7678/src/TypeTag.scala @@ -0,0 +1,9 @@ +package test + +object Test { + import scala.reflect.runtime.{ universe => ru } + def getTypeTag(implicit tag: ru.TypeTag[Int] ) = () + locally { + getTypeTag/*?*/ + } +} |