diff options
Diffstat (limited to 'src')
107 files changed, 3523 insertions, 1847 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala index 87dac18849..f3dd29d8b2 100644 --- a/src/compiler/scala/reflect/macros/contexts/Context.scala +++ b/src/compiler/scala/reflect/macros/contexts/Context.scala @@ -15,7 +15,8 @@ abstract class Context extends scala.reflect.macros.blackbox.Context with Parsers with Evals with ExprUtils - with Traces { + with Traces + with Internals { val universe: Global diff --git a/src/compiler/scala/reflect/macros/contexts/Evals.scala b/src/compiler/scala/reflect/macros/contexts/Evals.scala index 180a998c39..a715af986c 100644 --- a/src/compiler/scala/reflect/macros/contexts/Evals.scala +++ b/src/compiler/scala/reflect/macros/contexts/Evals.scala @@ -9,7 +9,7 @@ trait Evals { private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.defaultMacroClassloader) private lazy val evalToolBox = evalMirror.mkToolBox() - private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }] + private lazy val evalImporter = ru.internal.createImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }] def eval[T](expr: Expr[T]): T = { expr.tree match { diff --git a/src/compiler/scala/reflect/macros/contexts/Internals.scala b/src/compiler/scala/reflect/macros/contexts/Internals.scala new file mode 100644 index 0000000000..8c784d7e54 --- /dev/null +++ b/src/compiler/scala/reflect/macros/contexts/Internals.scala @@ -0,0 +1,47 @@ +package scala.reflect.macros +package contexts + +trait Internals extends scala.tools.nsc.transform.TypingTransformers { + self: Context => + + import global._ + + lazy val internal: ContextInternalApi = new global.SymbolTableInternal with ContextInternalApi { + val enclosingOwner = callsiteTyper.context.owner + + class HofTransformer(hof: (Tree, TransformApi) => Tree) extends Transformer { + val api = new TransformApi { + def recur(tree: Tree): Tree = hof(tree, this) + def default(tree: Tree): Tree = superTransform(tree) + } + def superTransform(tree: Tree) = super.transform(tree) + override def transform(tree: Tree): Tree = hof(tree, api) + } + + def transform(tree: Tree)(transformer: (Tree, TransformApi) => Tree): Tree = new HofTransformer(transformer).transform(tree) + + class HofTypingTransformer(hof: (Tree, TypingTransformApi) => Tree) extends TypingTransformer(callsiteTyper.context.unit) { self => + currentOwner = callsiteTyper.context.owner + curTree = EmptyTree + localTyper = global.analyzer.newTyper(callsiteTyper.context.make(unit = callsiteTyper.context.unit)) + + val api = new TypingTransformApi { + def recur(tree: Tree): Tree = hof(tree, this) + def default(tree: Tree): Tree = superTransform(tree) + def atOwner[T](owner: Symbol)(op: => T): T = self.atOwner(owner)(op) + def atOwner[T](tree: Tree, owner: Symbol)(op: => T): T = self.atOwner(tree, owner)(op) + def currentOwner: Symbol = self.currentOwner + def typecheck(tree: Tree): Tree = localTyper.typed(tree) + } + def superTransform(tree: Tree) = super.transform(tree) + override def transform(tree: Tree): Tree = hof(tree, api) + } + + def typingTransform(tree: Tree)(transformer: (Tree, TypingTransformApi) => Tree): Tree = new HofTypingTransformer(transformer).transform(tree) + + def typingTransform(tree: Tree, owner: Symbol)(transformer: (Tree, TypingTransformApi) => Tree): Tree = { + val trans = new HofTypingTransformer(transformer) + trans.atOwner(owner)(trans.transform(tree)) + } + } +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala index f80b43b636..28c1e3ddb3 100644 --- a/src/compiler/scala/reflect/macros/contexts/Typers.scala +++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala @@ -1,8 +1,6 @@ package scala.reflect.macros package contexts -import scala.reflect.internal.Mode - trait Typers { self: Context => @@ -10,17 +8,24 @@ trait Typers { def openImplicits: List[ImplicitCandidate] = callsiteTyper.context.openImplicits.map(_.toImplicitCandidate) + type TypecheckMode = scala.reflect.internal.Mode + val TypecheckMode = scala.reflect.internal.Mode + val TERMmode = TypecheckMode.EXPRmode + val TYPEmode = TypecheckMode.TYPEmode | TypecheckMode.FUNmode + val PATTERNmode = TypecheckMode.PATTERNmode + /** * @see [[scala.tools.reflect.ToolBox.typeCheck]] */ - def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = { + def typecheck(tree: Tree, mode: TypecheckMode = TERMmode, 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 context = callsiteTyper.context val withImplicitFlag = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _) val withMacroFlag = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _) def withContext(tree: => Tree) = withImplicitFlag(withMacroFlag(tree)) - def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), pt), reportAmbiguousErrors = false) - universe.wrappingIntoTerm(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match { + def withWrapping(tree: Tree)(op: Tree => Tree) = if (mode == TERMmode) universe.wrappingIntoTerm(tree)(op) else op(tree) + def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), mode, pt), reportAmbiguousErrors = false) + withWrapping(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match { case universe.analyzer.SilentResultValue(result) => macroLogVerbose(result) result diff --git a/src/compiler/scala/reflect/reify/States.scala b/src/compiler/scala/reflect/reify/States.scala index 29bfa19845..65f3f424e8 100644 --- a/src/compiler/scala/reflect/reify/States.scala +++ b/src/compiler/scala/reflect/reify/States.scala @@ -35,7 +35,7 @@ trait States { if (!value && concrete) { current match { case tpe: Type => CannotReifyWeakType(s" having unresolved type parameter $tpe") - case sym: Symbol => CannotReifyWeakType(s" referring to local ${sym.kindString} ${sym.fullName}") + case sym: Symbol => CannotReifyWeakType(s" referring to ${sym.kindString} ${sym.fullName} local to the reifee") case _ => CannotReifyWeakType("") } } diff --git a/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala index bd60faf4cd..ce26232e5f 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala @@ -38,19 +38,10 @@ trait GenAnnotationInfos { } } - def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match { - case LiteralAnnotArg(const) => - mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const)) - case ArrayAnnotArg(args) => - mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*)) - case NestedAnnotArg(ann) => - mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann)) - case _ => - sys.error(s"Don't know what to do with $arg") - } - // if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important - val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2))) - mirrorFactoryCall(nme.Annotation, reify(ann.atp), mkList(reifiedArgs), mkListMap(reifiedAssocs)) + val Apply(Select(New(tpt), name), args) = annotationToTree(ann) + val reifiedAtp = mirrorCall(nme.Select, mirrorCall(nme.New, mirrorCall(nme.TypeTree, reifyType(tpt.tpe))), reify(name)) + val reifiedAnnRepr = mirrorCall(nme.Apply, reifiedAtp, reifyList(args)) + mirrorFactoryCall(nme.Annotation, reifiedAnnRepr) } } diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala index 2965db17c6..52ddcb154b 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala @@ -13,7 +13,7 @@ trait GenSymbols { * Keeps track of auxiliary symbols that are necessary for this reification session. * These include: * 1) Free vars (terms, types and existentials), - * 2) Non-locatable symbols (sometimes, e.g. for RefinedTypes, we need to reify these; to do that we create their local copies in the reificode) + * 2) Non-locatable symbols (sometimes, e.g. for RefinedTypes, we need to reify these; to do that we create their copies in the reificode) * 3) Non-locatable symbols that are referred by #1, #2 and #3 * * Exposes three main methods: @@ -90,7 +90,7 @@ trait GenSymbols { mirrorBuildCall(nme.selectTerm, rowner, rname) } } else { - // todo. make sure that free methods and free local defs work correctly + // todo. make sure that free methods work correctly if (sym.isExistential) reifySymDef(sym) else if (sym.isTerm) reifyFreeTerm(Ident(sym)) else reifyFreeType(Ident(sym)) // TODO: reify refinement classes diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala index b082796757..743fe131c4 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala @@ -39,7 +39,7 @@ trait GenTrees { // // why bother? because this brings method to the madness // the first prototype of reification reified all types and symbols for all trees => this quickly became unyieldy - // the second prototype reified external types, but avoided reifying local ones => this created an ugly irregularity + // the second prototype reified external types, but avoided reifying ones local to the reifee => this created an ugly irregularity // current approach is uniform and compact var rtree: Tree = tree match { case FreeDef(_, _, _, _, _) => reifyNestedFreeDef(tree) @@ -102,7 +102,7 @@ trait GenTrees { if (reifyDebug) println("inlining the splicee") // all free vars local to the enclosing reifee should've already been inlined by `Metalevels` for (sym <- inlinedSymtab.syms if sym.isLocalToReifee) - abort("local free var, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym)) + abort("free var local to the reifee, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym)) state.symtab ++= inlinedSymtab rtree case tree => @@ -129,11 +129,11 @@ trait GenTrees { else if (sym.isClass && !sym.isModuleClass) { if (reifyDebug) println("This for %s, reified as freeVar".format(sym)) if (reifyDebug) println("Free: " + sym) - mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym))) + mirrorBuildCall(nme.mkIdent, reifyFreeTerm(This(sym))) } else { if (reifyDebug) println("This for %s, reified as This".format(sym)) - mirrorBuildCall(nme.This, reify(sym)) + mirrorBuildCall(nme.mkThis, reify(sym)) } case Ident(name) => @@ -146,15 +146,15 @@ trait GenTrees { else if (!sym.isLocalToReifee) { if (sym.isVariable && sym.owner.isTerm) { captureVariable(sym) // Note order dependency: captureVariable needs to come before reification here. - mirrorCall(nme.Select, mirrorBuildCall(nme.Ident, reify(sym)), reify(nme.elem)) + mirrorCall(nme.Select, mirrorBuildCall(nme.mkIdent, reify(sym)), reify(nme.elem)) } - else mirrorBuildCall(nme.Ident, reify(sym)) + else mirrorBuildCall(nme.mkIdent, reify(sym)) } else mirrorCall(nme.Ident, reify(name)) case Select(qual, name) => if (qual.symbol != null && qual.symbol.isPackage) { - mirrorBuildCall(nme.Ident, reify(sym)) + mirrorBuildCall(nme.mkIdent, reify(sym)) } else { val effectiveName = if (sym != null && sym != NoSymbol) sym.name else name reifyProduct(Select(qual, effectiveName)) @@ -173,7 +173,7 @@ trait GenTrees { assert(tpe != null, "unexpected: bound type that doesn't have a tpe: " + showRaw(tree)) // if a symbol or a type of the scrutinee are local to reifee - // (e.g. point to a locally declared class or to a path-dependent thingie that depends on a local variable) + // (e.g. point to a locally declared class or to a path-dependent thingie that depends on a variable defined within the reifee) // then we can reify the scrutinee as a symless AST and that will definitely be hygienic // why? because then typechecking of a scrutinee doesn't depend on the environment external to the quasiquote // otherwise we need to reify the corresponding type @@ -187,7 +187,7 @@ trait GenTrees { if (spliced == EmptyTree) { if (reifyDebug) println("splicing failed: reify as is") - mirrorBuildCall(nme.TypeTree, reify(tpe)) + mirrorBuildCall(nme.mkTypeTree, reify(tpe)) } else spliced match { case TypeRefToFreeType(freeType) => @@ -195,7 +195,7 @@ trait GenTrees { Ident(freeType) case _ => if (reifyDebug) println("splicing succeeded: " + spliced) - mirrorBuildCall(nme.TypeTree, spliced) + mirrorBuildCall(nme.mkTypeTree, spliced) } } else tree match { @@ -207,10 +207,10 @@ trait GenTrees { mirrorCall(nme.SelectFromTypeTree, reify(qual), reify(name)) case _ if sym.isLocatable => if (reifyDebug) println(s"tpe is locatable: reify as Ident($sym)") - mirrorBuildCall(nme.Ident, reify(sym)) + mirrorBuildCall(nme.mkIdent, reify(sym)) case _ => if (reifyDebug) println(s"tpe is not locatable: reify as TypeTree($tpe)") - mirrorBuildCall(nme.TypeTree, reify(tpe)) + mirrorBuildCall(nme.mkTypeTree, reify(tpe)) } } } diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index a90a3a338b..a6b69e239f 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -45,21 +45,21 @@ trait GenTypes { case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic => val module = reify(clazz.sourceModule) val moduleClass = Select(Select(module, nme.asModule), nme.moduleClass) - mirrorFactoryCall(nme.ThisType, moduleClass) - case tpe @ ThisType(_) => - reifyProduct(tpe) + mirrorBuildCall(nme.ThisType, moduleClass) + case tpe @ ThisType(sym) => + reifyBuildCall(nme.ThisType, sym) case tpe @ SuperType(thistpe, supertpe) => - reifyProduct(tpe) + reifyBuildCall(nme.SuperType, thistpe, supertpe) case tpe @ SingleType(pre, sym) => - reifyProduct(tpe) + reifyBuildCall(nme.SingleType, pre, sym) case tpe @ ConstantType(value) => - mirrorFactoryCall(nme.ConstantType, reifyProduct(value)) + mirrorBuildCall(nme.ConstantType, reifyProduct(value)) case tpe @ TypeRef(pre, sym, args) => - reifyProduct(tpe) + reifyBuildCall(nme.TypeRef, pre, sym, args) case tpe @ TypeBounds(lo, hi) => - reifyProduct(tpe) + reifyBuildCall(nme.TypeBounds, lo, hi) case tpe @ NullaryMethodType(restpe) => - reifyProduct(tpe) + reifyBuildCall(nme.NullaryMethodType, restpe) case tpe @ AnnotatedType(anns, underlying) => reifyAnnotatedType(tpe) case _ => @@ -119,7 +119,8 @@ trait GenTypes { // todo. write a test for this if (ReflectRuntimeUniverse == NoSymbol) CannotConvertManifestToTagWithoutScalaReflect(tpe, manifestInScope) val cm = typer.typed(Ident(ReflectRuntimeCurrentMirror)) - val tagTree = gen.mkMethodCall(ReflectRuntimeUniverse, nme.manifestToTypeTag, List(tpe), List(cm, manifestInScope)) + val internal = gen.mkAttributedSelect(gen.mkAttributedRef(ReflectRuntimeUniverse), UniverseInternal) + val tagTree = gen.mkMethodCall(Select(internal, nme.manifestToTypeTag), List(tpe), List(cm, manifestInScope)) Select(Apply(Select(tagTree, nme.in), List(Ident(nme.MIRROR_SHORT))), nme.tpe) case _ => EmptyTree @@ -157,13 +158,13 @@ trait GenTypes { */ private def reifySemiConcreteTypeMember(tpe: Type): Tree = tpe match { case tpe @ TypeRef(pre @ SingleType(prepre, presym), sym, args) if sym.isAbstractType && !sym.isExistential => - mirrorFactoryCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args)) + mirrorBuildCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args)) } /** Reify an annotated type, i.e. the one that makes us deal with AnnotationInfos */ private def reifyAnnotatedType(tpe: AnnotatedType): Tree = { val AnnotatedType(anns, underlying) = tpe - mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying)) + mirrorBuildCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying)) } /** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */ @@ -172,25 +173,25 @@ trait GenTypes { def reifyScope(scope: Scope): Tree = { scope foreach reifySymDef - mirrorCall(nme.newScopeWith, scope.toList map reify: _*) + mirrorBuildCall(nme.newScopeWith, scope.toList map reify: _*) } tpe match { case tpe @ RefinedType(parents, decls) => reifySymDef(tpe.typeSymbol) - mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) + mirrorBuildCall(nme.RefinedType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) case tpe @ ExistentialType(tparams, underlying) => tparams foreach reifySymDef - mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) + reifyBuildCall(nme.ExistentialType, tparams, underlying) case tpe @ ClassInfoType(parents, decls, clazz) => reifySymDef(clazz) - mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) + mirrorBuildCall(nme.ClassInfoType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol)) case tpe @ MethodType(params, restpe) => params foreach reifySymDef - mirrorFactoryCall(tpe, reify(params), reify(restpe)) + reifyBuildCall(nme.MethodType, params, restpe) case tpe @ PolyType(tparams, underlying) => tparams foreach reifySymDef - mirrorFactoryCall(tpe, reify(tparams), reify(underlying)) + reifyBuildCall(nme.PolyType, tparams, underlying) case _ => throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind)) } diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala index de9fec0df5..4512b2cb6f 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala @@ -5,6 +5,10 @@ trait GenUtils { self: Reifier => import global._ + import treeInfo._ + import definitions._ + private val runDefinitions = currentRun.runDefinitions + import runDefinitions._ def reifyList(xs: List[Any]): Tree = mkList(xs map reify) diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala index abd179b24b..a0035d73d6 100644 --- a/src/compiler/scala/reflect/reify/phases/Calculate.scala +++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala @@ -26,7 +26,7 @@ trait Calculate { } /** - * Merely traverses the reifiee and records local symbols along with their metalevels. + * Merely traverses the reifiee and records symbols local to the reifee along with their metalevels. */ val calculate = new Traverser { // see the explanation of metalevels in `Metalevels` diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 6c073c0b4c..9a54632796 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -78,7 +78,7 @@ trait Reshape { super.transform(preTyper) } - private def undoMacroExpansion(tree: Tree): Tree = + private def undoMacroExpansion(tree: Tree): Tree = { tree.attachments.get[analyzer.MacroExpansionAttachment] match { case Some(analyzer.MacroExpansionAttachment(original, _)) => def mkImplicitly(tp: Type) = atPos(tree.pos)( @@ -96,8 +96,30 @@ trait Reshape { case Apply(TypeApply(_, List(tt)), List(pre)) if sym == materializeTypeTag => mkImplicitly(typeRef(pre.tpe, TypeTagClass, List(tt.tpe))) case _ => original } - case _ => tree + case None => + // `typeOf[T]` calls get translated into `typeOf[T](Predef.implicitly)` by Reshape + // unfortunately, this doesn't work well with the recently introduced `def typeOf[T: TypeTag](x: T)` overload + // somehow the typechecker is now longer able to make sense of targless implicitly failing with: + // ambiguous implicit values: + // both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] + // and method conforms in object Predef of type [A]=> <:<[A,A] + // match expected type T + // could not find implicit value for parameter e: T + // overloaded method value typeOf with alternatives: + // (x: => List[Int])(implicit evidence$2: ru.TypeTag[List[Int]])ru.Type <and> + // (implicit ttag: ru.TypeTag[List[Int]])ru.Type + // cannot be applied to (Unit) + // therefore here we give the calls to `weakTypeOf` and `typeOf` a bit of extra helping + // erasing synthetic implicit arguments altogether, so that this weird tree shape doesn't appear in the reifee in the first place + def isTypeOf(sym: Symbol): Boolean = { + sym != null && (sym.name == nme.typeOf || sym.name == nme.weakTypeOf) && sym.owner == TypeTagsClass + } + tree match { + case Apply(fun, args) if !tree.tpe.isInstanceOf[MethodType] && isTypeOf(fun.symbol) => fun + case _ => tree + } } + } override def transformModifiers(mods: Modifiers) = { val mods1 = toPreTyperModifiers(mods, currentSymbol) diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala index d052127956..4ec4de28c4 100644 --- a/src/compiler/scala/reflect/reify/utils/Extractors.scala +++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala @@ -183,12 +183,12 @@ trait Extractors { tree match { case ValDef(_, name, _, Apply( - Select(Select(uref1 @ Ident(_), build1), freeTermFactory), + Select(Select(Select(uref1 @ Ident(_), internal1), rs1), freeTermFactory), _ :+ - ApplyCall(Select(Select(uref2 @ Ident(_), build2), flagsRepr), List(Literal(Constant(flags: Long)))) :+ + ApplyCall(Select(Select(Select(uref2 @ Ident(_), internal2), rs2), flagsRepr), List(Literal(Constant(flags: Long)))) :+ Literal(Constant(origin: String)))) - if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && acceptFreeTermFactory(freeTermFactory) && - uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsRepr == nme.FlagsRepr => + if uref1.name == nme.UNIVERSE_SHORT && internal1 == nme.internal && rs1 == nme.reificationSupport && acceptFreeTermFactory(freeTermFactory) && + uref2.name == nme.UNIVERSE_SHORT && internal2 == nme.internal && rs2 == nme.reificationSupport && flagsRepr == nme.FlagsRepr => Some((uref1, name, reifyBinding(tree), flags, origin)) case _ => None @@ -201,8 +201,8 @@ trait Extractors { object FreeRef { def unapply(tree: Tree): Option[(Tree, TermName)] = tree match { - case Apply(Select(Select(uref @ Ident(_), build), ident), List(Ident(name: TermName))) - if build == nme.build && ident == nme.Ident && name.startsWith(nme.REIFY_FREE_PREFIX) => + case Apply(Select(Select(Select(uref @ Ident(_), internal), rs), mkIdent), List(Ident(name: TermName))) + if internal == nme.internal && rs == nme.reificationSupport && mkIdent == nme.mkIdent && name.startsWith(nme.REIFY_FREE_PREFIX) => Some((uref, name)) case _ => None @@ -213,15 +213,15 @@ trait Extractors { def unapply(tree: Tree): Option[(Tree, TermName, Long, Boolean)] = tree match { case ValDef(_, name, _, Apply( - Select(Select(uref1 @ Ident(_), build1), newNestedSymbol), + Select(Select(Select(uref1 @ Ident(_), internal1), rs1), newNestedSymbol), List( _, _, _, - ApplyCall(Select(Select(uref2 @ Ident(_), build2), flagsRepr), List(Literal(Constant(flags: Long)))), + ApplyCall(Select(Select(Select(uref2 @ Ident(_), internal2), rs2), flagsRepr), List(Literal(Constant(flags: Long)))), Literal(Constant(isClass: Boolean))))) - if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && newNestedSymbol == nme.newNestedSymbol && - uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsRepr == nme.FlagsRepr => + if uref1.name == nme.UNIVERSE_SHORT && internal1 == nme.internal && rs1 == nme.reificationSupport && newNestedSymbol == nme.newNestedSymbol && + uref2.name == nme.UNIVERSE_SHORT && internal2 == nme.internal && rs2 == nme.reificationSupport && flagsRepr == nme.FlagsRepr => Some((uref1, name, flags, isClass)) case _ => None diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala index e37b861461..3b91d28360 100644 --- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala +++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala @@ -32,7 +32,7 @@ trait NodePrinters { s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List") s = "List\\[.*?\\]".r.replaceAllIn(s, "List") s = s.replace("immutable.this.Nil", "List()") - s = """build\.FlagsRepr\((\d+)[lL]\)""".r.replaceAllIn(s, m => { + s = """internal\.reificationSupport\.FlagsRepr\((\d+)[lL]\)""".r.replaceAllIn(s, m => { flagsAreUsed = true show(m.group(1).toLong) }) @@ -76,7 +76,6 @@ trait NodePrinters { if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim val imports = scala.collection.mutable.ListBuffer[String]() imports += nme.UNIVERSE_SHORT.toString - // if (buildIsUsed) imports += nme.build if (mirrorIsUsed) imports += nme.MIRROR_SHORT.toString if (flagsAreUsed) imports += nme.Flag.toString printout += s"""import ${imports map (_ + "._") mkString ", "}""" diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala index 5f8de9894f..b6ae3b8952 100644 --- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala +++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala @@ -162,7 +162,7 @@ trait SymbolTables { else if (isFreeTerm) sym.tpe else sym.info } else NoType - val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(signature)) + val rset = reifier.mirrorBuildCall(nme.setInfo, currtab.symRef(sym), reifier.reify(signature)) // `Symbol.annotations` doesn't initialize the symbol, so we don't need to do anything special here // also since we call `sym.info` a few lines above, by now the symbol will be initialized (if possible) // so the annotations will be filled in and will be waiting to be reified (unless symbol initialization is prohibited as described above) diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 81e96b76ac..03b76ed99e 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -15,6 +15,7 @@ import scala.collection.{ mutable, immutable } import io.{ SourceReader, AbstractFile, Path } import reporters.{ Reporter, ConsoleReporter } import util.{ ClassPath, MergedClassPath, StatisticsInfo, returning, stackTraceString } +import scala.reflect.ClassTag import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile } import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat } import scala.reflect.io.VirtualFile @@ -33,6 +34,7 @@ import backend.jvm.GenASM import backend.opt.{ Inliners, InlineExceptionHandlers, ConstantOptimization, ClosureElimination, DeadCodeElimination } import backend.icode.analysis._ import scala.language.postfixOps +import scala.tools.nsc.ast.{TreeGen => AstTreeGen} class Global(var currentSettings: Settings, var reporter: Reporter) extends SymbolTable @@ -49,11 +51,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter) override def isCompilerUniverse = true override val useOffsetPositions = !currentSettings.Yrangepos + type RuntimeClass = java.lang.Class[_] + implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass]) + class GlobalMirror extends Roots(NoSymbol) { val universe: self.type = self def rootLoader: LazyType = new loaders.PackageLoader(classPath) override def toString = "compiler mirror" } + implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[GlobalMirror]) lazy val rootMirror: Mirror = { val rm = new GlobalMirror @@ -100,13 +106,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter) // sub-components -------------------------------------------------- - /** Generate ASTs */ - type TreeGen = scala.tools.nsc.ast.TreeGen - /** Tree generation, usually based on existing symbols. */ override object gen extends { val global: Global.this.type = Global.this - } with TreeGen { + } with AstTreeGen { def mkAttributedCast(tree: Tree, pt: Type): Tree = typer.typed(mkCast(tree, pt)) } @@ -1348,7 +1351,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) val toReload = mutable.Set[String]() for (sym <- root.info.decls) { if (sym.isInitialized && clearOnNextRun(sym)) - if (sym.isPackage) { + if (sym.hasPackageFlag) { resetProjectClasses(sym.moduleClass) openPackageModule(sym.moduleClass) } else { diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index a87a04472a..0575b9703e 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -142,7 +142,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { * x.asInstanceOf[`pt`]() if after uncurry but before erasure * x.$asInstanceOf[`pt`]() if at or after erasure */ - def mkCast(tree: Tree, pt: Type): Tree = { + override def mkCast(tree: Tree, pt: Type): Tree = { debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase) assert(!tree.tpe.isInstanceOf[MethodType], tree) assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize)) diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 7a7d4ac0b2..d33ea5bb5c 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -6,6 +6,7 @@ package scala.tools.nsc package ast +import scala.reflect.ClassTag import scala.reflect.internal.Flags.BYNAMEPARAM import scala.reflect.internal.Flags.DEFAULTPARAM import scala.reflect.internal.Flags.IMPLICIT @@ -102,6 +103,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global => def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck } + implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier]) def newStrictTreeCopier: TreeCopier = new StrictTreeCopier def newLazyTreeCopier: TreeCopier = new LazyTreeCopier diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 8271363527..3542fe5945 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2231,7 +2231,7 @@ self => } else { // XX-METHOD-INFER accept(COLON) if (in.token == ARROW) { - if (owner.isTypeName && !mods.hasLocalFlag) + if (owner.isTypeName && !mods.isLocalToThis) syntaxError( in.offset, (if (mods.isMutable) "`var'" else "`val'") + diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index b650cdfa09..81fbbfcabf 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -869,7 +869,7 @@ abstract class GenICode extends SubComponent { case Ident(name) => def genLoadIdent = { val sym = tree.symbol - if (!sym.isPackage) { + if (!sym.hasPackageFlag) { if (sym.isModule) { genLoadModule(ctx, tree) generatedType = toTypeKind(sym.info) diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index c8845344e9..53142fbd87 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -350,7 +350,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { case Ident(name) => val sym = tree.symbol - if (!sym.isPackage) { + if (!sym.hasPackageFlag) { val tk = symInfoTK(sym) if (sym.isModule) { genLoadModule(tree) } else { locals.load(sym) } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 2f9cc01c0b..ea600bc586 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -561,14 +561,14 @@ abstract class ClassfileParser { // if this is a non-static inner class, remove the explicit outer parameter val paramsNoOuter = innerClasses getEntry currentClass match { case Some(entry) if !isScalaRaw && !entry.jflags.isStatic => - /* About `clazz.owner.isPackage` below: SI-5957 + /* About `clazz.owner.hasPackageFlag` below: SI-5957 * For every nested java class A$B, there are two symbols in the scala compiler. * 1. created by SymbolLoader, because of the existence of the A$B.class file, owner: package * 2. created by ClassfileParser of A when reading the inner classes, owner: A * If symbol 1 gets completed (e.g. because the compiled source mentions `A$B`, not `A#B`), the * ClassfileParser for 1 executes, and clazz.owner is the package. */ - assert(params.head.tpe.typeSymbol == clazz.owner || clazz.owner.isPackage, params.head.tpe.typeSymbol + ": " + clazz.owner) + assert(params.head.tpe.typeSymbol == clazz.owner || clazz.owner.hasPackageFlag, params.head.tpe.typeSymbol + ": " + clazz.owner) params.tail case _ => params diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 55f45257dc..592c5497b5 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -99,7 +99,7 @@ abstract class Pickler extends SubComponent { * added to fix that bug, but there may be a better way. */ private def localizedOwner(sym: Symbol) = - if (isLocal(sym) && !isRootSym(sym) && !isLocal(sym.owner)) + if (isLocalToPickle(sym) && !isRootSym(sym) && !isLocalToPickle(sym.owner)) // don't use a class as the localized owner for type parameters that are not owned by a class: those are not instantiated by asSeenFrom // however, they would suddenly be considered by asSeenFrom if their localized owner became a class (causing the crashes of #4079, #2741) (if ((sym.isTypeParameter || sym.isValueParameter) && !sym.owner.isClass) nonClassRoot @@ -110,14 +110,14 @@ abstract class Pickler extends SubComponent { * anyway? This is the case if symbol is a refinement class, * an existentially bound variable, or a higher-order type parameter. */ - private def isLocal(sym: Symbol): Boolean = (sym != NoSymbol) && !sym.isPackageClass && ( + private def isLocalToPickle(sym: Symbol): Boolean = (sym != NoSymbol) && !sym.isPackageClass && ( isRootSym(sym) || sym.isRefinementClass || sym.isAbstractType && sym.hasFlag(EXISTENTIAL) // existential param || sym.isParameter - || isLocal(sym.owner) + || isLocalToPickle(sym.owner) ) - private def isExternalSymbol(sym: Symbol): Boolean = (sym != NoSymbol) && !isLocal(sym) + private def isExternalSymbol(sym: Symbol): Boolean = (sym != NoSymbol) && !isLocalToPickle(sym) // Phase 1 methods: Populate entries/index ------------------------------------ @@ -174,7 +174,7 @@ abstract class Pickler extends SubComponent { val sym = deskolemize(sym0) if (putEntry(sym)) { - if (isLocal(sym)) { + if (isLocalToPickle(sym)) { putEntry(sym.name) putSymbol(sym.owner) putSymbol(sym.privateWithin) @@ -428,7 +428,7 @@ abstract class Pickler extends SubComponent { } def writeSymbolBody(sym: Symbol) { if (sym ne NoSymbol) { - if (isLocal(sym)) + if (isLocalToPickle(sym)) writeLocalSymbolBody(sym) else writeExtSymbolBody(sym) diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index d81a5d5755..1468680fe0 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -130,7 +130,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre if (!thisProxy.exists) { target setFlag STATIC } - val params = ((optionSymbol(thisProxy) map {proxy:Symbol => ValDef(proxy)}) ++ (target.paramss.flatten map ValDef)).toList + val params = ((optionSymbol(thisProxy) map {proxy:Symbol => ValDef(proxy)}) ++ (target.paramss.flatten map ValDef.apply)).toList val methSym = oldClass.newMethod(unit.freshTermName(nme.accessor.toString()), target.pos, FINAL | BRIDGE | SYNTHETIC | PROTECTED | STATIC) @@ -393,7 +393,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre declared += tree.symbol case Ident(_) => val sym = tree.symbol - if ((sym != NoSymbol) && sym.isLocal && sym.isTerm && !sym.isMethod && !declared.contains(sym)) freeVars += sym + if ((sym != NoSymbol) && sym.isLocalToBlock && sym.isTerm && !sym.isMethod && !declared.contains(sym)) freeVars += sym case _ => } super.traverse(tree) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 60c1553ef3..eba2e1399d 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -597,7 +597,7 @@ abstract class Erasure extends AddInterfaces if (tree.symbol == NoSymbol) { tree } else if (name == nme.CONSTRUCTOR) { - if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.primaryConstructor + if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.info.decl(nme.CONSTRUCTOR) tree } else if (tree.symbol == Any_asInstanceOf) adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf))) @@ -737,7 +737,7 @@ abstract class Erasure extends AddInterfaces /** TODO - adapt SymbolPairs so it can be used here. */ private def checkNoDeclaredDoubleDefs(base: Symbol) { val decls = base.info.decls - + // SI-8010 force infos, otherwise makeNotPrivate in ExplicitOuter info transformer can trigger // a scope rehash while were iterating and we can see the same entry twice! // Inspection of SymbolPairs (the basis of OverridingPairs), suggests that it is immune @@ -748,13 +748,13 @@ abstract class Erasure extends AddInterfaces // we do these checks, so that we're comparing same-named methods based on the expanded names that actually // end up in the bytecode. exitingPostErasure(decls.foreach(_.info)) - + var e = decls.elems while (e ne null) { if (e.sym.isTerm) { var e1 = decls lookupNextEntry e while (e1 ne null) { - assert(e.sym ne e1.sym, s"Internal error: encountered ${e.sym.debugLocationString} twice during scope traversal. This might be related to SI-8010.") + assert(e.sym ne e1.sym, s"Internal error: encountered ${e.sym.debugLocationString} twice during scope traversal. This might be related to SI-8010.") if (sameTypeAfterErasure(e.sym, e1.sym)) doubleDefError(new SymbolPair(base, e.sym, e1.sym)) diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index b2e071579e..0447e23e9e 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -206,7 +206,7 @@ abstract class ExplicitOuter extends InfoTransform // On the other hand, mixing in the trait into a separately compiled // class needs to have a common naming scheme, independently of whether // the field was accessed from an inner class or not. See #2946 - if (sym.owner.isTrait && sym.hasLocalFlag && + if (sym.owner.isTrait && sym.isLocalToThis && (sym.getter(sym.owner.toInterface) == NoSymbol)) sym.makeNotPrivate(sym.owner) tp diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index acef2a50d8..e38c034f4d 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -122,7 +122,7 @@ abstract class LambdaLift extends InfoTransform { * and the owner of `sym`. * Return `true` if there is no class between `enclosure` and * the owner of sym. - * pre: sym.isLocal, (enclosure.isMethod || enclosure.isClass) + * pre: sym.isLocalToBlock, (enclosure.isMethod || enclosure.isClass) * * The idea of `markFree` is illustrated with an example: * @@ -180,7 +180,7 @@ abstract class LambdaLift extends InfoTransform { tree match { case ClassDef(_, _, _, _) => liftedDefs(tree.symbol) = Nil - if (sym.isLocal) { + if (sym.isLocalToBlock) { // Don't rename implementation classes independently of their interfaces. If // the interface is to be renamed, then we will rename the implementation // class at that time. You'd think we could call ".implClass" on the trait @@ -201,7 +201,7 @@ abstract class LambdaLift extends InfoTransform { } } case DefDef(_, _, _, _, _, _) => - if (sym.isLocal) { + if (sym.isLocalToBlock) { renamable += sym sym setFlag (PrivateLocal | FINAL) } else if (sym.isPrimaryConstructor) { @@ -210,14 +210,14 @@ abstract class LambdaLift extends InfoTransform { case Ident(name) => if (sym == NoSymbol) { assert(name == nme.WILDCARD) - } else if (sym.isLocal) { + } else if (sym.isLocalToBlock) { val owner = currentOwner.logicallyEnclosingMember if (sym.isTerm && !sym.isMethod) markFree(sym, owner) else if (sym.isMethod) markCalled(sym, owner) //symSet(called, owner) += sym } case Select(_, _) => - if (sym.isConstructor && sym.owner.isLocal) + if (sym.isConstructor && sym.owner.isLocalToBlock) markCalled(sym, currentOwner.logicallyEnclosingMember) case _ => } @@ -362,7 +362,7 @@ abstract class LambdaLift extends InfoTransform { private def proxyRef(sym: Symbol) = { val psym = proxy(sym) - if (psym.isLocal) gen.mkAttributedIdent(psym) else memberRef(psym) + if (psym.isLocalToBlock) gen.mkAttributedIdent(psym) else memberRef(psym) } private def addFreeArgs(pos: Position, sym: Symbol, args: List[Tree]) = { @@ -459,10 +459,10 @@ abstract class LambdaLift extends InfoTransform { tree match { case ClassDef(_, _, _, _) => val tree1 = addFreeParams(tree, sym) - if (sym.isLocal) liftDef(tree1) else tree1 + if (sym.isLocalToBlock) liftDef(tree1) else tree1 case DefDef(_, _, _, _, _, _) => val tree1 = addFreeParams(tree, sym) - if (sym.isLocal) liftDef(tree1) else tree1 + if (sym.isLocalToBlock) liftDef(tree1) else tree1 case ValDef(mods, name, tpt, rhs) => if (sym.isCapturedVariable) { val tpt1 = TypeTree(sym.tpe) setPos tpt.pos @@ -499,7 +499,7 @@ abstract class LambdaLift extends InfoTransform { if (sym.isTerm && !sym.isLabel) if (sym.isMethod) atPos(tree.pos)(memberRef(sym)) - else if (sym.isLocal && !isSameOwnerEnclosure(sym)) + else if (sym.isLocalToBlock && !isSameOwnerEnclosure(sym)) atPos(tree.pos)(proxyRef(sym)) else tree else tree diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index c59b726076..02e55241b3 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -716,7 +716,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { enterMember(specVal) // create accessors - // debuglog("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name)) if (nme.isLocalName(m.name)) { val specGetter = mkAccessor(specVal, specVal.getterName) setInfo MethodType(Nil, specVal.info) @@ -1653,7 +1652,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case SpecialOverload(original, env) => debuglog("completing specialized " + symbol.fullName + " calling " + original) debuglog("special overload " + original + " -> " + env) - val t = DefDef(symbol, { vparamss => + val t = DefDef(symbol, { vparamss: List[List[Symbol]] => val fun = Apply(Select(This(symbol.owner), original), makeArguments(original, vparamss.head)) @@ -1751,7 +1750,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { // flag. nobody has to see this anyway :) sym.setFlag(SPECIALIZED) // create empty bodies for specializations - localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, { vparamss => EmptyTree })), ddef)) + localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, { vparamss: List[List[Symbol]] => EmptyTree })), ddef)) } else tree case _ => @@ -1816,7 +1815,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { val newBody = symSubstituter(body(source).duplicate) tpt modifyType (_.substSym(oldtparams, newtparams)) - copyDefDef(tree)(vparamss = List(newSyms map ValDef), rhs = newBody) + copyDefDef(tree)(vparamss = List(newSyms map ValDef.apply), rhs = newBody) } /** Create trees for specialized members of 'sClass', based on the @@ -1853,9 +1852,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } // ctor - mbrs += DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef), EmptyTree) + mbrs += DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef.apply), EmptyTree) } else { - mbrs += DefDef(m, { paramss => EmptyTree }) + mbrs += DefDef(m, { paramss: List[List[Symbol]] => EmptyTree }) } } else if (m.isValue) { mbrs += ValDef(m).setType(NoType) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index e7ea686bc8..8a7d30235f 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -412,7 +412,7 @@ abstract class UnCurry extends InfoTransform val sym = tree.symbol // true if the taget is a lambda body that's been lifted into a method - def isLiftedLambdaBody(target: Tree) = target.symbol.isLocal && target.symbol.isArtifact && target.symbol.name.containsName(nme.ANON_FUN_NAME) + def isLiftedLambdaBody(target: Tree) = target.symbol.isLocalToBlock && target.symbol.isArtifact && target.symbol.name.containsName(nme.ANON_FUN_NAME) val result = ( // TODO - settings.noassertions.value temporarily retained to avoid diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index c065fb54b7..6e9e16ffc9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -516,7 +516,7 @@ trait Contexts { self: Analyzer => argContext.scope enter e.sym } } - if (c.isLocal && !c.owner.isLocalDummy) { + if (c.owner.isTerm && !c.owner.isLocalDummy) { enterElems(c.outer) enterLocalElems(c.scope.elems) } @@ -589,9 +589,6 @@ trait Contexts { self: Analyzer => else if (bufferErrors) reportBuffer += (pos -> msg) } - /** Is the owning symbol of this context a term? */ - final def isLocal: Boolean = owner.isTerm - // nextOuter determines which context is searched next for implicits // (after `this`, which contributes `newImplicits` below.) In // most cases, it is simply the outer context: if we're owned by @@ -714,7 +711,7 @@ trait Contexts { self: Analyzer => ( (ab.isTerm || ab == rootMirror.RootClass) || (accessWithin(ab) || accessWithinLinked(ab)) && - ( !sym.hasLocalFlag + ( !sym.isLocalToThis || sym.owner.isImplClass // allow private local accesses to impl classes || sym.isProtected && isSubThisType(pre, sym.owner) || pre =:= sym.owner.thisType @@ -980,7 +977,7 @@ trait Contexts { self: Analyzer => // 2) sym.owner is inherited by the correct package object class // We try to establish 1) by inspecting the owners directly, and then we try // to rule out 2), and only if both those fail do we resort to looking in the info. - !sym.isPackage && sym.owner.exists && ( + !sym.hasPackageFlag && sym.owner.exists && ( if (sym.owner.isPackageObjectClass) sym.owner.owner == pkgClass else diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 8f5778862d..2bb874a8aa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -402,8 +402,8 @@ trait Implicits { } def complexity(tp: Type): Int = tp.dealias match { case NoPrefix => 0 - case SingleType(pre, sym) => if (sym.isPackage) 0 else complexity(tp.dealiasWiden) - case ThisType(sym) => if (sym.isPackage) 0 else 1 + case SingleType(pre, sym) => if (sym.hasPackageFlag) 0 else complexity(tp.dealiasWiden) + case ThisType(sym) => if (sym.hasPackageFlag) 0 else 1 case TypeRef(pre, sym, args) => complexity(pre) + (args map complexity).sum + 1 case RefinedType(parents, _) => (parents map complexity).sum + 1 case _ => 1 @@ -425,11 +425,11 @@ trait Implicits { * expected type. * Detect infinite search trees for implicits. * - * @param info The given implicit info describing the implicit definition - * @param isLocal Is the implicit in the local scope of the call site? - * @pre `info.tpe` does not contain an error + * @param info The given implicit info describing the implicit definition + * @param isLocalToCallsite Is the implicit in the local scope of the call site? + * @pre `info.tpe` does not contain an error */ - private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean, isLocal: Boolean): SearchResult = { + private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean, isLocalToCallsite: Boolean): SearchResult = { // SI-7167 let implicit macros decide what amounts for a divergent implicit search // imagine a macro writer which wants to synthesize a complex implicit Complex[T] by making recursive calls to Complex[U] for its parts // e.g. we have `class Foo(val bar: Bar)` and `class Bar(val x: Int)` @@ -450,7 +450,7 @@ trait Implicits { try { context.openImplicits = OpenImplicit(info, pt, tree) :: context.openImplicits // println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG - val result = typedImplicit0(info, ptChecked, isLocal) + val result = typedImplicit0(info, ptChecked, isLocalToCallsite) if (result.isDivergent) { //println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG if (context.openImplicits.tail.isEmpty && !pt.isErroneous) @@ -574,24 +574,24 @@ trait Implicits { case _ => false } - private def typedImplicit0(info: ImplicitInfo, ptChecked: Boolean, isLocal: Boolean): SearchResult = { + private def typedImplicit0(info: ImplicitInfo, ptChecked: Boolean, isLocalToCallsite: Boolean): SearchResult = { if (Statistics.canEnable) Statistics.incCounter(plausiblyCompatibleImplicits) val ok = ptChecked || matchesPt(info) && { - def word = if (isLocal) "local " else "" + def word = if (isLocalToCallsite) "local " else "" typingLog("match", s"$word$info") true } - if (ok) typedImplicit1(info, isLocal) else SearchFailure + if (ok) typedImplicit1(info, isLocalToCallsite) else SearchFailure } - private def typedImplicit1(info: ImplicitInfo, isLocal: Boolean): SearchResult = { + private def typedImplicit1(info: ImplicitInfo, isLocalToCallsite: Boolean): SearchResult = { if (Statistics.canEnable) Statistics.incCounter(matchingImplicits) // workaround for deficient context provided by ModelFactoryImplicitSupport#makeImplicitConstraints val isScalaDoc = context.tree == EmptyTree val itree0 = atPos(pos.focus) { - if (isLocal && !isScalaDoc) { + if (isLocalToCallsite && !isScalaDoc) { // SI-4270 SI-5376 Always use an unattributed Ident for implicits in the local scope, // rather than an attributed Select, to detect shadowing. Ident(info.name) @@ -661,7 +661,7 @@ trait Implicits { fail("hasMatchingSymbol reported error: " + context.firstError.get.errMsg) else if (itree3.isErroneous) fail("error typechecking implicit candidate") - else if (isLocal && !hasMatchingSymbol(itree2)) + else if (isLocalToCallsite && !hasMatchingSymbol(itree2)) fail("candidate implicit %s is shadowed by %s".format( info.sym.fullLocationString, itree2.symbol.fullLocationString)) else { @@ -776,12 +776,12 @@ trait Implicits { /** Prune ImplicitInfos down to either all the eligible ones or the best one. * - * @param iss list of list of infos - * @param isLocal if true, `iss` represents in-scope implicits, which must respect the normal rules of - * shadowing. The head of the list `iss` must represent implicits from the closest - * enclosing scope, and so on. + * @param iss list of list of infos + * @param isLocalToCallsite if true, `iss` represents in-scope implicits, which must respect the normal rules of + * shadowing. The head of the list `iss` must represent implicits from the closest + * enclosing scope, and so on. */ - class ImplicitComputation(iss: Infoss, isLocal: Boolean) { + class ImplicitComputation(iss: Infoss, isLocalToCallsite: Boolean) { abstract class Shadower { def addInfos(infos: Infos) def isShadowed(name: Name): Boolean @@ -800,7 +800,7 @@ trait Implicits { def addInfos(infos: Infos) {} def isShadowed(name: Name) = false } - if (isLocal) new LocalShadower else NoShadower + if (isLocalToCallsite) new LocalShadower else NoShadower } private var best: SearchResult = SearchFailure @@ -870,7 +870,7 @@ trait Implicits { @tailrec private def rankImplicits(pending: Infos, acc: Infos): Infos = pending match { case Nil => acc case i :: is => - DivergentImplicitRecovery(typedImplicit(i, ptChecked = true, isLocal), i) match { + DivergentImplicitRecovery(typedImplicit(i, ptChecked = true, isLocalToCallsite), i) match { case sr if sr.isDivergent => Nil case sr if sr.isFailure => @@ -898,7 +898,7 @@ trait Implicits { /** Returns all eligible ImplicitInfos and their SearchResults in a map. */ - def findAll() = mapFrom(eligible)(typedImplicit(_, ptChecked = false, isLocal)) + def findAll() = mapFrom(eligible)(typedImplicit(_, ptChecked = false, isLocalToCallsite)) /** Returns the SearchResult of the best match. */ @@ -940,15 +940,15 @@ trait Implicits { /** Computes from a list of lists of implicit infos a map which takes * infos which are applicable for given expected type `pt` to their attributed trees. * - * @param iss The given list of lists of implicit infos - * @param isLocal Is implicit definition visible without prefix? - * If this is the case then symbols in preceding lists shadow - * symbols of the same name in succeeding lists. - * @return map from infos to search results + * @param iss The given list of lists of implicit infos + * @param isLocalToCallsite Is implicit definition visible without prefix? + * If this is the case then symbols in preceding lists shadow + * symbols of the same name in succeeding lists. + * @return map from infos to search results */ - def applicableInfos(iss: Infoss, isLocal: Boolean): Map[ImplicitInfo, SearchResult] = { + def applicableInfos(iss: Infoss, isLocalToCallsite: Boolean): Map[ImplicitInfo, SearchResult] = { val start = if (Statistics.canEnable) Statistics.startCounter(subtypeAppInfos) else null - val computation = new ImplicitComputation(iss, isLocal) { } + val computation = new ImplicitComputation(iss, isLocalToCallsite) { } val applicable = computation.findAll() if (Statistics.canEnable) Statistics.stopCounter(subtypeAppInfos, start) @@ -959,14 +959,14 @@ trait Implicits { * If found return a search result with a tree from found implicit info * which is typed with expected type `pt`. Otherwise return SearchFailure. * - * @param implicitInfoss The given list of lists of implicit infos - * @param isLocal Is implicit definition visible without prefix? - * If this is the case then symbols in preceding lists shadow - * symbols of the same name in succeeding lists. + * @param implicitInfoss The given list of lists of implicit infos + * @param isLocalToCallsite Is implicit definition visible without prefix? + * If this is the case then symbols in preceding lists shadow + * symbols of the same name in succeeding lists. */ - def searchImplicit(implicitInfoss: Infoss, isLocal: Boolean): SearchResult = + def searchImplicit(implicitInfoss: Infoss, isLocalToCallsite: Boolean): SearchResult = if (implicitInfoss.forall(_.isEmpty)) SearchFailure - else new ImplicitComputation(implicitInfoss, isLocal) findBest() + else new ImplicitComputation(implicitInfoss, isLocalToCallsite) findBest() /** Produce an implicict info map, i.e. a map from the class symbols C of all parts of this type to * the implicit infos in the companion objects of these class symbols C. @@ -1271,7 +1271,8 @@ trait Implicits { return SearchFailure } val cm = typed(Ident(ReflectRuntimeCurrentMirror)) - val interop = gen.mkMethodCall(ReflectRuntimeUniverse, nme.typeTagToManifest, List(tp), List(cm, tagInScope)) + val internal = gen.mkAttributedSelect(gen.mkAttributedRef(ReflectRuntimeUniverse), UniverseInternal) + val interop = gen.mkMethodCall(Select(internal, nme.typeTagToManifest), List(tp), List(cm, tagInScope)) wrapResult(interop) } } else { @@ -1326,7 +1327,7 @@ trait Implicits { val failstart = if (Statistics.canEnable) Statistics.startTimer(inscopeFailNanos) else null val succstart = if (Statistics.canEnable) Statistics.startTimer(inscopeSucceedNanos) else null - var result = searchImplicit(context.implicitss, isLocal = true) + var result = searchImplicit(context.implicitss, isLocalToCallsite = true) if (result.isFailure) { if (Statistics.canEnable) Statistics.stopTimer(inscopeFailNanos, failstart) @@ -1344,7 +1345,7 @@ trait Implicits { // `materializeImplicit` does some preprocessing for `pt` // is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`? if (result.isFailure && !wasAmbigious) - result = searchImplicit(implicitsOfExpectedType, isLocal = false) + result = searchImplicit(implicitsOfExpectedType, isLocalToCallsite = false) if (result.isFailure) { context.updateBuffer(previousErrs) @@ -1383,8 +1384,11 @@ trait Implicits { } def allImplicits: List[SearchResult] = { - def search(iss: Infoss, isLocal: Boolean) = applicableInfos(iss, isLocal).values - (search(context.implicitss, isLocal = true) ++ search(implicitsOfExpectedType, isLocal = false)).toList.filter(_.tree ne EmptyTree) + def search(iss: Infoss, isLocalToCallsite: Boolean) = applicableInfos(iss, isLocalToCallsite).values + ( + search(context.implicitss, isLocalToCallsite = true) ++ + search(implicitsOfExpectedType, isLocalToCallsite = false) + ).toList.filter(_.tree ne EmptyTree) } // find all implicits for some type that contains type variables @@ -1392,8 +1396,8 @@ trait Implicits { def allImplicitsPoly(tvars: List[TypeVar]): List[(SearchResult, List[TypeConstraint])] = { def resetTVars() = tvars foreach { _.constr = new TypeConstraint } - def eligibleInfos(iss: Infoss, isLocal: Boolean) = { - val eligible = new ImplicitComputation(iss, isLocal).eligible + def eligibleInfos(iss: Infoss, isLocalToCallsite: Boolean) = { + val eligible = new ImplicitComputation(iss, isLocalToCallsite).eligible eligible.toList.flatMap { (ii: ImplicitInfo) => // each ImplicitInfo contributes a distinct set of constraints (generated indirectly by typedImplicit) @@ -1402,12 +1406,13 @@ trait Implicits { // any previous errors should not affect us now context.flushBuffer() - val res = typedImplicit(ii, ptChecked = false, isLocal) + val res = typedImplicit(ii, ptChecked = false, isLocalToCallsite) if (res.tree ne EmptyTree) List((res, tvars map (_.constr))) else Nil } } - eligibleInfos(context.implicitss, isLocal = true) ++ eligibleInfos(implicitsOfExpectedType, isLocal = false) + eligibleInfos(context.implicitss, isLocalToCallsite = true) ++ + eligibleInfos(implicitsOfExpectedType, isLocalToCallsite = false) } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 9b5b0e1f37..23dc57d5b9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -374,7 +374,7 @@ trait Namers extends MethodSynthesis { } val existing = pkgOwner.info.decls.lookup(pid.name) - if (existing.isPackage && pkgOwner == existing.owner) + if (existing.hasPackageFlag && pkgOwner == existing.owner) existing else { val pkg = pkgOwner.newPackage(pid.name.toTermName, pos) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 916b8a3e0c..b166bf988d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -908,7 +908,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans var index = -1 for (stat <- stats) { index = index + 1 - def enterSym(sym: Symbol) = if (sym.isLocal) { + def enterSym(sym: Symbol) = if (sym.isLocalToBlock) { currentLevel.scope.enter(sym) symIndex(sym) = index } @@ -925,7 +925,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } private def enterReference(pos: Position, sym: Symbol) { - if (sym.isLocal) { + if (sym.isLocalToBlock) { val e = currentLevel.scope.lookupEntry(sym.name) if ((e ne null) && sym == e.sym) { var l = currentLevel @@ -1230,7 +1230,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans if (tree1.symbol.isLazy) tree1 :: Nil else { val lazySym = tree.symbol.lazyAccessorOrSelf - if (lazySym.isLocal && index <= currentLevel.maxindex) { + if (lazySym.isLocalToBlock && index <= currentLevel.maxindex) { debuglog("refsym = " + currentLevel.refsym) unit.error(currentLevel.refpos, "forward reference extends over definition of " + lazySym) } @@ -1549,7 +1549,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans if (!sym.exists) devWarning("Select node has NoSymbol! " + tree + " / " + tree.tpe) - else if (sym.hasLocalFlag) + else if (sym.isLocalToThis) varianceValidator.checkForEscape(sym, currentClass) def checkSuper(mix: Name) = @@ -1758,7 +1758,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans result match { case ClassDef(_, _, _, _) | TypeDef(_, _, _, _) => - if (result.symbol.isLocal || result.symbol.isTopLevel) + if (result.symbol.isLocalToBlock || result.symbol.isTopLevel) varianceValidator.traverse(result) case tt @ TypeTree() if tt.original != null => varianceValidator.traverse(tt.original) // See SI-7872 diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 06796eca8e..87da565142 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -71,7 +71,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT acc setInfoAndEnter (tpe cloneInfo acc) // Diagnostic for SI-7091 if (!accDefs.contains(clazz)) - reporter.error(sel.pos, s"Internal error: unable to store accessor definition in ${clazz}. clazz.isPackage=${clazz.isPackage}. Accessor required for ${sel} (${showRaw(sel)})") + reporter.error(sel.pos, s"Internal error: unable to store accessor definition in ${clazz}. clazz.hasPackageFlag=${clazz.hasPackageFlag}. Accessor required for ${sel} (${showRaw(sel)})") else storeAccessorDefinition(clazz, DefDef(acc, EmptyTree)) acc } @@ -224,7 +224,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT if (settings.lint) { if (sym.isPrivateLocal && sym.paramss.isEmpty) { qual.symbol.ancestors foreach { parent => - parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 => + parent.info.decls filterNot (x => x.isPrivate || x.isLocalToThis) foreach { m2 => if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) { unit.warning(sel.pos, sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala index fd8f9bebba..a2f52e1905 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala @@ -376,7 +376,7 @@ abstract class TreeCheckers extends Analyzer { def isOk(sym: Symbol) = treeSym hasTransOwner sym.enclosingSuchThat(x => !x.isTypeParameterOrSkolem) // account for higher order type params def isEligible(sym: Symbol) = (sym ne NoSymbol) && ( sym.isTypeParameter - || sym.isLocal + || sym.isLocalToBlock ) val referencedSymbols = (treeSym :: referencesInType(treeInfo)).distinct filter (sym => isEligible(sym) && !isOk(sym)) def mk[T](what: String, x: T, str: T => String = (x: T) => "" + x): ((Any, String)) = diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 71e6454931..ca960d7b11 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -452,10 +452,10 @@ trait TypeDiagnostics { val treeTypes = mutable.Set[Type]() def defnSymbols = defnTrees.toList map (_.symbol) - def localVars = defnSymbols filter (t => t.isLocal && t.isVar) + def localVars = defnSymbols filter (t => t.isLocalToBlock && t.isVar) def qualifiesTerm(sym: Symbol) = ( - (sym.isModule || sym.isMethod || sym.isPrivateLocal || sym.isLocal) + (sym.isModule || sym.isMethod || sym.isPrivateLocal || sym.isLocalToBlock) && !nme.isLocalName(sym.name) && !sym.isParameter && !sym.isParamAccessor // could improve this, but it's a pain @@ -499,12 +499,12 @@ trait TypeDiagnostics { def isUnusedType(m: Symbol): Boolean = ( m.isType && !m.isTypeParameterOrSkolem // would be nice to improve this - && (m.isPrivate || m.isLocal) + && (m.isPrivate || m.isLocalToBlock) && !(treeTypes.exists(tp => tp exists (t => t.typeSymbolDirect == m))) ) def isUnusedTerm(m: Symbol): Boolean = ( (m.isTerm) - && (m.isPrivate || m.isLocal) + && (m.isPrivate || m.isLocalToBlock) && !targets(m) && !(m.name == nme.WILDCARD) // e.g. val _ = foo && !ignoreNames(m.name.toTermName) // serialization methods diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index aadc8f5e3b..ba4b3499e5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -393,7 +393,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (sym.isPrivate && !sym.hasFlag(SYNTHETIC_PRIVATE)) { var o = owner while (o != NoSymbol && o != sym.owner && o != sym.owner.linkedClassOfClass && - !o.isLocal && !o.isPrivate && + !o.isLocalToBlock && !o.isPrivate && !o.privateWithin.hasTransOwner(sym.owner)) o = o.owner if (o == sym.owner || o == sym.owner.linkedClassOfClass) @@ -3015,7 +3015,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper /* 'accessor' and 'accessed' are so similar it becomes very difficult to * follow the logic, so I renamed one to something distinct. */ - def accesses(looker: Symbol, accessed: Symbol) = accessed.hasLocalFlag && ( + def accesses(looker: Symbol, accessed: Symbol) = accessed.isLocalToThis && ( (accessed.isParamAccessor) || (looker.hasAccessorFlag && !accessed.hasAccessorFlag && accessed.isPrivate) ) diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala index 6f369212ad..ac63232967 100644 --- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala +++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala @@ -37,5 +37,13 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val // (each mirror has its own set package symbols, because of the peculiarities of symbol loading in scala), // that `Predef` symbol only has a single owner, and this messes up visibility, which is calculated based on owners, not scopes. override def runtimeMirror(cl: ClassLoader): Mirror = rootMirror + + // Mirror and RuntimeClass come from both Global and reflect.runtime.SymbolTable + // so here the compiler needs an extra push to help decide between those (in favor of the latter) + import scala.reflect.ClassTag + override type Mirror = JavaMirror + override implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[Mirror]) + override type RuntimeClass = java.lang.Class[_] + override implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass]) } diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala index 5c53c81e8b..ee352c5e02 100644 --- a/src/compiler/scala/tools/reflect/StdTags.scala +++ b/src/compiler/scala/tools/reflect/StdTags.scala @@ -18,8 +18,7 @@ trait StdTags { new TypeCreator { def apply[U <: ApiUniverse with Singleton](m: Mirror[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.toTypeConstructor)) + u.appliedType(u.definitions.ListClass.toType, List(u.definitions.StringClass.toType)) } }) diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala index 4a3db09909..dfe53be6c9 100644 --- a/src/compiler/scala/tools/reflect/ToolBox.scala +++ b/src/compiler/scala/tools/reflect/ToolBox.scala @@ -21,19 +21,39 @@ trait ToolBox[U <: scala.reflect.api.Universe] { */ def frontEnd: FrontEnd + /** Represents mode of operations of the typechecker underlying `c.typecheck` calls. + * Is necessary since the shape of the typechecked tree alone is not enough to guess how it should be typechecked. + * Can be EXPRmode (typecheck as a term), TYPEmode (typecheck as a type) or PATTERNmode (typecheck as a pattern). + */ + type TypecheckMode + + /** Indicates that an argument to `c.typecheck` should be typechecked as a term. + * This is the default typechecking mode in Scala 2.11 and the only one supported in Scala 2.10. + */ + val TERMmode: TypecheckMode + + /** Indicates that an argument to `c.typecheck` should be typechecked as a type. + */ + val TYPEmode: TypecheckMode + + /** Indicates that an argument to `c.typecheck` should be typechecked as a pattern. + */ + val PATTERNmode: TypecheckMode + /** @see `Typers.typecheck` */ @deprecated("Use `tb.typecheck` instead", "2.11.0") def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = - typecheck(tree, pt, silent, withImplicitViewsDisabled, withMacrosDisabled) + typecheck(tree, TERMmode, pt, silent, withImplicitViewsDisabled, withMacrosDisabled) - /** Typechecks a tree using this ToolBox. + /** Typechecks a tree against the expected type `pt` + * under typechecking mode specified in `mode` with [[EXPRmode]] being default. * 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 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 false, `ToolBoxError` 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. * @@ -41,7 +61,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] { * `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, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree + def typecheck(tree: u.Tree, mode: TypecheckMode = TERMmode, 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 top-level context. * Optional `pos` parameter provides a position that will be associated with the implicit search. @@ -50,7 +70,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] { * 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 false, `ToolBoxError` 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. @@ -64,7 +84,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] { * 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 false, `ToolBoxError` 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. diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala index 6fabac9fe8..3b12086cc7 100644 --- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala +++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala @@ -116,8 +116,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => (expr, freeTermNames) } - def transformDuringTyper(expr: Tree, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean)(transform: (analyzer.Typer, Tree) => Tree): Tree = { - wrappingIntoTerm(verify(expr))(expr1 => { + def transformDuringTyper(expr: Tree, mode: scala.reflect.internal.Mode, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean)(transform: (analyzer.Typer, Tree) => Tree): Tree = { + def withWrapping(tree: Tree)(op: Tree => Tree) = if (mode == TERMmode) wrappingIntoTerm(tree)(op) else op(tree) + withWrapping(verify(expr))(expr1 => { // need to extract free terms, because otherwise you won't be able to typecheck macros against something that contains them val exprAndFreeTerms = extractFreeTerms(expr1, wrapFreeTermRefs = false) var expr2 = exprAndFreeTerms._1 @@ -130,7 +131,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => // rather than polluting the empty package with synthetics. // [Eugene] how can we implement that? val ownerClass = rootMirror.EmptyPackageClass.newClassSymbol(newTypeName("<expression-owner>")) - build.setTypeSignature(ownerClass, ClassInfoType(List(ObjectTpe), newScope, ownerClass)) + build.setInfo(ownerClass, ClassInfoType(List(ObjectTpe), newScope, ownerClass)) val owner = ownerClass.newLocalDummy(expr2.pos) val currentTyper = analyzer.newTyper(analyzer.rootContext(NoCompilationUnit, EmptyTree).make(expr2, owner)) val withImplicitFlag = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _) @@ -163,11 +164,11 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => }) } - def typecheck(expr: Tree, pt: Type, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree = - transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( + def typecheck(expr: Tree, pt: Type, mode: scala.reflect.internal.Mode, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree = + transformDuringTyper(expr, mode, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)( (currentTyper, expr) => { trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value)) - currentTyper.silent(_.typed(expr, pt), reportAmbiguousErrors = false) match { + currentTyper.silent(_.typed(expr, mode, pt), reportAmbiguousErrors = false) match { case analyzer.SilentResultValue(result) => trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value)) result @@ -179,7 +180,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => }) def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree = - transformDuringTyper(tree, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)( + transformDuringTyper(tree, TERMmode, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)( (currentTyper, tree) => { trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value)) analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg)) @@ -209,7 +210,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = true) val (obj, _) = rootMirror.EmptyPackageClass.newModuleAndClassSymbol( - nextWrapperModuleName()) + nextWrapperModuleName(), NoPosition, NoFlags) val minfo = ClassInfoType(List(ObjectTpe), newScope, obj.moduleClass) obj.moduleClass setInfo minfo @@ -356,7 +357,13 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => } } - def typecheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = withCompilerApi { compilerApi => + type TypecheckMode = scala.reflect.internal.Mode + val TypecheckMode = scala.reflect.internal.Mode + val TERMmode = TypecheckMode.EXPRmode + val TYPEmode = TypecheckMode.TYPEmode | TypecheckMode.FUNmode + val PATTERNmode = TypecheckMode.PATTERNmode + + def typecheck(tree: u.Tree, mode: TypecheckMode = TERMmode, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = withCompilerApi { compilerApi => import compilerApi._ if (compiler.settings.verbose) println("importing "+tree+", expectedType = "+expectedType) @@ -364,7 +371,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf => val cexpectedType: compiler.Type = importer.importType(expectedType) if (compiler.settings.verbose) println("typing "+ctree+", expectedType = "+expectedType) - val ttree: compiler.Tree = compiler.typecheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) + val ttree: compiler.Tree = compiler.typecheck(ctree, cexpectedType, mode, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled) val uttree = exporter.importTree(ttree) uttree } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala index 2027d43264..c2f1bf430d 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala @@ -120,8 +120,8 @@ trait Holes { self: Quasiquotes => } private def toStats(tree: Tree): Tree = - // q"$u.build.toStats($tree)" - Apply(Select(Select(u, nme.build), nme.toStats), tree :: Nil) + // q"$u.internal.reificationSupport.toStats($tree)" + Apply(Select(Select(Select(u, nme.internal), nme.reificationSupport), nme.toStats), tree :: Nil) private def toList(tree: Tree, tpe: Type): Tree = if (isListType(tpe)) tree @@ -234,10 +234,10 @@ trait Holes { self: Quasiquotes => } val lifter = inferUnliftable(tpe) assert(helperName.isTermName) - // q"val $name: $u.build.${helperName.toTypeName} = $u.build.$helperName($lifter)" + // q"val $name: $u.internal.reificationSupport.${helperName.toTypeName} = $u.internal.reificationSupport.$helperName($lifter)" ValDef(NoMods, name, - AppliedTypeTree(Select(Select(u, nme.build), helperName.toTypeName), List(TypeTree(tpe))), - Apply(Select(Select(u, nme.build), helperName), lifter :: Nil)) + AppliedTypeTree(Select(Select(Select(u, nme.internal), nme.reificationSupport), helperName.toTypeName), List(TypeTree(tpe))), + Apply(Select(Select(Select(u, nme.internal), nme.reificationSupport), helperName), lifter :: Nil)) } } } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala index 130a01332b..e7730f878f 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala @@ -42,7 +42,7 @@ trait Placeholders { self: Quasiquotes => case nme.apply => args case nme.unapply => val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args - dummy.attachments.get[SubpatternsAttachment].get.patterns + internal.subpatterns(dummy).get case _ => global.abort("unreachable") } diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala index 70580adbce..339937adc3 100644 --- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala +++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala @@ -7,7 +7,7 @@ import scala.reflect.internal.Flags._ trait Reifiers { self: Quasiquotes => import global._ - import global.build.{Select => _, Ident => _, TypeTree => _, _} + import global.build._ import global.treeInfo._ import global.definitions._ import Cardinality._ @@ -64,9 +64,9 @@ trait Reifiers { self: Quasiquotes => val FreshName(prefix) = origname val nameTypeName = if (origname.isTermName) tpnme.TermName else tpnme.TypeName val freshName = if (origname.isTermName) nme.freshTermName else nme.freshTypeName - // q"val ${names.head}: $u.$nameTypeName = $u.build.$freshName($prefix)" + // q"val ${names.head}: $u.$nameTypeName = $u.internal.reificationSupport.$freshName($prefix)" ValDef(NoMods, names.head, Select(u, nameTypeName), - Apply(Select(Select(u, nme.build), freshName), Literal(Constant(prefix)) :: Nil)) + Apply(Select(Select(Select(u, nme.internal), nme.reificationSupport), freshName), Literal(Constant(prefix)) :: Nil)) }.toList // q"..$freshdefs; $tree" SyntacticBlock(freshdefs :+ tree) @@ -146,7 +146,7 @@ trait Reifiers { self: Quasiquotes => override def reifyTreeSyntactically(tree: Tree) = tree match { case RefTree(qual, SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions => - mirrorBuildCall(nme.RefTree, reify(qual), tree) + mirrorBuildCall(nme.mkRefTree, reify(qual), tree) case This(SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions => mirrorCall(nme.This, tree) case SyntacticTraitDef(mods, name, tparams, earlyDefs, parents, selfdef, body) => @@ -365,7 +365,7 @@ trait Reifiers { self: Quasiquotes => Apply(Select(universe, name), args.toList) override def mirrorBuildCall(name: TermName, args: Tree*): Tree = - Apply(Select(Select(universe, nme.build), name), args.toList) + Apply(Select(Select(Select(universe, nme.internal), nme.reificationSupport), name), args.toList) override def scalaFactoryCall(name: String, args: Tree*): Tree = call("scala." + name, args: _*) diff --git a/src/reflect/scala/reflect/api/Annotations.scala b/src/reflect/scala/reflect/api/Annotations.scala index e19e0cefad..b880fad756 100644 --- a/src/reflect/scala/reflect/api/Annotations.scala +++ b/src/reflect/scala/reflect/api/Annotations.scala @@ -5,11 +5,11 @@ package api import scala.collection.immutable.ListMap /** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> + * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> * - * This trait provides annotation support for the reflection API. + * This trait provides annotation support for the reflection API. * - * The API distinguishes between two kinds of annotations: + * In Scala, annotations belong to one of the two categories: * * <ul> * <li>''Java annotations'': annotations on definitions produced by the Java compiler, i.e., subtypes of [[java.lang.annotation.Annotation]] @@ -22,16 +22,13 @@ import scala.collection.immutable.ListMap * it is stored as special attributes in the corresponding classfile, and not as a Java annotation. Note that subclassing * just [[scala.annotation.Annotation]] is not enough to have the corresponding metadata persisted for runtime reflection. * - * The distinction between Java and Scala annotations is manifested in the contract of [[scala.reflect.api.Annotations#Annotation]], which exposes - * both `scalaArgs` and `javaArgs`. For Scala or Java annotations extending [[scala.annotation.ClassfileAnnotation]] `scalaArgs` is empty - * and arguments are stored in `javaArgs`. For all other Scala annotations, arguments are stored in `scalaArgs` and `javaArgs` is empty. + * Both Java and Scala annotations are represented as typed trees carrying constructor invocations corresponding + * to the annotation. For instance, the annotation in `@ann(1, 2) class C` is represented as `q"@new ann(1, 2)"`. * - * Arguments in `scalaArgs` are represented as typed trees. Note that these trees are not transformed by any phases - * following the type-checker. Arguments in `javaArgs` are repesented as a map from [[scala.reflect.api.Names#Name]] to - * [[scala.reflect.api.Annotations#JavaArgument]]. Instances of `JavaArgument` represent different kinds of Java annotation arguments: - * - literals (primitive and string constants), - * - arrays and - * - nested annotations. + * Unlike Java reflection, Scala reflection does not support evaluation of constructor invocations stored in annotations + * into underlying objects. For instance it's impossible to go from `@ann(1, 2) class C` to `ann(1, 2)`, so one + * has to analyze trees representing annotation arguments to manually extract corresponding values. Towards that end, + * arguments of an annotation can be obtained via `annotation.tree.children.tail`. * * For more information about `Annotation`s, see the [[http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html Reflection Guide: Annotations, Names, Scopes, and More]] * @@ -46,17 +43,22 @@ trait Annotations { self: Universe => */ type Annotation >: Null <: AnyRef with AnnotationApi - /** The constructor/extractor for `Annotation` instances. - * @group Extractors - */ - val Annotation: AnnotationExtractor + /** The constructor/extractor for `Annotation` instances. + * @group Extractors + */ + val Annotation: AnnotationExtractor /** An extractor class to create and pattern match with syntax `Annotation(tpe, scalaArgs, javaArgs)`. * Here, `tpe` is the annotation type, `scalaArgs` the payload of Scala annotations, and `javaArgs` the payload of Java annotations. * @group Extractors */ abstract class AnnotationExtractor { + def apply(tree: Tree): Annotation = treeToAnnotation(tree) + + @deprecated("Use `apply(tree: Tree): Annotation` instead", "2.11.0") def apply(tpe: Type, scalaArgs: List[Tree], javaArgs: ListMap[Name, JavaArgument]): Annotation + + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def unapply(ann: Annotation): Option[(Type, List[Tree], ListMap[Name, JavaArgument])] } @@ -65,44 +67,64 @@ trait Annotations { self: Universe => * @group API */ trait AnnotationApi { + /** The tree underlying the annotation. */ + def tree: Tree = annotationToTree(this.asInstanceOf[Annotation]) + /** The type of the annotation. */ + @deprecated("Use `tree.tpe` instead", "2.11.0") def tpe: Type /** Payload of the Scala annotation: a list of abstract syntax trees that represent the argument. * Empty for Java annotations. */ + @deprecated("Use `tree.children.tail` instead", "2.11.0") def scalaArgs: List[Tree] /** Payload of the Java annotation: a list of name-value pairs. * Empty for Scala annotations. */ + @deprecated("Use `tree.children.tail` instead", "2.11.0") def javaArgs: ListMap[Name, JavaArgument] } + protected[scala] def annotationToTree(ann: Annotation): Tree + protected[scala] def treeToAnnotation(tree: Tree): Annotation + /** A Java annotation argument * @template * @group Annotations */ - type JavaArgument >: Null <: AnyRef + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") + type JavaArgument >: Null <: AnyRef with JavaArgumentApi + /** Has no special methods. Is here to provides erased identity for `CompoundType`. + * @group API + */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") + trait JavaArgumentApi /** A literal argument to a Java annotation as `"Use X instead"` in `@Deprecated("Use X instead")` * @template * @group Annotations */ - type LiteralArgument >: Null <: AnyRef with JavaArgument with LiteralArgumentApi + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") + type LiteralArgument >: Null <: LiteralArgumentApi with JavaArgument /** The constructor/extractor for `LiteralArgument` instances. * @group Extractors */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") val LiteralArgument: LiteralArgumentExtractor /** An extractor class to create and pattern match with syntax `LiteralArgument(value)` * where `value` is the constant argument. * @group Extractors */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") abstract class LiteralArgumentExtractor { + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def apply(value: Constant): LiteralArgument + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def unapply(arg: LiteralArgument): Option[Constant] } @@ -110,8 +132,10 @@ trait Annotations { self: Universe => * The main source of information about annotations is the [[scala.reflect.api.Annotations]] page. * @group API */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") trait LiteralArgumentApi { /** The underlying compile-time constant value. */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def value: Constant } @@ -119,19 +143,24 @@ trait Annotations { self: Universe => * @template * @group Annotations */ - type ArrayArgument >: Null <: AnyRef with JavaArgument with ArrayArgumentApi + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") + type ArrayArgument >: Null <: ArrayArgumentApi with JavaArgument /** The constructor/extractor for `ArrayArgument` instances. * @group Extractors */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") val ArrayArgument: ArrayArgumentExtractor /** An extractor class to create and pattern match with syntax `ArrayArgument(args)` * where `args` is the argument array. * @group Extractors */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") abstract class ArrayArgumentExtractor { + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def apply(args: Array[JavaArgument]): ArrayArgument + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def unapply(arg: ArrayArgument): Option[Array[JavaArgument]] } @@ -139,8 +168,10 @@ trait Annotations { self: Universe => * The main source of information about annotations is the [[scala.reflect.api.Annotations]] page. * @group API */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") trait ArrayArgumentApi { /** The underlying array of Java annotation arguments. */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def args: Array[JavaArgument] } @@ -148,19 +179,24 @@ trait Annotations { self: Universe => * @template * @group Annotations */ - type NestedArgument >: Null <: AnyRef with JavaArgument with NestedArgumentApi + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") + type NestedArgument >: Null <: NestedArgumentApi with JavaArgument /** The constructor/extractor for `NestedArgument` instances. * @group Extractors */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") val NestedArgument: NestedArgumentExtractor /** An extractor class to create and pattern match with syntax `NestedArgument(annotation)` * where `annotation` is the nested annotation. * @group Extractors */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") abstract class NestedArgumentExtractor { + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def apply(annotation: Annotation): NestedArgument + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def unapply(arg: NestedArgument): Option[Annotation] } @@ -168,8 +204,10 @@ trait Annotations { self: Universe => * The main source of information about annotations is the [[scala.reflect.api.Annotations]] page. * @group API */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") trait NestedArgumentApi { /** The underlying nested annotation. */ + @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0") def annotation: Annotation } } diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala deleted file mode 100644 index 57dc7da6cc..0000000000 --- a/src/reflect/scala/reflect/api/BuildUtils.scala +++ /dev/null @@ -1,306 +0,0 @@ -package scala -package reflect -package api - -/** - * This is an internal implementation class. - * @groupname TreeBuilders Tree Building - */ -private[reflect] trait BuildUtils { self: Universe => - - /** @group TreeBuilders */ - val build: BuildApi - - // this API abstracts away the functionality necessary for reification - // it's too gimmicky and unstructured to be exposed directly in the universe - // but we need it in a publicly available place for reification to work - - /** @group TreeBuilders */ - abstract class BuildApi { - /** Selects type symbol with given simple name `name` from the defined members of `owner`. - */ - def selectType(owner: Symbol, name: String): TypeSymbol - - /** Selects term symbol with given name and type from the defined members of prefix type - */ - def selectTerm(owner: Symbol, name: String): TermSymbol - - /** Selects overloaded method symbol with given name and index - */ - def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol - - /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has - * the current symbol as its owner. - */ - def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol - - /** Create a fresh free term symbol. - * @param name the name of the free variable - * @param value the value of the free variable at runtime - * @param flags (optional) flags of the free variable - * @param origin debug information that tells where this symbol comes from - */ - def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol - - /** Create a fresh free type symbol. - * @param name the name of the free variable - * @param flags (optional) flags of the free variable - * @param origin debug information that tells where this symbol comes from - */ - def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol - - /** Set symbol's type signature to given type. - * @return the symbol itself - */ - def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S - - /** Set symbol's annotations to given annotations `annots`. - */ - def setAnnotations[S <: Symbol](sym: S, annots: List[Annotation]): S - - def This(sym: Symbol): Tree - - def Select(qualifier: Tree, sym: Symbol): Select - - def Ident(sym: Symbol): Ident - - def TypeTree(tp: Type): TypeTree - - def thisPrefix(sym: Symbol): Type - - def setType[T <: Tree](tree: T, tpe: Type): T - - def setSymbol[T <: Tree](tree: T, sym: Symbol): T - - def toStats(tree: Tree): List[Tree] - - def mkAnnotation(tree: Tree): Tree - - def mkAnnotation(trees: List[Tree]): List[Tree] - - def mkRefineStat(stat: Tree): Tree - - def mkRefineStat(stats: List[Tree]): List[Tree] - - def mkPackageStat(stat: Tree): Tree - - def mkPackageStat(stats: List[Tree]): List[Tree] - - def mkEarlyDef(defn: Tree): Tree - - def mkEarlyDef(defns: List[Tree]): List[Tree] - - def RefTree(qual: Tree, sym: Symbol): Tree - - def freshTermName(prefix: String): TermName - - def freshTypeName(prefix: String): TypeName - - val ImplicitParams: ImplicitParamsExtractor - - trait ImplicitParamsExtractor { - def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]] - def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])] - } - - val ScalaDot: ScalaDotExtractor - - trait ScalaDotExtractor { - def apply(name: Name): Tree - def unapply(tree: Tree): Option[Name] - } - - val FlagsRepr: FlagsReprExtractor - - trait FlagsReprExtractor { - def apply(value: Long): FlagSet - def unapply(flags: Long): Some[Long] - } - - val SyntacticTypeApplied: SyntacticTypeAppliedExtractor - - trait SyntacticTypeAppliedExtractor { - def apply(tree: Tree, targs: List[Tree]): Tree - def unapply(tree: Tree): Some[(Tree, List[Tree])] - } - - val SyntacticApplied: SyntacticAppliedExtractor - - trait SyntacticAppliedExtractor { - def apply(tree: Tree, argss: List[List[Tree]]): Tree - def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] - } - - val SyntacticClassDef: SyntacticClassDefExtractor - - trait SyntacticClassDefExtractor { - def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], - constrMods: Modifiers, vparamss: List[List[Tree]], - earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef - def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]], - List[Tree], List[Tree], ValDef, List[Tree])] - } - - val SyntacticTraitDef: SyntacticTraitDefExtractor - - trait SyntacticTraitDefExtractor { - def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], - earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef - def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], - List[Tree], List[Tree], ValDef, List[Tree])] - } - - val SyntacticObjectDef: SyntacticObjectDefExtractor - - trait SyntacticObjectDefExtractor { - def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree], - parents: List[Tree], selfType: Tree, body: List[Tree]): ModuleDef - def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])] - } - - val SyntacticPackageObjectDef: SyntacticPackageObjectDefExtractor - - trait SyntacticPackageObjectDefExtractor { - def apply(name: TermName, earlyDefs: List[Tree], - parents: List[Tree], selfType: Tree, body: List[Tree]): PackageDef - def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] - } - - val SyntacticTuple: SyntacticTupleExtractor - val SyntacticTupleType: SyntacticTupleExtractor - - trait SyntacticTupleExtractor { - def apply(args: List[Tree]): Tree - def unapply(tree: Tree): Option[List[Tree]] - } - - val SyntacticBlock: SyntacticBlockExtractor - - trait SyntacticBlockExtractor { - def apply(stats: List[Tree]): Tree - def unapply(tree: Tree): Option[List[Tree]] - } - - val SyntacticNew: SyntacticNewExtractor - - trait SyntacticNewExtractor { - def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree - def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] - } - - val SyntacticFunctionType: SyntacticFunctionTypeExtractor - - trait SyntacticFunctionTypeExtractor { - def apply(argtpes: List[Tree], restpe: Tree): Tree - def unapply(tree: Tree): Option[(List[Tree], Tree)] - } - - val SyntacticFunction: SyntacticFunctionExtractor - - trait SyntacticFunctionExtractor { - def apply(params: List[Tree], body: Tree): Function - - def unapply(tree: Function): Option[(List[ValDef], Tree)] - } - - val SyntacticDefDef: SyntacticDefDefExtractor - - trait SyntacticDefDefExtractor { - def apply(mods: Modifiers, name: TermName, tparams: List[Tree], - vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef - - def unapply(tree: Tree): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] - } - - val SyntacticValDef: SyntacticValDefExtractor - val SyntacticVarDef: SyntacticValDefExtractor - - trait SyntacticValDefExtractor { - def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef - def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)] - } - - val SyntacticPatDef: SyntacticPatDefExtractor - - trait SyntacticPatDefExtractor { - def apply(mods: Modifiers, pat: Tree, tpt: Tree, rhs: Tree): List[ValDef] - } - - val SyntacticAssign: SyntacticAssignExtractor - - trait SyntacticAssignExtractor { - def apply(lhs: Tree, rhs: Tree): Tree - def unapply(tree: Tree): Option[(Tree, Tree)] - } - - val SyntacticValFrom: SyntacticValFromExtractor - - trait SyntacticValFromExtractor { - def apply(pat: Tree, rhs: Tree): Tree - def unapply(tree: Tree): Option[(Tree, Tree)] - } - - val SyntacticValEq: SyntacticValEqExtractor - - trait SyntacticValEqExtractor { - def apply(pat: Tree, rhs: Tree): Tree - def unapply(tree: Tree): Option[(Tree, Tree)] - } - - val SyntacticFilter: SyntacticFilterExtractor - - trait SyntacticFilterExtractor { - def apply(test: Tree): Tree - def unapply(tree: Tree): Option[(Tree)] - } - - val SyntacticEmptyTypeTree: SyntacticEmptyTypeTreeExtractor - - trait SyntacticEmptyTypeTreeExtractor { - def apply(): TypeTree - def unapply(tt: TypeTree): Boolean - } - - val SyntacticFor: SyntacticForExtractor - val SyntacticForYield: SyntacticForExtractor - - trait SyntacticForExtractor { - def apply(enums: List[Tree], body: Tree): Tree - def unapply(tree: Tree): Option[(List[Tree], Tree)] - } - - def UnliftListElementwise[T](unliftable: Unliftable[T]): UnliftListElementwise[T] - trait UnliftListElementwise[T] { - def unapply(lst: List[Tree]): Option[List[T]] - } - - def UnliftListOfListsElementwise[T](unliftable: Unliftable[T]): UnliftListOfListsElementwise[T] - trait UnliftListOfListsElementwise[T] { - def unapply(lst: List[List[Tree]]): Option[List[List[T]]] - } - - val SyntacticMatch: SyntacticMatchExtractor - trait SyntacticMatchExtractor { - def apply(selector: Tree, cases: List[Tree]): Match - def unapply(tree: Match): Option[(Tree, List[CaseDef])] - } - - val SyntacticTry: SyntacticTryExtractor - trait SyntacticTryExtractor { - def apply(block: Tree, catches: List[Tree], finalizer: Tree): Try - def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] - } - - val SyntacticIdent: SyntacticIdentExtractor - trait SyntacticIdentExtractor { - def apply(name: Name, isBackquoted: Boolean = false): Ident - def unapply(tree: Ident): Option[(Name, Boolean)] - } - - val SyntacticImport: SyntacticImportExtractor - trait SyntacticImportExtractor { - def apply(expr: Tree, selectors: List[Tree]): Import - def unapply(imp: Import): Some[(Tree, List[Tree])] - } - } -} diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala index c654961f4a..e73c5ffa91 100644 --- a/src/reflect/scala/reflect/api/Constants.scala +++ b/src/reflect/scala/reflect/api/Constants.scala @@ -69,7 +69,7 @@ package api * val enumRef = jarg("enumRef").symbolValue * println(enumRef) // value BAR * - * val siblings = enumRef.owner.typeSignature.declarations + * val siblings = enumRef.owner.info.decls * val enumValues = siblings.filter(sym => sym.isVal && sym.isPublic) * println(enumValues) // Scope{ * // final val FOO: JavaSimpleEnumeration; @@ -165,7 +165,7 @@ trait Constants { * // ideally one should match instead of casting * println(enumRef) // value BAR * - * val siblings = enumRef.owner.typeSignature.declarations + * val siblings = enumRef.owner.info.decls * val enumValues = siblings.filter(sym => sym.isVal && sym.isPublic) * println(enumValues) // Scope{ * // final val FOO: JavaSimpleEnumeration; diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala index 54b65166d8..bf4d6353df 100644 --- a/src/reflect/scala/reflect/api/FlagSets.scala +++ b/src/reflect/scala/reflect/api/FlagSets.scala @@ -131,8 +131,8 @@ trait FlagSets { self: Universe => /** Flag indicating that tree has `protected` modifier set */ val PROTECTED: FlagSet - /** Flag indicating that tree represents a member local to current class - * (i.e. private[this] or protected[this]. + /** Flag indicating that tree represents a member local to current class, + * i.e. private[this] or protected[this]. * This requires having either PRIVATE or PROTECTED set as well. */ val LOCAL: FlagSet @@ -167,9 +167,6 @@ trait FlagSets { self: Universe => /** Flag indicating that tree represents a variable or a member initialized to the default value */ val DEFAULTINIT: FlagSet - /** Flag indicating that tree was generated by the compiler */ - val SYNTHETIC: FlagSet - /** Flag indicating that tree represents an enum. * * It can only appear at @@ -177,6 +174,82 @@ trait FlagSets { self: Universe => * - enum constants **/ val ENUM: FlagSet + + /** Flag indicating that tree represents a parameter of the primary constructor of some class + * or a synthetic member underlying thereof. E.g. here's how 'class C(val x: Int)' is represented: + * + * [[syntax trees at end of parser]]// Scala source: tmposDU52 + * class C extends scala.AnyRef { + * <paramaccessor> val x: Int = _; + * def <init>(x: Int) = { + * super.<init>(); + * () + * } + * } + * ClassDef( + * Modifiers(), TypeName("C"), List(), + * Template( + * List(Select(Ident(scala), TypeName("AnyRef"))), + * noSelfType, + * List( + * ValDef(Modifiers(PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree), + * DefDef( + * Modifiers(), nme.CONSTRUCTOR, List(), + * List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree))), TypeTree(), + * Block(List(pendingSuperCall), Literal(Constant(()))))))))) + */ + val PARAMACCESSOR: FlagSet + + /** Flag indicating that tree represents a parameter of the primary constructor of some case class + * or a synthetic member underlying thereof. E.g. here's how 'case class C(val x: Int)' is represented: + * + * [[syntax trees at end of parser]]// Scala source: tmpnHkJ3y + * case class C extends scala.Product with scala.Serializable { + * <caseaccessor> <paramaccessor> val x: Int = _; + * def <init>(x: Int) = { + * super.<init>(); + * () + * } + * } + * ClassDef( + * Modifiers(CASE), TypeName("C"), List(), + * Template( + * List(Select(Ident(scala), TypeName("Product")), Select(Ident(scala), TypeName("Serializable"))), + * noSelfType, + * List( + * ValDef(Modifiers(CASEACCESSOR | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree), + * DefDef( + * Modifiers(), nme.CONSTRUCTOR, List(), + * List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree))), TypeTree(), + * Block(List(pendingSuperCall), Literal(Constant(()))))))))) + */ + val CASEACCESSOR: FlagSet + + /** Flag used to distinguish programmatically generated definitions from user-written ones. + * @see ARTIFACT + */ + val SYNTHETIC: FlagSet + + /** Flag used to distinguish platform-specific implementation details. + * Trees and symbols which are currently marked ARTIFACT by scalac: + * * $outer fields and accessors + * * super accessors + * * protected accessors + * * lazy local accessors + * * bridge methods + * * default argument getters + * * evaluation-order preserving locals for right-associative and out-of-order named arguments + * * catch-expression storing vals + * * anything else which feels a setFlag(ARTIFACT) + * + * @see SYNTHETIC + */ + val ARTIFACT: FlagSet + + /** Flag that indicates methods that are supposed to be stable + * (e.g. synthetic getters of valdefs). + */ + val STABLE: FlagSet } /** The empty set of flags diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala index 1b654a4a8d..aca0692d0d 100644 --- a/src/reflect/scala/reflect/api/ImplicitTags.scala +++ b/src/reflect/scala/reflect/api/ImplicitTags.scala @@ -51,8 +51,6 @@ trait ImplicitTags { implicit val TypeSymbolTag: ClassTag[TypeSymbol] implicit val ModuleSymbolTag: ClassTag[ModuleSymbol] implicit val ClassSymbolTag: ClassTag[ClassSymbol] - implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol] - implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol] // Tags for misc Tree relatives. implicit val PositionTag: ClassTag[Position] @@ -91,7 +89,6 @@ trait ImplicitTags { implicit val NewTag: ClassTag[New] implicit val PackageDefTag: ClassTag[PackageDef] implicit val RefTreeTag: ClassTag[RefTree] - implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed] implicit val ReturnTag: ClassTag[Return] implicit val SelectFromTypeTreeTag: ClassTag[SelectFromTypeTree] implicit val SelectTag: ClassTag[Select] @@ -114,4 +111,9 @@ trait ImplicitTags { implicit val UnApplyTag: ClassTag[UnApply] implicit val ValDefTag: ClassTag[ValDef] implicit val ValOrDefDefTag: ClassTag[ValOrDefDef] + + // Miscellaneous + implicit val TreeCopierTag: ClassTag[TreeCopier] + implicit val RuntimeClassTag: ClassTag[RuntimeClass] + implicit val MirrorTag: ClassTag[Mirror] } diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala deleted file mode 100644 index 6539137cee..0000000000 --- a/src/reflect/scala/reflect/api/Importers.scala +++ /dev/null @@ -1,104 +0,0 @@ -package scala -package reflect -package api - -/** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> - * - * This trait provides support for importers, a facility to migrate reflection artifacts between universes. - * ''Note: this trait should typically be used only rarely.'' - * - * Reflection artifacts, such as [[scala.reflect.api.Symbols Symbols]] and [[scala.reflect.api.Types Types]], - * are contained in [[scala.reflect.api.Universe Universe]]s. Typically all processing happens - * within a single `Universe` (e.g. a compile-time macro `Universe` or a runtime reflection `Universe`), but sometimes - * there is a need to migrate artifacts from one `Universe` to another. For example, runtime compilation works by - * importing runtime reflection trees into a runtime compiler universe, compiling the importees and exporting the - * result back. - * - * Reflection artifacts are firmly grounded in their `Universe`s, which is reflected by the fact that types of artifacts - * from different universes are not compatible. By using `Importer`s, however, they be imported from one universe - * into another. For example, to import `foo.bar.Baz` from the source `Universe` to the target `Universe`, - * an importer will first check whether the entire owner chain exists in the target `Universe`. - * If it does, then nothing else will be done. Otherwise, the importer will recreate the entire owner chain - * and will import the corresponding type signatures into the target `Universe`. - * - * Since importers match `Symbol` tables of the source and the target `Universe`s using plain string names, - * it is programmer's responsibility to make sure that imports don't distort semantics, e.g., that - * `foo.bar.Baz` in the source `Universe` means the same that `foo.bar.Baz` does in the target `Universe`. - * - * === Example === - * - * Here's how one might implement a macro that performs compile-time evaluation of its argument - * by using a runtime compiler to compile and evaluate a tree that belongs to a compile-time compiler: - * - * {{{ - * def staticEval[T](x: T) = macro staticEval[T] - * - * def staticEval[T](c: scala.reflect.macros.blackbox.Context)(x: c.Expr[T]) = { - * // creates a runtime reflection universe to host runtime compilation - * import scala.reflect.runtime.{universe => ru} - * val mirror = ru.runtimeMirror(c.libraryClassLoader) - * import scala.tools.reflect.ToolBox - * val toolBox = mirror.mkToolBox() - * - * // runtime reflection universe and compile-time macro universe are different - * // therefore an importer is needed to bridge them - * // currently mkImporter requires a cast to correctly assign the path-dependent types - * val importer0 = ru.mkImporter(c.universe) - * val importer = importer0.asInstanceOf[ru.Importer { val from: c.universe.type }] - * - * // the created importer is used to turn a compiler tree into a runtime compiler tree - * // both compilers use the same classpath, so semantics remains intact - * val imported = importer.importTree(tree) - * - * // after the tree is imported, it can be evaluated as usual - * val tree = toolBox.untypecheck(imported.duplicate) - * val valueOfX = toolBox.eval(imported).asInstanceOf[T] - * ... - * } - * }}} - * - * @group ReflectionAPI - */ -trait Importers { self: Universe => - - /** Creates an importer that moves reflection artifacts between universes. - * @group Importers - */ - def mkImporter(from0: Universe): Importer { val from: from0.type } - - /** The API of importers. - * The main source of information about importers is the [[scala.reflect.api.Importers]] page. - * @group Importers - */ - trait Importer { - /** The source universe of reflection artifacts that will be processed. - * The target universe is universe that created this importer with `mkImporter`. - */ - val from: Universe - - /** An importer that works in reverse direction, namely: - * imports reflection artifacts from the current universe to the universe specified in `from`. - */ - val reverse: from.Importer { val from: self.type } - - /** In the current universe, locates or creates a symbol that corresponds to the provided symbol in the source universe. - * If necessary imports the owner chain, companions, type signature, annotations and attachments. - */ - def importSymbol(sym: from.Symbol): Symbol - - /** In the current universe, locates or creates a type that corresponds to the provided type in the source universe. - * If necessary imports the underlying symbols, annotations, scopes and trees. - */ - def importType(tpe: from.Type): Type - - /** In the current universe, creates a tree that corresponds to the provided tree in the source universe. - * If necessary imports the underlying symbols, types and attachments. - */ - def importTree(tree: from.Tree): Tree - - /** In the current universe, creates a position that corresponds to the provided position in the source universe. - */ - def importPosition(pos: from.Position): Position - } -} diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala new file mode 100644 index 0000000000..37406385c8 --- /dev/null +++ b/src/reflect/scala/reflect/api/Internals.scala @@ -0,0 +1,1145 @@ +package scala +package reflect +package api + +import scala.language.implicitConversions +import scala.language.higherKinds + +/** + * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> + * + * This trait assembles APIs occasionally necessary for performing low-level operations on reflection artifacts. + * See [[Internals#InternalApi]] for more information about nature, usefulness and compatibility guarantees of these APIs. + * + * @group ReflectionAPI + */ +trait Internals { self: Universe => + + /** @see [[InternalApi]] + * @group Internal + */ + val internal: Internal + + /** @see [[InternalApi]] + * @group Internal + */ + type Internal <: InternalApi + + /** Reflection API exhibits a tension inherent to experimental things: + * on the one hand we want it to grow into a beautiful and robust API, + * but on the other hand we have to deal with immaturity of underlying mechanisms + * by providing not very pretty solutions to enable important use cases. + * + * In Scala 2.10, which was our first stab at reflection API, we didn't have a systematic + * approach to dealing with this tension, sometimes exposing too much of internals (e.g. Symbol.deSkolemize) + * and sometimes exposing too little (e.g. there's still no facility to change owners, to do typing + * transformations, etc). This resulted in certain confusion with some internal APIs + * living among public ones, scaring the newcomers, and some internal APIs only available via casting, + * which requires intimate knowledge of the compiler and breaks compatibility guarantees. + * + * This led to creation of the `internal` API module for the reflection API, which + * provides advanced APIs necessary for macros that push boundaries of the state of the art, + * clearly demarcating them from the more or less straightforward rest and + * providing compatibility guarantees on par with the rest of the reflection API + * (full compatibility within minor releases, best effort towards backward compatibility within major releases, + * clear replacement path in case of rare incompatible changes in major releases). + * + * The `internal` module itself (the value that implements [[InternalApi]]) isn't defined here, + * in [[scala.reflect.api.Universe]], but is provided on per-implementation basis. Runtime API endpoint + * ([[scala.reflect.runtime.universe]]) provides `universe.compat: InternalApi`, whereas compile-time API endpoints + * (instances of [[scala.reflect.macros.Context]]) provide `c.compat: ContextInternalApi`, which extends `InternalApi` + * with additional universe-specific and context-specific functionality. + * + * @group Internal + */ + trait InternalApi { internal => + /** This is an internal implementation module. + */ + val reificationSupport: ReificationSupportApi + + /** Creates an importer that moves reflection artifacts between universes. + * @see [[Importer]] + */ + // SI-6241: move importers to a mirror + def createImporter(from0: Universe): Importer { val from: from0.type } + + /** + * Convert a [[scala.reflect.api.TypeTags#TypeTag]] to a [[scala.reflect.Manifest]]. + * + * Compiler usually generates these conversions automatically, when a type tag for a type `T` is in scope, + * and an implicit of type `Manifest[T]` is requested, but this method can also be called manually. + * For example: + * {{{ + * typeTagToManifest(scala.reflect.runtime.currentMirror, implicitly[TypeTag[String]]) + * }}} + * @group TagInterop + */ + def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] = + throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.") + + /** + * Convert a [[scala.reflect.Manifest]] to a [[scala.reflect.api.TypeTags#TypeTag]]. + * + * Compiler usually generates these conversions automatically, when a manifest for a type `T` is in scope, + * and an implicit of type `TypeTag[T]` is requested, but this method can also be called manually. + * For example: + * {{{ + * manifestToTypeTag(scala.reflect.runtime.currentMirror, implicitly[Manifest[String]]) + * }}} + * @group TagInterop + */ + def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] = + throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.") + + /** Create a new scope with the given initial elements. + */ + def newScopeWith(elems: Symbol*): Scope + + /** Extracts free term symbols from a tree that is reified or contains reified subtrees. + */ + def freeTerms(tree: Tree): List[FreeTermSymbol] + + /** Extracts free type symbols from a tree that is reified or contains reified subtrees. + */ + def freeTypes(tree: Tree): List[FreeTypeSymbol] + + /** Substitute symbols in `to` for corresponding occurrences of references to + * symbols `from` in this type. + */ + def substituteSymbols(tree: Tree, from: List[Symbol], to: List[Symbol]): Tree + + /** Substitute types in `to` for corresponding occurrences of references to + * symbols `from` in this tree. + */ + def substituteTypes(tree: Tree, from: List[Symbol], to: List[Type]): Tree + + /** Substitute given tree `to` for occurrences of nodes that represent + * `C.this`, where `C` referes to the given class `clazz`. + */ + def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree + + /** A factory method for `ClassDef` nodes. + */ + def classDef(sym: Symbol, impl: Template): ClassDef + + /** A factory method for `ModuleDef` nodes. + */ + def moduleDef(sym: Symbol, impl: Template): ModuleDef + + /** A factory method for `ValDef` nodes. + */ + def valDef(sym: Symbol, rhs: Tree): ValDef + + /** A factory method for `ValDef` nodes. + */ + def valDef(sym: Symbol): ValDef + + /** A factory method for `DefDef` nodes. + */ + def defDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + /** A factory method for `DefDef` nodes. + */ + def defDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef + + /** A factory method for `DefDef` nodes. + */ + def defDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef + + /** A factory method for `DefDef` nodes. + */ + def defDef(sym: Symbol, rhs: Tree): DefDef + + /** A factory method for `DefDef` nodes. + */ + def defDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef + + /** A factory method for `TypeDef` nodes. + */ + def typeDef(sym: Symbol, rhs: Tree): TypeDef + + /** A factory method for `TypeDef` nodes. + */ + def typeDef(sym: Symbol): TypeDef + + /** A factory method for `LabelDef` nodes. + */ + def labelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef + + /** Does this symbol represent a free term captured by reification? + * If yes, `isTerm` is also guaranteed to be true. + */ + def isFreeTerm(symbol: Symbol): Boolean + + /** This symbol cast to a free term symbol. + * @throws ScalaReflectionException if `isFreeTerm` is false. + */ + def asFreeTerm(symbol: Symbol): FreeTermSymbol + + /** Does this symbol represent a free type captured by reification? + * If yes, `isType` is also guaranteed to be true. + */ + def isFreeType(symbol: Symbol): Boolean + + /** This symbol cast to a free type symbol. + * @throws ScalaReflectionException if `isFreeType` is false. + */ + def asFreeType(symbol: Symbol): FreeTypeSymbol + + def newTermSymbol(owner: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol + + def newModuleAndClassSymbol(owner: Symbol, name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) + + def newMethodSymbol(owner: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol + + def newTypeSymbol(owner: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol + + def newClassSymbol(owner: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol + + def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol + + def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol + + /** Does this symbol or its underlying type represent a typechecking error? + */ + def isErroneous(symbol: Symbol): 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(symbol: Symbol): Boolean + + /** If this symbol is a skolem, its corresponding type parameter, otherwise the symbol itself. + * + * [[https://groups.google.com/forum/#!msg/scala-internals/0j8laVNTQsI/kRXMF_c8bGsJ To quote Martin Odersky]], + * skolems are synthetic type "constants" that are copies of existentially bound or universally + * bound type variables. E.g. if one is inside the right-hand side of a method: + * + * {{{ + * def foo[T](x: T) = ... foo[List[T]].... + * }}} + * + * the skolem named `T` refers to the unknown type instance of `T` when `foo` is called. It needs to be different + * from the type parameter because in a recursive call as in the `foo[List[T]]` above the type parameter gets + * substituted with `List[T]`, but the ''type skolem'' stays what it is. + * + * The other form of skolem is an ''existential skolem''. Say one has a function + * + * {{{ + * def bar(xs: List[T] forSome { type T }) = xs.head + * }}} + * + * then each occurrence of `xs` on the right will have type `List[T']` where `T'` is a fresh copy of `T`. + */ + def deSkolemize(symbol: Symbol): Symbol + + /** Forces all outstanding completers associated with this symbol. + * After this call returns, the symbol becomes immutable and thread-safe. + */ + def initialize(symbol: Symbol): symbol.type + + /** Calls [[initialize]] on the owner and all the value and type parameters of the symbol. + */ + def fullyInitialize(symbol: Symbol): symbol.type + + /** Calls [[initialize]] on all the value and type parameters of the type. + */ + def fullyInitialize(tp: Type): tp.type + + /** Calls [[initialize]] on all the symbols that the scope consists of. + */ + def fullyInitialize(scope: Scope): scope.type + + /** Returns internal flags associated with the symbol. + */ + def flags(symbol: Symbol): FlagSet + + /** A creator for `ThisType` types. + */ + def thisType(sym: Symbol): Type + + /** A creator for `SingleType` types. + */ + def singleType(pre: Type, sym: Symbol): Type + + /** A creator for `SuperType` types. + */ + def superType(thistpe: Type, supertpe: Type): Type + + /** A creator for `ConstantType` types. + */ + def constantType(value: Constant): ConstantType + + /** A creator for `TypeRef` types. + */ + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type + + /** A creator for `RefinedType` types. + */ + def refinedType(parents: List[Type], decls: Scope): RefinedType + + /** A creator for `RefinedType` types. + */ + def refinedType(parents: List[Type], owner: Symbol): Type + + /** A creator for `RefinedType` types. + */ + def refinedType(parents: List[Type], owner: Symbol, decls: Scope): Type + + /** A creator for `RefinedType` types. + */ + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself. + */ + def intersectionType(tps: List[Type]): Type + + /** A creator for intersection type where intersections of a single type are + * replaced by the type itself, and repeated parent classes are merged. + * + * !!! Repeated parent classes are not merged - is this a bug in the + * comment or in the code? + */ + def intersectionType(tps: List[Type], owner: Symbol): Type + + /** A creator for `ClassInfoType` types. + */ + def classInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType + + /** A creator for `MethodType` types. + */ + def methodType(params: List[Symbol], resultType: Type): MethodType + + /** A creator for `NullaryMethodType` types. + */ + def nullaryMethodType(resultType: Type): NullaryMethodType + + /** A creator for type parameterizations that strips empty type parameter lists. + * Use this factory method to indicate the type has kind * (it's a polymorphic value) + * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty). + */ + def polyType(tparams: List[Symbol], tpe: Type): PolyType + + /** A creator for `ExistentialType` types. + */ + def existentialType(quantified: List[Symbol], underlying: Type): ExistentialType + + /** A creator for existential types. This generates: + * + * {{{ + * tpe1 where { tparams } + * }}} + * + * where `tpe1` is the result of extrapolating `tpe` with regard to `tparams`. + * Extrapolating means that type variables in `tparams` occurring + * in covariant positions are replaced by upper bounds, (minus any + * SingletonClass markers), type variables in `tparams` occurring in + * contravariant positions are replaced by upper bounds, provided the + * resulting type is legal with regard to stability, and does not contain + * any type variable in `tparams`. + * + * The abstraction drops all type parameters that are not directly or + * indirectly referenced by type `tpe1`. If there are no remaining type + * parameters, simply returns result type `tpe`. + * @group TypeCreators + */ + def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type + + /** A creator for `AnnotatedType` types. + */ + def annotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType + + /** A creator for `TypeBounds` types. + */ + def typeBounds(lo: Type, hi: Type): TypeBounds + + /** A creator for `BoundedWildcardType` types. + */ + def boundedWildcardType(bounds: TypeBounds): BoundedWildcardType + + /** Syntactic conveniences for additional internal APIs for trees, symbols and types */ + type Decorators <: DecoratorApi + + /** @see [[Decorators]] */ + val decorators: Decorators + + /** @see [[Decorators]] */ + trait DecoratorApi { + /** Extension methods for trees */ + type TreeDecorator[T <: Tree] <: TreeDecoratorApi[T] + + /** @see [[TreeDecorator]] */ + implicit def treeDecorator[T <: Tree](tree: T): TreeDecorator[T] + + /** @see [[TreeDecorator]] */ + class TreeDecoratorApi[T <: Tree](val tree: T) { + /** @see [[internal.freeTerms]] */ + def freeTerms: List[FreeTermSymbol] = internal.freeTerms(tree) + + /** @see [[internal.freeTypes]] */ + def freeTypes: List[FreeTypeSymbol] = internal.freeTypes(tree) + + /** @see [[internal.substituteSymbols]] */ + def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = internal.substituteSymbols(tree, from, to) + + /** @see [[internal.substituteTypes]] */ + def substituteTypes(from: List[Symbol], to: List[Type]): Tree = internal.substituteTypes(tree, from, to) + + /** @see [[internal.substituteThis]] */ + def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to) + } + + /** Extension methods for symbols */ + type SymbolDecorator[T <: Symbol] <: SymbolDecoratorApi[T] + + /** @see [[SymbolDecorator]] */ + implicit def symbolDecorator[T <: Symbol](symbol: T): SymbolDecorator[T] + + /** @see [[SymbolDecorator]] */ + class SymbolDecoratorApi[T <: Symbol](val symbol: T) { + /** @see [[internal.isFreeTerm]] */ + def isFreeTerm: Boolean = internal.isFreeTerm(symbol) + + /** @see [[internal.asFreeTerm]] */ + def asFreeTerm: FreeTermSymbol = internal.asFreeTerm(symbol) + + /** @see [[internal.isFreeType]] */ + def isFreeType: Boolean = internal.isFreeType(symbol) + + /** @see [[internal.asFreeType]] */ + def asFreeType: FreeTypeSymbol = internal.asFreeType(symbol) + + /** @see [[internal.newTermSymbol]] */ + def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = internal.newTermSymbol(symbol, name, pos, flags) + + /** @see [[internal.newModuleAndClassSymbol]] */ + def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = internal.newModuleAndClassSymbol(symbol, name, pos, flags) + + /** @see [[internal.newMethodSymbol]] */ + def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol = internal.newMethodSymbol(symbol, name, pos, flags) + + /** @see [[internal.newTypeSymbol]] */ + def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = internal.newTypeSymbol(symbol, name, pos, flags) + + /** @see [[internal.newClassSymbol]] */ + def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = internal.newClassSymbol(symbol, name, pos, flags) + + /** @see [[internal.isErroneous]] */ + def isErroneous: Boolean = internal.isErroneous(symbol) + + /** @see [[internal.isSkolem]] */ + def isSkolem: Boolean = internal.isSkolem(symbol) + + /** @see [[internal.deSkolemize]] */ + def deSkolemize: Symbol = internal.deSkolemize(symbol) + + /** @see [[internal.initialize]] */ + def initialize: T = internal.initialize(symbol) + + /** @see [[internal.fullyInitialize]] */ + def fullyInitialize: T = internal.fullyInitialize(symbol) + + /** @see [[internal.flags]] */ + def flags: FlagSet = internal.flags(symbol) + } + + /** Extension methods for types */ + type TypeDecorator[T <: Type] <: TypeDecoratorApi[T] + + /** @see [[TypeDecorator]] */ + implicit def typeDecorator[T <: Type](tp: T): TypeDecorator[T] + + /** @see [[TypeDecorator]] */ + implicit class TypeDecoratorApi[T <: Type](val tp: T) { + /** @see [[internal.fullyInitialize]] */ + def fullyInitialize: T = internal.fullyInitialize(tp) + } + } + } + + /** This is an internal implementation class. + * @group Internal + */ + // this API abstracts away the functionality necessary for reification and quasiquotes + // it's too gimmicky and unstructured to be exposed directly in the universe + // but we need it in a publicly available place for reification to work + trait ReificationSupportApi { + /** Selects type symbol with given simple name `name` from the defined members of `owner`. + */ + def selectType(owner: Symbol, name: String): TypeSymbol + + /** Selects term symbol with given name and type from the defined members of prefix type + */ + def selectTerm(owner: Symbol, name: String): TermSymbol + + /** Selects overloaded method symbol with given name and index + */ + def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol + + /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has + * the current symbol as its owner. + */ + def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol + + def newScopeWith(elems: Symbol*): Scope + + /** Create a fresh free term symbol. + * @param name the name of the free variable + * @param value the value of the free variable at runtime + * @param flags (optional) flags of the free variable + * @param origin debug information that tells where this symbol comes from + */ + def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol + + /** Create a fresh free type symbol. + * @param name the name of the free variable + * @param flags (optional) flags of the free variable + * @param origin debug information that tells where this symbol comes from + */ + def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol + + /** Set symbol's type signature to given type. + * @return the symbol itself + */ + def setInfo[S <: Symbol](sym: S, tpe: Type): S + + /** Set symbol's annotations to given annotations `annots`. + */ + def setAnnotations[S <: Symbol](sym: S, annots: List[Annotation]): S + + def mkThis(sym: Symbol): Tree + + def mkSelect(qualifier: Tree, sym: Symbol): Select + + def mkIdent(sym: Symbol): Ident + + def mkTypeTree(tp: Type): TypeTree + + def ThisType(sym: Symbol): Type + + def SingleType(pre: Type, sym: Symbol): Type + + def SuperType(thistpe: Type, supertpe: Type): Type + + def ConstantType(value: Constant): ConstantType + + def TypeRef(pre: Type, sym: Symbol, args: List[Type]): Type + + def RefinedType(parents: List[Type], decls: Scope, typeSymbol: Symbol): RefinedType + + def ClassInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType + + def MethodType(params: List[Symbol], resultType: Type): MethodType + + def NullaryMethodType(resultType: Type): NullaryMethodType + + def PolyType(typeParams: List[Symbol], resultType: Type): PolyType + + def ExistentialType(quantified: List[Symbol], underlying: Type): ExistentialType + + def AnnotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType + + def TypeBounds(lo: Type, hi: Type): TypeBounds + + def BoundedWildcardType(bounds: TypeBounds): BoundedWildcardType + + def thisPrefix(sym: Symbol): Type + + def setType[T <: Tree](tree: T, tpe: Type): T + + def setSymbol[T <: Tree](tree: T, sym: Symbol): T + + def toStats(tree: Tree): List[Tree] + + def mkAnnotation(tree: Tree): Tree + + def mkAnnotation(trees: List[Tree]): List[Tree] + + def mkRefineStat(stat: Tree): Tree + + def mkRefineStat(stats: List[Tree]): List[Tree] + + def mkPackageStat(stat: Tree): Tree + + def mkPackageStat(stats: List[Tree]): List[Tree] + + def mkEarlyDef(defn: Tree): Tree + + def mkEarlyDef(defns: List[Tree]): List[Tree] + + def mkRefTree(qual: Tree, sym: Symbol): Tree + + def freshTermName(prefix: String): TermName + + def freshTypeName(prefix: String): TypeName + + val ImplicitParams: ImplicitParamsExtractor + + trait ImplicitParamsExtractor { + def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]] + def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])] + } + + val ScalaDot: ScalaDotExtractor + + trait ScalaDotExtractor { + def apply(name: Name): Tree + def unapply(tree: Tree): Option[Name] + } + + val FlagsRepr: FlagsReprExtractor + + trait FlagsReprExtractor { + def apply(value: Long): FlagSet + def unapply(flags: Long): Some[Long] + } + + val SyntacticTypeApplied: SyntacticTypeAppliedExtractor + + trait SyntacticTypeAppliedExtractor { + def apply(tree: Tree, targs: List[Tree]): Tree + def unapply(tree: Tree): Some[(Tree, List[Tree])] + } + + val SyntacticApplied: SyntacticAppliedExtractor + + trait SyntacticAppliedExtractor { + def apply(tree: Tree, argss: List[List[Tree]]): Tree + def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] + } + + val SyntacticClassDef: SyntacticClassDefExtractor + + trait SyntacticClassDefExtractor { + def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], + constrMods: Modifiers, vparamss: List[List[Tree]], + earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef + def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]], + List[Tree], List[Tree], ValDef, List[Tree])] + } + + val SyntacticTraitDef: SyntacticTraitDefExtractor + + trait SyntacticTraitDefExtractor { + def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], + earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef + def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], + List[Tree], List[Tree], ValDef, List[Tree])] + } + + val SyntacticObjectDef: SyntacticObjectDefExtractor + + trait SyntacticObjectDefExtractor { + def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree], + parents: List[Tree], selfType: Tree, body: List[Tree]): ModuleDef + def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])] + } + + val SyntacticPackageObjectDef: SyntacticPackageObjectDefExtractor + + trait SyntacticPackageObjectDefExtractor { + def apply(name: TermName, earlyDefs: List[Tree], + parents: List[Tree], selfType: Tree, body: List[Tree]): PackageDef + def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] + } + + val SyntacticTuple: SyntacticTupleExtractor + val SyntacticTupleType: SyntacticTupleExtractor + + trait SyntacticTupleExtractor { + def apply(args: List[Tree]): Tree + def unapply(tree: Tree): Option[List[Tree]] + } + + val SyntacticBlock: SyntacticBlockExtractor + + trait SyntacticBlockExtractor { + def apply(stats: List[Tree]): Tree + def unapply(tree: Tree): Option[List[Tree]] + } + + val SyntacticNew: SyntacticNewExtractor + + trait SyntacticNewExtractor { + def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree + def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] + } + + val SyntacticFunctionType: SyntacticFunctionTypeExtractor + + trait SyntacticFunctionTypeExtractor { + def apply(argtpes: List[Tree], restpe: Tree): Tree + def unapply(tree: Tree): Option[(List[Tree], Tree)] + } + + val SyntacticFunction: SyntacticFunctionExtractor + + trait SyntacticFunctionExtractor { + def apply(params: List[Tree], body: Tree): Function + + def unapply(tree: Function): Option[(List[ValDef], Tree)] + } + + val SyntacticDefDef: SyntacticDefDefExtractor + + trait SyntacticDefDefExtractor { + def apply(mods: Modifiers, name: TermName, tparams: List[Tree], + vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef + + def unapply(tree: Tree): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] + } + + val SyntacticValDef: SyntacticValDefExtractor + val SyntacticVarDef: SyntacticValDefExtractor + + trait SyntacticValDefExtractor { + def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef + def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)] + } + + val SyntacticPatDef: SyntacticPatDefExtractor + + trait SyntacticPatDefExtractor { + def apply(mods: Modifiers, pat: Tree, tpt: Tree, rhs: Tree): List[ValDef] + } + + val SyntacticAssign: SyntacticAssignExtractor + + trait SyntacticAssignExtractor { + def apply(lhs: Tree, rhs: Tree): Tree + def unapply(tree: Tree): Option[(Tree, Tree)] + } + + val SyntacticValFrom: SyntacticValFromExtractor + + trait SyntacticValFromExtractor { + def apply(pat: Tree, rhs: Tree): Tree + def unapply(tree: Tree): Option[(Tree, Tree)] + } + + val SyntacticValEq: SyntacticValEqExtractor + + trait SyntacticValEqExtractor { + def apply(pat: Tree, rhs: Tree): Tree + def unapply(tree: Tree): Option[(Tree, Tree)] + } + + val SyntacticFilter: SyntacticFilterExtractor + + trait SyntacticFilterExtractor { + def apply(test: Tree): Tree + def unapply(tree: Tree): Option[(Tree)] + } + + val SyntacticEmptyTypeTree: SyntacticEmptyTypeTreeExtractor + + trait SyntacticEmptyTypeTreeExtractor { + def apply(): TypeTree + def unapply(tt: TypeTree): Boolean + } + + val SyntacticFor: SyntacticForExtractor + val SyntacticForYield: SyntacticForExtractor + + trait SyntacticForExtractor { + def apply(enums: List[Tree], body: Tree): Tree + def unapply(tree: Tree): Option[(List[Tree], Tree)] + } + + def UnliftListElementwise[T](unliftable: Unliftable[T]): UnliftListElementwise[T] + trait UnliftListElementwise[T] { + def unapply(lst: List[Tree]): Option[List[T]] + } + + def UnliftListOfListsElementwise[T](unliftable: Unliftable[T]): UnliftListOfListsElementwise[T] + trait UnliftListOfListsElementwise[T] { + def unapply(lst: List[List[Tree]]): Option[List[List[T]]] + } + + val SyntacticMatch: SyntacticMatchExtractor + trait SyntacticMatchExtractor { + def apply(selector: Tree, cases: List[Tree]): Match + def unapply(tree: Match): Option[(Tree, List[CaseDef])] + } + + val SyntacticTry: SyntacticTryExtractor + trait SyntacticTryExtractor { + def apply(block: Tree, catches: List[Tree], finalizer: Tree): Try + def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] + } + + val SyntacticIdent: SyntacticIdentExtractor + trait SyntacticIdentExtractor { + def apply(name: Name, isBackquoted: Boolean = false): Ident + def unapply(tree: Ident): Option[(Name, Boolean)] + } + + val SyntacticImport: SyntacticImportExtractor + trait SyntacticImportExtractor { + def apply(expr: Tree, selectors: List[Tree]): Import + def unapply(imp: Import): Some[(Tree, List[Tree])] + } + } + + @deprecated("Use `internal.reificationSupport` instead", "2.11.0") + val build: ReificationSupportApi + + /** This trait provides support for importers, a facility to migrate reflection artifacts between universes. + * ''Note: this trait should typically be used only rarely.'' + * + * Reflection artifacts, such as [[scala.reflect.api.Symbols Symbols]] and [[scala.reflect.api.Types Types]], + * are contained in [[scala.reflect.api.Universe Universe]]s. Typically all processing happens + * within a single `Universe` (e.g. a compile-time macro `Universe` or a runtime reflection `Universe`), but sometimes + * there is a need to migrate artifacts from one `Universe` to another. For example, runtime compilation works by + * importing runtime reflection trees into a runtime compiler universe, compiling the importees and exporting the + * result back. + * + * Reflection artifacts are firmly grounded in their `Universe`s, which is reflected by the fact that types of artifacts + * from different universes are not compatible. By using `Importer`s, however, they be imported from one universe + * into another. For example, to import `foo.bar.Baz` from the source `Universe` to the target `Universe`, + * an importer will first check whether the entire owner chain exists in the target `Universe`. + * If it does, then nothing else will be done. Otherwise, the importer will recreate the entire owner chain + * and will import the corresponding type signatures into the target `Universe`. + * + * Since importers match `Symbol` tables of the source and the target `Universe`s using plain string names, + * it is programmer's responsibility to make sure that imports don't distort semantics, e.g., that + * `foo.bar.Baz` in the source `Universe` means the same that `foo.bar.Baz` does in the target `Universe`. + * + * === Example === + * + * Here's how one might implement a macro that performs compile-time evaluation of its argument + * by using a runtime compiler to compile and evaluate a tree that belongs to a compile-time compiler: + * + * {{{ + * def staticEval[T](x: T) = macro staticEval[T] + * + * def staticEval[T](c: scala.reflect.macros.blackbox.Context)(x: c.Expr[T]) = { + * // creates a runtime reflection universe to host runtime compilation + * import scala.reflect.runtime.{universe => ru} + * val mirror = ru.runtimeMirror(c.libraryClassLoader) + * import scala.tools.reflect.ToolBox + * val toolBox = mirror.mkToolBox() + * + * // runtime reflection universe and compile-time macro universe are different + * // therefore an importer is needed to bridge them + * // currently mkImporter requires a cast to correctly assign the path-dependent types + * val importer0 = ru.internal.mkImporter(c.universe) + * val importer = importer0.asInstanceOf[ru.internal.Importer { val from: c.universe.type }] + * + * // the created importer is used to turn a compiler tree into a runtime compiler tree + * // both compilers use the same classpath, so semantics remains intact + * val imported = importer.importTree(tree) + * + * // after the tree is imported, it can be evaluated as usual + * val tree = toolBox.untypecheck(imported.duplicate) + * val valueOfX = toolBox.eval(imported).asInstanceOf[T] + * ... + * } + * }}} + * + * @group Internal + */ + // SI-6241: move importers to a mirror + trait Importer { + /** The source universe of reflection artifacts that will be processed. + * The target universe is universe that created this importer with `mkImporter`. + */ + val from: Universe + + /** An importer that works in reverse direction, namely: + * imports reflection artifacts from the current universe to the universe specified in `from`. + */ + val reverse: from.Importer { val from: self.type } + + /** In the current universe, locates or creates a symbol that corresponds to the provided symbol in the source universe. + * If necessary imports the owner chain, companions, type signature, annotations and attachments. + */ + def importSymbol(sym: from.Symbol): Symbol + + /** In the current universe, locates or creates a type that corresponds to the provided type in the source universe. + * If necessary imports the underlying symbols, annotations, scopes and trees. + */ + def importType(tpe: from.Type): Type + + /** In the current universe, creates a tree that corresponds to the provided tree in the source universe. + * If necessary imports the underlying symbols, types and attachments. + */ + def importTree(tree: from.Tree): Tree + + /** In the current universe, creates a position that corresponds to the provided position in the source universe. + */ + def importPosition(pos: from.Position): Position + } + + @deprecated("Use `internal.createImporter` instead", "2.11.0") + def mkImporter(from0: Universe): Importer { val from: from0.type } = internal.createImporter(from0) + + /** Marks underlying reference to id as boxed. + * + * <b>Precondition:<\b> id must refer to a captured variable + * A reference such marked will refer to the boxed entity, no dereferencing + * with `.elem` is done on it. + * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. + * It is eliminated in LambdaLift, where the boxing conversion takes place. + * @group Internal + * @template + */ + type ReferenceToBoxed >: Null <: ReferenceToBoxedApi with TermTree + + /** The constructor/extractor for `ReferenceToBoxed` instances. + * @group Internal + */ + val ReferenceToBoxed: ReferenceToBoxedExtractor + + /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`. + * This AST node does not have direct correspondence to Scala code, + * and is emitted by macros to reference capture vars directly without going through `elem`. + * + * For example: + * + * var x = ... + * fun { x } + * + * Will emit: + * + * Ident(x) + * + * Which gets transformed to: + * + * Select(Ident(x), "elem") + * + * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed. + * @group Internal + */ + abstract class ReferenceToBoxedExtractor { + def apply(ident: Ident): ReferenceToBoxed + def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident] + } + + /** The API that all references support + * @group Internal + */ + trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed => + /** The underlying reference. */ + def ident: Tree + } + + /** Tag that preserves the identity of `ReferenceToBoxed` in the face of erasure. + * Can be used for pattern matching, instance tests, serialization and the like. + * @group Internal + */ + implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed] + + /** The type of free terms introduced by reification. + * @group Internal + * @template + */ + type FreeTermSymbol >: Null <: FreeTermSymbolApi with TermSymbol + + /** The API of free term symbols. + * The main source of information about symbols is the [[Symbols]] page. + * + * $SYMACCESSORS + * @group Internal + */ + trait FreeTermSymbolApi extends TermSymbolApi { this: FreeTermSymbol => + /** The place where this symbol has been spawned + * + * @group FreeTerm + */ + def origin: String + + /** The valus this symbol refers to + * + * @group FreeTerm + */ + def value: Any + } + + /** Tag that preserves the identity of `FreeTermSymbol` in the face of erasure. + * Can be used for pattern matching, instance tests, serialization and the like. + * @group Internal + */ + implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol] + + /** The type of free types introduced by reification. + * @group Internal + * @template + */ + type FreeTypeSymbol >: Null <: FreeTypeSymbolApi with TypeSymbol + + /** The API of free type symbols. + * The main source of information about symbols is the [[Symbols]] page. + * + * $SYMACCESSORS + * @group Internal + */ + trait FreeTypeSymbolApi extends TypeSymbolApi { this: FreeTypeSymbol => + /** The place where this symbol has been spawned + * + * @group FreeType + */ + def origin: String + } + + /** Tag that preserves the identity of `FreeTermSymbol` in the face of erasure. + * Can be used for pattern matching, instance tests, serialization and the like. + * @group Internal + */ + implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol] + + /** Provides enrichments to ensure source compatibility between Scala 2.10 and Scala 2.11. + * If in your reflective program for Scala 2.10 you've used something that's now become an internal API, + * a single `compat._` import will fix things for you. + * @group Internal + */ + val compat: Compat + + /** @see [[compat]] + * @group Internal + */ + type Compat <: CompatApi + + /** Presence of an implicit value of this type in scope + * indicates that source compatibility with Scala 2.10 has been enabled. + * @group Internal + */ + @scala.annotation.implicitNotFound("This method has been removed from the public API. Import compat._ or migrate away.") + class CompatToken + + /** @see [[compat]] + * @group Internal + */ + trait CompatApi { + /** @see [[CompatToken]] */ + implicit val token = new CompatToken + + /** @see [[InternalApi.typeTagToManifest]] */ + @deprecated("Use `internal.typeTagToManifest` instead", "2.11.0") + def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] = + internal.typeTagToManifest(mirror, tag) + + /** @see [[InternalApi.manifestToTypeTag]] */ + @deprecated("Use `internal.manifestToTypeTag` instead", "2.11.0") + def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] = + internal.manifestToTypeTag(mirror, manifest) + + /** @see [[InternalApi.newScopeWith]] */ + @deprecated("Use `internal.newScopeWith` instead", "2.11.0") + def newScopeWith(elems: Symbol*): Scope = + internal.newScopeWith(elems: _*) + + /** Scala 2.10 compatibility enrichments for Tree. */ + implicit class CompatibleTree(tree: Tree) { + /** @see [[InternalApi.freeTerms]] */ + @deprecated("Use `internal.freeTerms` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def freeTerms: List[FreeTermSymbol] = internal.freeTerms(tree) + + /** @see [[InternalApi.freeTypes]] */ + @deprecated("Use `internal.freeTerms` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def freeTypes: List[FreeTypeSymbol] = internal.freeTypes(tree) + + /** @see [[InternalApi.substituteSymbols]] */ + @deprecated("Use `internal.substituteSymbols` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = internal.substituteSymbols(tree, from, to) + + /** @see [[InternalApi.substituteTypes]] */ + @deprecated("Use `internal.substituteTypes` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def substituteTypes(from: List[Symbol], to: List[Type]): Tree = internal.substituteTypes(tree, from, to) + + /** @see [[InternalApi.substituteThis]] */ + @deprecated("Use `internal.substituteThis` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to) + } + + /** Scala 2.10 compatibility enrichments for Tree. */ + implicit class CompatibleSymbol(symbol: Symbol) { + @deprecated("This API is unreliable. Use `isPrivateThis` or `isProtectedThis` instead", "2.11.0") + def isLocal: Boolean = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol].isLocal + + @deprecated("This API is unreliable. Use `overrides.nonEmpty` instead", "2.11.0") + def isOverride: Boolean = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol].isOverride + + /** @see [[InternalApi.isFreeTerm]] */ + @deprecated("Use `internal.isFreeTerm` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def isFreeTerm: Boolean = internal.isFreeTerm(symbol) + + /** @see [[InternalApi.asFreeTerm]] */ + @deprecated("Use `internal.asFreeTerm` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def asFreeTerm: FreeTermSymbol = internal.asFreeTerm(symbol) + + /** @see [[InternalApi.isFreeType]] */ + @deprecated("Use `internal.isFreeType` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def isFreeType: Boolean = internal.isFreeType(symbol) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.asFreeType` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def asFreeType: FreeTypeSymbol = internal.asFreeType(symbol) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.newTermSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = internal.newTermSymbol(symbol, name, pos, flags) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.newModuleAndClassSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = internal.newModuleAndClassSymbol(symbol, name, pos, flags) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.newMethodSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol = internal.newMethodSymbol(symbol, name, pos, flags) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.newTypeSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = internal.newTypeSymbol(symbol, name, pos, flags) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.newClassSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = internal.newClassSymbol(symbol, name, pos, flags) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.isErroneous` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def isErroneous: Boolean = internal.isErroneous(symbol) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.isSkolem` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def isSkolem: Boolean = internal.isSkolem(symbol) + + /** @see [[InternalApi.asFreeType]] */ + @deprecated("Use `internal.deSkolemize` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def deSkolemize: Symbol = internal.deSkolemize(symbol) + } + + /** @see [[InternalApi.singleType]] */ + @deprecated("Use `internal.singleType` instead", "2.11.0") + def singleType(pre: Type, sym: Symbol): Type = internal.singleType(pre, sym) + + /** @see [[InternalApi.refinedType]] */ + @deprecated("Use `internal.refinedType` instead", "2.11.0") + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type = internal.refinedType(parents, owner, decls, pos) + + /** @see [[InternalApi.refinedType]] */ + @deprecated("Use `internal.refinedType` instead", "2.11.0") + def refinedType(parents: List[Type], owner: Symbol): Type = internal.refinedType(parents, owner) + + /** @see [[InternalApi.typeRef]] */ + @deprecated("Use `internal.typeRef` instead", "2.11.0") + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = internal.typeRef(pre, sym, args) + + /** @see [[InternalApi.intersectionType]] */ + @deprecated("Use `internal.intersectionType` instead", "2.11.0") + def intersectionType(tps: List[Type]): Type = internal.intersectionType(tps) + + /** @see [[InternalApi.intersectionType]] */ + @deprecated("Use `internal.intersectionType` instead", "2.11.0") + def intersectionType(tps: List[Type], owner: Symbol): Type = internal.intersectionType(tps, owner) + + /** @see [[InternalApi.polyType]] */ + @deprecated("Use `internal.polyType` instead", "2.11.0") + def polyType(tparams: List[Symbol], tpe: Type): Type = internal.polyType(tparams, tpe) + + /** @see [[InternalApi.existentialAbstraction]] */ + @deprecated("Use `internal.existentialAbstraction` instead", "2.11.0") + def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type = internal.existentialAbstraction(tparams, tpe0) + } +} diff --git a/src/reflect/scala/reflect/api/JavaMirrors.scala b/src/reflect/scala/reflect/api/JavaMirrors.scala deleted file mode 100644 index 23abc23eb9..0000000000 --- a/src/reflect/scala/reflect/api/JavaMirrors.scala +++ /dev/null @@ -1,57 +0,0 @@ -package scala -package reflect -package api - -/** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> - * - * A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders. - * - * This refinement equips mirrors with reflection capabilities for the JVM. `JavaMirror` can - * convert Scala reflection artifacts (symbols and types) into Java reflection artifacts (classes) - * and vice versa. It can also perform reflective invocations (getting/setting field values, - * calling methods, etc). - * - * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the - * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]] - * - * @groupname JavaMirrors Java Mirrors - * @group ReflectionAPI - */ -trait JavaMirrors { self: JavaUniverse => - - /** In runtime reflection universes, runtime representation of a class is `java.lang.Class`. - * @group JavaMirrors - */ - type RuntimeClass = java.lang.Class[_] - - /** In runtime reflection universes, mirrors are `JavaMirrors`. - * @group JavaMirrors - */ - override type Mirror >: Null <: JavaMirror - - /** A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders. - * - * With this upgrade, mirrors become capable of converting Scala reflection artifacts (symbols and types) - * into Java reflection artifacts (classes) and vice versa. Consequently, refined mirrors - * become capable of performing reflective invocations (getting/setting field values, calling methods, etc). - * - * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the - * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]] - * - * @group JavaMirrors - */ - trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror { - val classLoader: ClassLoader - override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}" - } - - /** Creates a runtime reflection mirror from a JVM classloader. - * - * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the - * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]] - * - * @group JavaMirrors - */ - def runtimeMirror(cl: ClassLoader): Mirror -} diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala index df5e0699a5..88107ea117 100644 --- a/src/reflect/scala/reflect/api/JavaUniverse.scala +++ b/src/reflect/scala/reflect/api/JavaUniverse.scala @@ -3,12 +3,14 @@ package reflect package api /** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> + * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> * - * A refinement of [[scala.reflect.api.Universe]] for runtime reflection using JVM classloaders. + * A refinement of [[scala.reflect.api.Universe]] for runtime reflection using JVM classloaders. * - * The refinement consists of an upgrade to the mirror API, which gets extended from [[scala.reflect.api.Mirror]] - * to [[scala.reflect.api.JavaMirrors#JavaMirror]]. + * This refinement equips mirrors with reflection capabilities for the JVM. `JavaMirror` can + * convert Scala reflection artifacts (symbols and types) into Java reflection artifacts (classes) + * and vice versa. It can also perform reflective invocations (getting/setting field values, + * calling methods, etc). * * See the [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]] for details on how to use runtime reflection. * @@ -17,31 +19,41 @@ package api * * @contentDiagram hideNodes "*Api" */ -trait JavaUniverse extends Universe with JavaMirrors { self => +trait JavaUniverse extends Universe { self => - /* @group JavaUniverse */ - override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: Universe # TypeTag[T]): Manifest[T] = { - // SI-6239: make this conversion more precise - val mirror = mirror0.asInstanceOf[Mirror] - val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe) - Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]] + /** In runtime reflection universes, runtime representation of a class is `java.lang.Class`. + * @group JavaMirrors + */ + type RuntimeClass = java.lang.Class[_] + implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass]) + + /** In runtime reflection universes, mirrors are `JavaMirrors`. + * @group JavaMirrors + */ + override type Mirror >: Null <: JavaMirror + + /** A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders. + * + * With this upgrade, mirrors become capable of converting Scala reflection artifacts (symbols and types) + * into Java reflection artifacts (classes) and vice versa. Consequently, refined mirrors + * become capable of performing reflective invocations (getting/setting field values, calling methods, etc). + * + * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the + * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]] + * + * @group JavaMirrors + */ + trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror { + val classLoader: ClassLoader + override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}" } - /* @group JavaUniverse */ - override def manifestToTypeTag[T](mirror0: Any, manifest: Manifest[T]): Universe # TypeTag[T] = - TypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator { - def apply[U <: Universe with Singleton](mirror: scala.reflect.api.Mirror[U]): U # Type = { - mirror.universe match { - case ju: JavaUniverse => - val jm = mirror.asInstanceOf[ju.Mirror] - val sym = jm.classSymbol(manifest.runtimeClass) - val 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 - } - } - }) -} + /** Creates a runtime reflection mirror from a JVM classloader. + * + * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the + * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]] + * + * @group JavaMirrors + */ + def runtimeMirror(cl: ClassLoader): Mirror +}
\ No newline at end of file diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala index e0219c9074..da3afd89ff 100644 --- a/src/reflect/scala/reflect/api/Mirror.scala +++ b/src/reflect/scala/reflect/api/Mirror.scala @@ -58,7 +58,7 @@ abstract class Mirror[U <: Universe with Singleton] { * scala> cm.staticPackage("scala") * res2: scala.reflect.runtime.universe.ModuleSymbol = package scala * - * scala> res2.moduleClass.typeSignature member newTypeName("List") + * scala> res2.moduleClass.info member newTypeName("List") * res3: scala.reflect.runtime.universe.Symbol = type List * * scala> res3.fullName @@ -79,11 +79,10 @@ abstract class Mirror[U <: Universe with Singleton] { * } * * staticClass("foo.B") will resolve to the symbol corresponding to the class B declared in the package foo, and - * staticClass("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this - * fully qualified class name is written inside any package in a Scala program). + * staticClass("foo.A") will throw a ScalaReflectionException. * * In the example above, to load a symbol that corresponds to the class B declared in the object foo, - * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass. + * use staticModule("foo") to load the module symbol and then navigate info.members of its moduleClass. * @group Mirror */ def staticClass(fullName: String): U#ClassSymbol @@ -106,11 +105,10 @@ abstract class Mirror[U <: Universe with Singleton] { * } * * staticModule("foo.B") will resolve to the symbol corresponding to the object B declared in the package foo, and - * staticModule("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this - * fully qualified class name is written inside any package in a Scala program). + * staticModule("foo.A") will throw a ScalaReflectionException * * In the example above, to load a symbol that corresponds to the object B declared in the object foo, - * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass. + * use staticModule("foo") to load the module symbol and then navigate info.members of its moduleClass. * @group Mirror */ def staticModule(fullName: String): U#ModuleSymbol diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala index f11b9a5c55..ec420d184c 100644 --- a/src/reflect/scala/reflect/api/Mirrors.scala +++ b/src/reflect/scala/reflect/api/Mirrors.scala @@ -62,7 +62,7 @@ package api * The entry point to `Mirror`s for use at runtime is via `ru.runtimeMirror(<classloader>)`, where * `ru` is [[scala.reflect.runtime.universe]]. * - * The result of a [[scala.reflect.api.JavaMirrors#runtimeMirror]] call is a classloader mirror, + * The result of a [[scala.reflect.api.JavaUniverse#runtimeMirror]] call is a classloader mirror, * of type [[scala.reflect.api.Mirrors#ReflectiveMirror]], which can load symbols by names as * discussed above (in the “Compile-time” section). * @@ -225,7 +225,12 @@ trait Mirrors { self: Universe => /** Abstracts the runtime representation of a class on the underlying platform. * @group Mirrors */ - type RuntimeClass >: Null + type RuntimeClass >: Null <: AnyRef + + /** Has no special methods. Is here to provides erased identity for `RuntimeClass`. + * @group API + */ + trait RuntimeClassApi // todo. an improvement might be having mirrors reproduce the structure of the reflection domain // e.g. a ClassMirror could also have a list of fields, methods, constructors and so on @@ -255,8 +260,8 @@ trait Mirrors { self: Universe => * Note also that only accessor MethodMirrors, but not FieldMirrors will accurately reflect overriding behavior. * * To get a field symbol by the name of the field you would like to reflect, - * use `<this mirror>.symbol.typeSignature.member(TermName(<name of the field>)).asTerm.accessed`. - * For further information about member lookup refer to `Symbol.typeSignature`. + * use `<this mirror>.symbol.info.member(TermName(<name of the field>)).asTerm.accessed`. + * For further information about member lookup refer to `Symbol.info`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). * It must be a member (declared or inherited) of the class of the instance underlying this mirror. @@ -275,8 +280,8 @@ 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(TermName(<name of the method>)).asMethod`. - * For further information about member lookup refer to `Symbol.typeSignature`. + * use `<this mirror>.symbol.info.member(TermName(<name of the method>)).asMethod`. + * For further information about member lookup refer to `Symbol.info`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). * It must be a member (declared or inherited) of the instance underlying this mirror. @@ -287,8 +292,8 @@ 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>)).asClass`. - * For further information about member lookup refer to `Symbol.typeSignature`. + * use `<this mirror>.symbol.info.member(newTypeName(<name of the class>)).asClass`. + * For further information about member lookup refer to `Symbol.info`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). * It must be a member (declared or inherited) of the instance underlying this mirror. @@ -299,8 +304,8 @@ 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(TermName(<name of the object>)).asModule`. - * For further information about member lookup refer to `Symbol.typeSignature`. + * use `<this mirror>.symbol.info.member(TermName(<name of the object>)).asModule`. + * For further information about member lookup refer to `Symbol.info`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). * It must be a member (declared or inherited) of the instance underlying this mirror. @@ -432,8 +437,8 @@ 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).asMethod`. - * For further information about member lookup refer to `Symbol.typeSignature`. + * use `<this mirror>.symbol.info.member(termNames.CONSTRUCTOR).asMethod`. + * For further information about member lookup refer to `Symbol.info`. * * The input symbol can be either private or non-private (Scala reflection transparently deals with visibility). * It must be a member (declared or inherited) of the class underlying this mirror. @@ -499,7 +504,7 @@ trait Mirrors { self: Universe => /** A class symbol for the specified runtime class. * @return The class symbol for the runtime class in the current class loader. * @throws java.lang.ClassNotFoundException if no class with that name exists - * @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists + * @throws scala.reflect.ScalaReflectionException if no corresponding symbol exists * to do: throws anything else? */ def classSymbol(rtcls: RuntimeClass): ClassSymbol @@ -507,7 +512,7 @@ trait Mirrors { self: Universe => /** A module symbol for the specified runtime class. * @return The module symbol for the runtime class in the current class loader. * @throws java.lang.ClassNotFoundException if no class with that name exists - * @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists + * @throws scala.reflect.ScalaReflectionException if no corresponding symbol exists * to do: throws anything else? */ def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala index 87d7f9fd8e..fe5f47c25d 100644 --- a/src/reflect/scala/reflect/api/Names.scala +++ b/src/reflect/scala/reflect/api/Names.scala @@ -33,28 +33,40 @@ trait Names { * Enables an alternative notation `"map": TermName` as opposed to `newTermName("map")`. * @group Names */ + @deprecated("Use explicit `TermName(s)` instead", "2.11.0") implicit def stringToTermName(s: String): TermName = TermName(s) /** An implicit conversion from String to TypeName. * Enables an alternative notation `"List": TypeName` as opposed to `newTypeName("List")`. * @group Names */ + @deprecated("Use explicit `TypeName(s)` instead", "2.11.0") implicit def stringToTypeName(s: String): TypeName = TypeName(s) /** The abstract type of names. * @group Names */ - type Name >: Null <: NameApi + type Name >: Null <: AnyRef with NameApi /** The abstract type of names representing terms. * @group Names */ - type TypeName >: Null <: Name + type TypeName >: Null <: TypeNameApi with Name + + /** Has no special methods. Is here to provides erased identity for `TypeName`. + * @group API + */ + trait TypeNameApi /** The abstract type of names representing types. * @group Names */ - type TermName >: Null <: Name + type TermName >: Null <: TermNameApi with Name + + /** Has no special methods. Is here to provides erased identity for `TermName`. + * @group API + */ + trait TermNameApi /** The API of Name instances. * @group API @@ -75,11 +87,13 @@ trait Names { /** Replaces all occurrences of \$op_names in this name by corresponding operator symbols. * Example: `foo_\$plus\$eq` becomes `foo_+=` */ + @deprecated("Use `decodedName.toString` instead", "2.11.0") def decoded: String /** Replaces all occurrences of operator symbols in this name by corresponding \$op_names. * Example: `foo_+=` becomes `foo_\$plus\$eq`. */ + @deprecated("Use `encodedName.toString` instead", "2.11.0") def encoded: String /** The decoded name, still represented as a name. diff --git a/src/reflect/scala/reflect/api/Position.scala b/src/reflect/scala/reflect/api/Position.scala index 2019e2f1d9..9d1b7c3812 100644 --- a/src/reflect/scala/reflect/api/Position.scala +++ b/src/reflect/scala/reflect/api/Position.scala @@ -5,14 +5,48 @@ package api import scala.reflect.macros.Attachments /** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> + * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> * - * Position tracks the origin of [[Symbols#Symbol symbols]] and [[Trees#Tree tree nodes]]. They are commonly used when - * displaying warnings and errors, to indicate the incorrect point in the program. + * Position tracks the origin of [[Symbols#Symbol symbols]] and [[Trees#Tree tree nodes]]. They are commonly used when + * displaying warnings and errors, to indicate the incorrect point in the program. * - * <b>Please note that this trait may be refactored in future versions of the Scala reflection API.</b> + * Every non-empty position refers to a SourceFile and three character + * offsets within it: start, end, and point. The point is where the ^ belongs when + * issuing an error message, usually a Name. A range position can be designated + * as transparent, which excuses it from maintaining the invariants to follow. If + * a transparent position has opaque children, those are considered as if they were + * the direct children of the transparent position's parent. * - * For more information about `Position`s, see the [[http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html Reflection Guide: Annotations, Names, Scopes, and More]] + * Note: some of these invariants actually apply to the trees which carry + * the positions, but they are phrased as if the positions themselves were + * the parent/children for conciseness. + * + * Invariant 1: in a focused/offset position, start == point == end + * Invariant 2: in a range position, start <= point < end + * Invariant 3: an offset position never has a child with a range position + * Invariant 4: every range position child of a range position parent is contained within its parent + * Invariant 5: opaque range position siblings overlap at most at a single point + * + * The following tests are useful on positions: + * + * pos.isDefined true if position is not an UndefinedPosition (those being NoPosition and FakePos) + * pos.isRange true if position is a range (opaque or transparent) which implies start < end + * pos.isOpaqueRange true if position is an opaque range + * + * The following accessor methods are provided - an exception will be thrown if + * point/start/end are attempted on an UndefinedPosition. + * + * pos.source The source file of the position, or NoSourceFile if unavailable + * pos.point The offset of the point + * pos.start The (inclusive) start offset, or the point of an offset position + * pos.end The (exclusive) end offset, or the point of an offset position + * + * The following conversion methods are often used: + * + * pos.focus Converts a range position to an offset position focused on the point + * pos.makeTransparent Convert an opaque range into a transparent range + * + * For more information about `Position`s, see the [[http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html Reflection Guide: Annotations, Names, Scopes, and More]] * * @groupname Common Commonly used methods * @group ReflectionAPI @@ -20,23 +54,9 @@ import scala.reflect.macros.Attachments trait Position extends Attachments { /** @inheritdoc */ - type Pos >: Null <: Position - - /** Java file corresponding to the source file of this position. - * - * The return type is `scala.reflect.io.AbstractFile`, which belongs to an experimental part of Scala reflection. - * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined - * and exposed as a part of scala.reflect.api. - * - * @group Common - */ - def source: scala.reflect.internal.util.SourceFile + type Pos >: Null <: AnyRef with Position - /** Is this position neither a NoPosition nor a FakePosition? - * If isDefined is true, offset and source are both defined. - * @group Common - */ - def isDefined: Boolean + ////////////////// POSITION FLAVORS ////////////////// /** Is this position a range position? */ def isRange: Boolean @@ -47,119 +67,141 @@ trait Position extends Attachments { /** Is this position a non-transparent range position? */ def isOpaqueRange: Boolean + /** If this is a range position, the offset position of its point. + * Otherwise the position itself + */ + def focus: Pos + /** If opaque range, make this position transparent. */ def makeTransparent: Pos + ////////////////// POSITION ESSENTIALS ////////////////// + /** The start of the position's range, or the point if not a range position. */ def start: Int - /** The start of the position's range, or point if not a range position. */ - @deprecated("Use `start` instead", "2.11.0") def startOrPoint: Int - /** The point (where the ^ is) of the position, which is easiest to access using the [[line]] and [[column]] values. * The [[lineContent line content]] is also available. * @group Common */ def point: Int - /** The point (where the ^ is) of the position, or else `default` if undefined. + /** The end of the position's range, or the point if not a range position. + */ + def end: Int + + /** Java file corresponding to the source file of this position. + * + * The return type is `scala.reflect.io.AbstractFile`, which belongs to an experimental part of Scala reflection. + * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined + * and exposed as a part of scala.reflect.api. + * * @group Common */ - def pointOrElse(default: Int): Int + def source: scala.reflect.internal.util.SourceFile - /** The end of the position's range, or the point if not a range position. + /** The position indicates a [[column `column`]] and the `line` in the source file. + * @group Common */ - def end: Int + def line: Int - /** The end of the position's range, or point if not a range position. + /** The position indicates a `column` and the [[line `line`]] in the source file. + * @group Common */ - @deprecated("Use `end` instead", "2.11.0") def endOrPoint: Int + def column: Int - /** The same position with a different start value (if a range). + ////////////////// POSITION FACTORIES ////////////////// + + /** Returns a new position with the same attributes, but a different start value (if a range). */ def withStart(off: Int): Pos - /** The same position with a different end value (if a range). + /** Returns a new position with the same attributes, but a different end value (if a range). */ def withEnd(off: Int): Pos - /** The same position with a different point value (if a range or offset). + /** Returns a new position with the same attributes, but a different point value (if a range or offset). */ def withPoint(off: Int): Pos - /** If this is a range, the union with the other range, with the point of this position. - * Otherwise, this position + ////////////////// STUFF ////////////////// + + /** Is this position not a NoPosition? + * If isDefined is true, offset and source are both defined. + * @group Common */ - def union(pos: Pos): Pos + @deprecated("Removed from the public API", "2.11.0") def isDefined: Boolean - /** If this is a range position, the offset position of its point. - * Otherwise the position itself + /** The point (where the ^ is) of the position, or else `default` if undefined. + * @group Common */ - def focus: Pos + @deprecated("Removed from the public API", "2.11.0") def pointOrElse(default: Int): Int + + /** The start of the position's range, or point if not a range position. */ + @deprecated("Removed from the public API", "2.11.0") def startOrPoint: Int + + /** The end of the position's range, or point if not a range position. + */ + @deprecated("Removed from the public API", "2.11.0") def endOrPoint: Int + + /** If this is a range, the union with the other range, with the point of this position. + * Otherwise, this position + */ + @deprecated("Removed from the public API", "2.11.0") def union(pos: Pos): Pos /** If this is a range position, the offset position of its start. * Otherwise the position itself */ - def focusStart: Pos + @deprecated("Removed from the public API", "2.11.0") def focusStart: Pos /** If this is a range position, the offset position of its end. * Otherwise the position itself */ - def focusEnd: Pos + @deprecated("Removed from the public API", "2.11.0") def focusEnd: Pos /** Does this position include the given position `pos`? * This holds if `this` is a range position and its range [start..end] * is the same or covers the range of the given position, which may or may not be a range position. */ - def includes(pos: Pos): Boolean + @deprecated("Removed from the public API", "2.11.0") def includes(pos: Pos): Boolean /** Does this position properly include the given position `pos` ("properly" meaning their * ranges are not the same)? */ - def properlyIncludes(pos: Pos): Boolean + @deprecated("Removed from the public API", "2.11.0") def properlyIncludes(pos: Pos): Boolean /** Does this position precede that position? * This holds if both positions are defined and the end point of this position * is not larger than the start point of the given position. */ - def precedes(pos: Pos): Boolean + @deprecated("Removed from the public API", "2.11.0") def precedes(pos: Pos): Boolean /** Does this position properly precede the given position `pos` ("properly" meaning their ranges * do not share a common point). */ - def properlyPrecedes(pos: Pos): Boolean + @deprecated("Removed from the public API", "2.11.0") def properlyPrecedes(pos: Pos): Boolean /** Does this position overlap with that position? * This holds if both positions are ranges and there is an interval of * non-zero length that is shared by both position ranges. */ - def overlaps(pos: Pos): Boolean + @deprecated("Removed from the public API", "2.11.0") def overlaps(pos: Pos): Boolean /** Does this position cover the same range as that position? * Holds only if both position are ranges */ - def sameRange(pos: Pos): Boolean - - /** The position indicates a [[column `column`]] and the `line` in the source file. - * @group Common - */ - def line: Int - - /** The position indicates a `column` and the [[line `line`]] in the source file. - * @group Common - */ - def column: Int + @deprecated("Removed from the public API", "2.11.0") def sameRange(pos: Pos): Boolean /** Convert this to a position around `point` that spans a single source line */ - def toSingleLine: Pos + @deprecated("Removed from the public API", "2.11.0") def toSingleLine: Pos /** The content of the line this Position refers to. * @group Common */ - def lineContent: String + @deprecated("Removed from the public API", "2.11.0") def lineContent: String /** Show a textual representation of the position. */ - def show: String + @deprecated("Use `universe.show(position)` instead", "2.11.0") def show: String } diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala index 8ad46418f8..63ad605656 100644 --- a/src/reflect/scala/reflect/api/Positions.scala +++ b/src/reflect/scala/reflect/api/Positions.scala @@ -19,7 +19,8 @@ trait Positions { * The main documentation entry about positions is located at [[scala.reflect.api.Position]]. * @group Positions */ - type Position >: Null <: scala.reflect.api.Position { type Pos = Position } + type Position >: Null <: AnyRef with scala.reflect.api.Position { type Pos = Position } + /** A special "missing" position. * @group Positions */ diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala index 637fcd782e..b262fdce68 100644 --- a/src/reflect/scala/reflect/api/Printers.scala +++ b/src/reflect/scala/reflect/api/Printers.scala @@ -252,8 +252,23 @@ trait Printers { self: Universe => */ def show(flags: FlagSet): String + /** Renders a prettified representation of a position. + * @group Printers + */ + def show(position: Position): String + /** Renders internal structure of a flag set. * @group Printers */ def showRaw(flags: FlagSet): String = flags.toString + + /** Renders internal structure of a position. + * @group Printers + */ + def showRaw(position: Position): String = position.toString + + /** Renders a string that represents a declaration of this symbol written in Scala. + * @group Printers + */ + def showDecl(sym: Symbol): String } diff --git a/src/reflect/scala/reflect/api/Scopes.scala b/src/reflect/scala/reflect/api/Scopes.scala index 2eb477f652..c9142fba47 100644 --- a/src/reflect/scala/reflect/api/Scopes.scala +++ b/src/reflect/scala/reflect/api/Scopes.scala @@ -16,7 +16,7 @@ package api * there is the `newScopeWith` function. * * Additional functionality is exposed in member scopes that are returned by - * `members` and `declarations` defined in [[scala.reflect.api.Types#TypeApi]]. + * `members` and `decls` defined in [[scala.reflect.api.Types#TypeApi]]. * Such scopes support the `sorted` method, which sorts members in declaration order. * * @group ReflectionAPI @@ -27,23 +27,18 @@ trait Scopes { self: Universe => * @template * @group Scopes */ - type Scope >: Null <: ScopeApi + type Scope >: Null <: AnyRef with ScopeApi /** The API that all scopes support * @group API */ trait ScopeApi extends Iterable[Symbol] - /** Create a new scope with the given initial elements. - * @group Scopes - */ - def newScopeWith(elems: Symbol*): Scope - /** The type of member scopes, as in class definitions, for example. * @template * @group Scopes */ - type MemberScope >: Null <: Scope with MemberScopeApi + type MemberScope >: Null <: AnyRef with MemberScopeApi with Scope /** The API that all member scopes support * @group API diff --git a/src/reflect/scala/reflect/api/StandardDefinitions.scala b/src/reflect/scala/reflect/api/StandardDefinitions.scala index 1a8885e6b5..524b7ea14b 100644 --- a/src/reflect/scala/reflect/api/StandardDefinitions.scala +++ b/src/reflect/scala/reflect/api/StandardDefinitions.scala @@ -131,10 +131,10 @@ trait StandardDefinitions { * scala> val m = typeOf[C].member(newTermName("m")).asMethod * m: reflect.runtime.universe.MethodSymbol = method m * - * scala> m.params(0)(0).typeSignature + * scala> m.params(0)(0).info * res1: reflect.runtime.universe.Type = => scala.Int * - * scala> showRaw(m.params(0)(0).typeSignature) + * scala> showRaw(m.params(0)(0).info) * res2: String = TypeRef( * ThisType(scala), * scala.<byname>, // <-- ByNameParamClass @@ -159,10 +159,10 @@ trait StandardDefinitions { * scala> val m = typeOf[C].member(newTermName("m")).asMethod * m: reflect.runtime.universe.MethodSymbol = method m * - * scala> m.params(0)(0).typeSignature + * scala> m.params(0)(0).info * res1: reflect.runtime.universe.Type = <repeated...>[Object] * - * scala> showRaw(m.params(0)(0).typeSignature) + * scala> showRaw(m.params(0)(0).info) * res2: String = TypeRef( * ThisType(scala), * scala.<repeated...>, // <-- JavaRepeatedParamClass @@ -184,10 +184,10 @@ trait StandardDefinitions { * scala> val m = typeOf[C].member(newTermName("m")).asMethod * m: reflect.runtime.universe.MethodSymbol = method m * - * scala> m.params(0)(0).typeSignature + * scala> m.params(0)(0).info * res1: reflect.runtime.universe.Type = scala.Int* * - * scala> showRaw(m.params(0)(0).typeSignature) + * scala> showRaw(m.params(0)(0).info) * res2: String = TypeRef( * ThisType(scala), * scala.<repeated>, // <-- RepeatedParamClass diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala index f89630a938..af11de46ce 100644 --- a/src/reflect/scala/reflect/api/StandardLiftables.scala +++ b/src/reflect/scala/reflect/api/StandardLiftables.scala @@ -2,13 +2,14 @@ package scala.reflect package api trait StandardLiftables { self: Universe => - import build.{SyntacticTuple, ScalaDot} + import internal._ + import reificationSupport.{SyntacticTuple, ScalaDot} trait StandardLiftableInstances { private def lift[T: Liftable](value: T): Tree = implicitly[Liftable[T]].apply(value) private def selectScala(names: Name*) = names.tail.foldLeft(ScalaDot(names.head)) { Select(_, _) } private def callScala(names: Name*)(args: List[Tree]) = Apply(selectScala(names: _*), args) - private def callCollection(name: Name)(args: List[Tree]) = callScala(nme.collection, nme.immutable, name)(args) + private def callCollection(name: Name)(args: List[Tree]) = callScala(stdnme.collection, stdnme.immutable, name)(args) private def liftAsLiteral[T]: Liftable[T] = Liftable { v => Literal(Constant(v)) } implicit def liftByte[T <: Byte]: Liftable[T] = liftAsLiteral[T] @@ -23,7 +24,7 @@ trait StandardLiftables { self: Universe => implicit def liftString[T <: String]: Liftable[T] = liftAsLiteral[T] implicit def liftScalaSymbol: Liftable[scala.Symbol] = Liftable { v => - callScala(nme.Symbol)(Literal(Constant(v.name)) :: Nil) + callScala(stdnme.Symbol)(Literal(Constant(v.name)) :: Nil) } implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) } @@ -32,22 +33,22 @@ trait StandardLiftables { self: Universe => implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = Liftable { ttag => TypeTree(ttag.tpe) } implicit def liftConstant[T <: Constant]: Liftable[T] = Liftable { const => Literal(const) } - implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(nme.Array)(arr.map(lift(_)).toList) } - implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(nme.Vector)(vect.map(lift(_)).toList) } - implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(nme.List)(lst.map(lift(_))) } - implicit def liftNil: Liftable[Nil.type] = Liftable { _ => selectScala(nme.collection, nme.immutable, nme.Nil) } - implicit def liftMap[K: Liftable, V: Liftable]: Liftable[Map[K, V]] = Liftable { m => callCollection(nme.Map)(m.toList.map(lift(_))) } - implicit def liftSet[T: Liftable]: Liftable[Set[T]] = Liftable { s => callCollection(nme.Set)(s.toList.map(lift(_))) } + implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(stdnme.Array)(arr.map(lift(_)).toList) } + implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(stdnme.Vector)(vect.map(lift(_)).toList) } + implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(stdnme.List)(lst.map(lift(_))) } + implicit def liftNil: Liftable[Nil.type] = Liftable { _ => selectScala(stdnme.collection, stdnme.immutable, stdnme.Nil) } + implicit def liftMap[K: Liftable, V: Liftable]: Liftable[Map[K, V]] = Liftable { m => callCollection(stdnme.Map)(m.toList.map(lift(_))) } + implicit def liftSet[T: Liftable]: Liftable[Set[T]] = Liftable { s => callCollection(stdnme.Set)(s.toList.map(lift(_))) } - implicit def liftSome[T: Liftable]: Liftable[Some[T]] = Liftable { case Some(v) => callScala(nme.Some)(lift(v) :: Nil) } - implicit def liftNone: Liftable[None.type] = Liftable { _ => selectScala(nme.None) } + implicit def liftSome[T: Liftable]: Liftable[Some[T]] = Liftable { case Some(v) => callScala(stdnme.Some)(lift(v) :: Nil) } + implicit def liftNone: Liftable[None.type] = Liftable { _ => selectScala(stdnme.None) } implicit def liftOption[T: Liftable]: Liftable[Option[T]] = Liftable { case some: Some[T] => lift(some) case none: None.type => lift(none) } - implicit def liftLeft[L: Liftable, R]: Liftable[Left[L, R]] = Liftable { case Left(v) => callScala(nme.util, nme.Left)(lift(v) :: Nil) } - implicit def liftRight[L, R: Liftable]: Liftable[Right[L, R]] = Liftable { case Right(v) => callScala(nme.util, nme.Right)(lift(v) :: Nil) } + implicit def liftLeft[L: Liftable, R]: Liftable[Left[L, R]] = Liftable { case Left(v) => callScala(stdnme.util, stdnme.Left)(lift(v) :: Nil) } + implicit def liftRight[L, R: Liftable]: Liftable[Right[L, R]] = Liftable { case Right(v) => callScala(stdnme.util, stdnme.Right)(lift(v) :: Nil) } implicit def liftEither[L: Liftable, R: Liftable]: Liftable[Either[L, R]] = Liftable { case left: Left[L, R] => lift(left) case right: Right[L, R] => lift(right) @@ -137,10 +138,10 @@ trait StandardLiftables { self: Universe => implicit def unliftString: Unliftable[String] = Unliftable { case Literal(Constant(s: String)) => s } implicit def unliftScalaSymbol: Unliftable[scala.Symbol] = Unliftable { - case Apply(ScalaDot(symbol), List(Literal(Constant(name: String)))) if symbol == nme.Symbol => scala.Symbol(name) + case Apply(ScalaDot(stdnme.Symbol), List(Literal(Constant(name: String)))) => scala.Symbol(name) } - implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(nme.WILDCARD)) => name } + implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(stdnme.WILDCARD)) => name } implicit def unliftType: Unliftable[Type] = Unliftable[Type] { case tt: TypeTree if tt.tpe != null => tt.tpe } implicit def unliftConstant: Unliftable[Constant] = Unliftable[Constant] { case Literal(const) => const } @@ -210,9 +211,10 @@ trait StandardLiftables { self: Universe => } // names used internally by implementations of standard liftables and unliftables - import scala.language.implicitConversions - private implicit def cachedNames(nme: self.nme.type): CachedNames.type = CachedNames - private object CachedNames { + // can't be `private object nme` because of https://groups.google.com/forum/#!topic/scala-internals/b-Full9WZeE + // can't be `private[this] object nme` because then STARR has problems prioritizing this.nme over self.nme + // therefore I'm essentially forced to give this object a non-standard name + private object stdnme { val Array = TermName("Array") val collection = TermName("collection") val immutable = TermName("immutable") @@ -225,7 +227,8 @@ trait StandardLiftables { self: Universe => val Set = TermName("Set") val Some = TermName("Some") val Symbol = TermName("Symbol") - val Vector = TermName("Vector") val util = TermName("util") + val Vector = TermName("Vector") + val WILDCARD = self.nme.WILDCARD } } diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala index aec5f19fa0..19bdfcae59 100644 --- a/src/reflect/scala/reflect/api/StandardNames.scala +++ b/src/reflect/scala/reflect/api/StandardNames.scala @@ -28,15 +28,23 @@ package api trait StandardNames { self: Universe => + /** @see [[termNames]] */ + @deprecated("Use `termNames` instead", "2.11.0") + val nme: TermNamesApi + /** A value containing all [[TermNamesApi standard term names]]. * @group StandardNames */ - val nme: TermNamesApi + val termNames: TermNamesApi + + /** @see [[typeNames]] */ + @deprecated("Use `typeNames` instead", "2.11.0") + val tpnme: TypeNamesApi /** A value containing all [[TypeNamesApi standard type names]]. * @group StandardNames */ - val tpnme: TypeNamesApi + val typeNames: TypeNamesApi /** Defines standard names, common for term and type names: These can be accessed via the [[nme]] and [[tpnme]] members. * @group API diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala index 1250545497..ff7ac3f574 100644 --- a/src/reflect/scala/reflect/api/Symbols.scala +++ b/src/reflect/scala/reflect/api/Symbols.scala @@ -30,7 +30,7 @@ package api * scala> val test = typeOf[C[Int]].member(newTermName("test")).asMethod * test: reflect.runtime.universe.MethodSymbol = method test * - * scala> test.typeSignature + * scala> test.info * res0: reflect.runtime.universe.Type = [U](x: T)(y: U)scala.Int * }}} * @@ -60,51 +60,39 @@ trait Symbols { self: Universe => * @group Symbols * @template */ - type Symbol >: Null <: SymbolApi + type Symbol >: Null <: AnyRef with SymbolApi /** The type of type symbols representing type, class, and trait declarations, * as well as type parameters. * @group Symbols * @template */ - type TypeSymbol >: Null <: Symbol with TypeSymbolApi + type TypeSymbol >: Null <: TypeSymbolApi with Symbol /** The type of term symbols representing val, var, def, and object declarations as * well as packages and value parameters. * @group Symbols * @template */ - type TermSymbol >: Null <: Symbol with TermSymbolApi + type TermSymbol >: Null <: TermSymbolApi with Symbol /** The type of method symbols representing def declarations. * @group Symbols * @template */ - type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi + type MethodSymbol >: Null <: MethodSymbolApi with TermSymbol /** The type of module symbols representing object declarations. * @group Symbols * @template */ - type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolApi + type ModuleSymbol >: Null <: ModuleSymbolApi with TermSymbol /** The type of class symbols representing class and trait definitions. * @group Symbols * @template */ - type ClassSymbol >: Null <: TypeSymbol with ClassSymbolApi - - /** The type of free terms introduced by reification. - * @group Symbols - * @template - */ - type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi - - /** The type of free types introduced by reification. - * @group Symbols - * @template - */ - type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi + type ClassSymbol >: Null <: ClassSymbolApi with TypeSymbol /** A special "missing" symbol. Commonly used in the API to denote a default or empty value. * @group Symbols @@ -131,12 +119,8 @@ trait Symbols { self: Universe => * @groupdesc Helpers These methods enable collections-like operations on symbols. * @groupname Type TypeSymbol Members * @groupprio Type -1 - * @groupname FreeType FreeType Symbol Members - * @groupprio FreeType -2 * @groupname Term TermSymbol Members * @groupprio Term -1 - * @groupname FreeTerm FreeTerm Symbol Members - * @groupprio FreeTerm -2 * @groupname Class Class Symbol Members * @groupprio Class -2 * @groupname Method Method Symbol Members @@ -171,7 +155,7 @@ trait Symbols { self: Universe => /** The name of the symbol as a member of the `Name` type. * @group Basics */ - def name: Name + def name: NameType /** The encoded full path name of this symbol, where outer names and inner names * are separated by periods. @@ -179,6 +163,9 @@ trait Symbols { self: Universe => */ def fullName: String + /** Position of the tree. */ + def pos: Position + /** 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` (except for `NoSymbol`), @@ -218,6 +205,15 @@ trait Symbols { self: Universe => */ def isMethod: Boolean = false + /** Does this method represent a constructor? + * + * If `owner` is a class, then this is a vanilla JVM constructor. + * If `owner` is a trait, then this is a mixin constructor. + * + * @group Method + */ + def isConstructor: Boolean + /** This symbol cast to a MethodSymbol. * @throws ScalaReflectionException if `isMethod` is false. * @@ -275,45 +271,6 @@ trait Symbols { self: Universe => */ def asClass: ClassSymbol = throw new ScalaReflectionException(s"$this is not a class") - /** Does this symbol represent a free term captured by reification? - * If yes, `isTerm` is also guaranteed to be true. - * - * @group Tests - */ - def isFreeTerm: Boolean = false - - /** This symbol cast to a free term symbol. - * @throws ScalaReflectionException if `isFreeTerm` is false. - * - * @group Conversions - */ - def asFreeTerm: FreeTermSymbol = throw new ScalaReflectionException(s"$this is not a free term") - - /** Does this symbol represent a free type captured by reification? - * If yes, `isType` is also guaranteed to be true. - * - * @group Tests - */ - def isFreeType: Boolean = false - - /** This symbol cast to a free type symbol. - * @throws ScalaReflectionException if `isFreeType` is false. - * - * @group Conversions - */ - def asFreeType: FreeTypeSymbol = throw new ScalaReflectionException(s"$this is not a free type") - - /** @group Constructors */ - def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol - /** @group Constructors */ - def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) - /** @group Constructors */ - def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol - /** @group Constructors */ - def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol - /** @group Constructors */ - def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol - /** Source file if this symbol is created during this compilation run, * or a class file if this symbol is loaded from a *.class or *.jar. * @@ -323,6 +280,7 @@ trait Symbols { self: Universe => * * @group Basics */ + @deprecated("Use `pos.source.file` instead", "2.11.0") def associatedFile: scala.reflect.io.AbstractFile /** A list of annotations attached to this Symbol. @@ -335,15 +293,34 @@ trait Symbols { self: Universe => * For a module: the class with the same name in the same package. * For all others: NoSymbol * + * This API may return unexpected results for module classes, packages and package classes. + * Use `companion` instead in order to get predictable results. + * * @group Basics */ + @deprecated("Use `companion` instead", "2.11.0") def companionSymbol: Symbol + /** For a class: its companion object if exists. + * For a module or a module class: companion class of the module if exists. + * For a package or a package class: NoSymbol. + * For all others: NoSymbol. + */ + def companion: Symbol + + /** @see [[infoIn]] */ + @deprecated("Use `infoIn` instead", "2.11.0") + def typeSignatureIn(site: Type): Type + /** The type signature of this symbol seen as a member of given type `site`. * * @group Basics */ - def typeSignatureIn(site: Type): Type + def infoIn(site: Type): Type + + /** @see [[info]] */ + @deprecated("Use `info` instead", "2.11.0") + def typeSignature: Type /** The type signature of this symbol. * @@ -351,17 +328,27 @@ trait Symbols { self: Universe => * instantiation of a generic type. For example, signature * of the method `def map[B](f: (A) ⇒ B): List[B]`, which refers to the type parameter `A` of the declaring class `List[A]`, * will always feature `A`, regardless of whether `map` is loaded from the `List[_]` or from `List[Int]`. To get a signature - * with type parameters appropriately instantiated, one should use `typeSignatureIn`. + * with type parameters appropriately instantiated, one should use `infoIn`. * * @group Basics */ - def typeSignature: Type + def info: Type + + /** @see [[overrides]] */ + @deprecated("Use `overrides` instead", "2.11.0") + def allOverriddenSymbols: List[Symbol] /** Returns all symbols overriden by this symbol. * * @group Basics */ - def allOverriddenSymbols: List[Symbol] + def overrides: List[Symbol] + + /** The overloaded alternatives of this symbol + * + * @group Basics + */ + def alternatives: List[Symbol] /******************* tests *******************/ @@ -380,16 +367,13 @@ trait Symbols { self: Universe => */ def isImplementationArtifact: 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. + /** Does this symbol represent a declaration or definition written in a source file as `private[this]` + * or generated in tree/symbol form with the combination of flags LOCAL and PRIVATE? + * If yes, `isPrivate` is guaranteed to be true, * * @group Tests */ - def isLocal: Boolean + def isPrivateThis: Boolean /** Does this symbol represent a private declaration or definition? * If yes, `privateWithin` might tell more about this symbol's visibility scope. @@ -398,6 +382,14 @@ trait Symbols { self: Universe => */ def isPrivate: Boolean + /** Does this symbol represent a declaration or definition written in a source file as `protected[this]` + * or generated in tree/symbol form with the combination of flags LOCAL and PROTECTED? + * If yes, `isProtected` is guaranteed to be true, + * + * @group Tests + */ + def isProtectedThis: Boolean + /** Does this symbol represent a protected declaration or definition? * If yes, `privateWithin` might tell more about this symbol's visibility scope. * @@ -412,7 +404,7 @@ trait Symbols { self: Universe => def isPublic: Boolean /** - * Set when symbol has a modifier of the form private[X], NoSymbol otherwise. + * Set when symbol has a modifier of the form private[X] or protected[X], NoSymbol otherwise. * * Access level encoding: there are three scala flags (PRIVATE, PROTECTED, * and LOCAL) which combine with value privateWithin (the "foo" in private[foo]) @@ -441,7 +433,7 @@ trait Symbols { self: Universe => def privateWithin: Symbol /** Does this symbol represent the definition of a package? - * If yes, `isTerm` is also guaranteed to be true. + * Known issues: [[https://issues.scala-lang.org/browse/SI-6732]]. * * @group Tests */ @@ -454,12 +446,6 @@ trait Symbols { self: Universe => */ def isPackageClass: Boolean - /** Does this symbol or its underlying type represent a typechecking error? - * - * @group Tests - */ - def isErroneous : Boolean - /** 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. @@ -475,11 +461,11 @@ trait Symbols { self: Universe => */ def isFinal: Boolean - /** Is this symbol overriding something? + /** Is this symbol abstract (i.e. an abstract class, an abstract method, value or type member)? * * @group Tests */ - def isOverride: Boolean + def isAbstract: Boolean /** Is this symbol labelled as "abstract override"? * @@ -613,12 +599,6 @@ trait Symbols { self: Universe => */ def isLazy: Boolean - /** The overloaded alternatives of this symbol - * - * @group Term - */ - def alternatives: List[Symbol] - /** Used to provide a better error message for `asMethod` */ override protected def isOverloadedMethod = alternatives exists (_.isMethod) @@ -704,7 +684,7 @@ trait Symbols { self: Universe => * 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 + * By contrast, `C.info` would be a type signature of form * `PolyType(ClassInfoType(...))` that describes type parameters, value * parameters, parent types, and members of `C`. * @@ -727,13 +707,6 @@ trait Symbols { self: Universe => */ 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. - * - * @group Type - */ - def isSkolem : Boolean - /** Does this symbol represent the definition of a type alias? * * @group Type @@ -744,6 +717,7 @@ trait Symbols { self: Universe => * * @group Type */ + @deprecated("Use isAbstract instead", "2.11.0") def isAbstractType : Boolean /** Does this symbol represent an existentially bound type? @@ -769,15 +743,6 @@ trait Symbols { self: Universe => final override def isMethod = true final override def asMethod = this - /** Does this method represent a constructor? - * - * If `owner` is a class, then this is a vanilla JVM constructor. - * If `owner` is a trait, then this is a mixin constructor. - * - * @group Method - */ - def isConstructor: Boolean - /** Does this symbol denote the primary constructor of its enclosing class? * * @group Method @@ -790,6 +755,10 @@ trait Symbols { self: Universe => */ def typeParams: List[Symbol] + /** @see [[paramLists]] */ + @deprecated("Use `paramLists` instead", "2.11.0") + def paramss: List[List[Symbol]] + /** All parameter lists of the method. * The name ending with "ss" indicates that the result type is a list of lists. * @@ -799,7 +768,7 @@ trait Symbols { self: Universe => * * @group Method */ - def paramss: List[List[Symbol]] + def paramLists: List[List[Symbol]] /** Does this method support variable length argument lists? * @@ -812,6 +781,14 @@ trait Symbols { self: Universe => * @group Method */ def returnType: Type + + /** Exceptions that this method is known to throw. + * For Scala methods, the list is calculated from [[throws]] annotations present on a method. + * For Java methods, the list is calculated from `throws` clauses attached to the method and stored in bytecode. + * + * @group Method + */ + def exceptions: List[Symbol] } /** The API of module symbols. @@ -877,6 +854,7 @@ trait Symbols { self: Universe => * * @group Class */ + @deprecated("Use isAbstract instead", "2.11.0") def isAbstractClass: Boolean /** Does this symbol represent a case class? @@ -926,50 +904,29 @@ trait Symbols { self: Universe => */ def thisPrefix: Type - /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait + /** The type `C.super[M]`, where `C` is the current class and `M` is supertpe. * * @group Class */ - def typeParams: List[Symbol] - } - - /** The API of free term symbols. - * The main source of information about symbols is the [[Symbols]] page. - * - * $SYMACCESSORS - * @group API - */ - trait FreeTermSymbolApi extends TermSymbolApi { this: FreeTermSymbol => - final override def isFreeTerm = true - final override def asFreeTerm = this + def superPrefix(supertpe: Type): Type - /** The place where this symbol has been spawned - * - * @group FreeTerm - */ - def origin: String - - /** The valus this symbol refers to + /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait * - * @group FreeTerm + * @group Class */ - def value: Any - } - - /** The API of free type symbols. - * The main source of information about symbols is the [[Symbols]] page. - * - * $SYMACCESSORS - * @group API - */ - trait FreeTypeSymbolApi extends TypeSymbolApi { this: FreeTypeSymbol => - final override def isFreeType = true - final override def asFreeType = this + def typeParams: List[Symbol] - /** The place where this symbol has been spawned + /** For a Scala class or module class, the primary constructor of the class. + * For a Scala trait, its mixin constructor. + * For a Scala package class, NoSymbol. + * For a Java class, NoSymbol. * - * @group FreeType + * @group Class */ - def origin: String + // TODO: SI-8193 I think we should only return a non-empty symbol if called for Scala classes + // returning something for traits and module classes is outright confusing + // This, however, will require some refactoring in the compiler, so I'll leave it for later + // as at the moment we don't have time or risk tolerance for that + def primaryConstructor: Symbol } } diff --git a/src/reflect/scala/reflect/api/TagInterop.scala b/src/reflect/scala/reflect/api/TagInterop.scala deleted file mode 100644 index 51b7c519c5..0000000000 --- a/src/reflect/scala/reflect/api/TagInterop.scala +++ /dev/null @@ -1,44 +0,0 @@ -package scala -package reflect -package api - -/** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> - * - * This trait provides type tag <-> manifest interoperability. - * @group ReflectionAPI - * - * @groupname TagInterop TypeTag and Manifest Interoperability - */ -trait TagInterop { self: Universe => - // TODO `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work - // if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_typetags_are_manifests.scala - - /** - * Convert a [[scala.reflect.api.TypeTags#TypeTag]] to a [[scala.reflect.Manifest]]. - * - * Compiler usually generates these conversions automatically, when a type tag for a type `T` is in scope, - * and an implicit of type `Manifest[T]` is requested, but this method can also be called manually. - * For example: - * {{{ - * typeTagToManifest(scala.reflect.runtime.currentMirror, implicitly[TypeTag[String]]) - * }}} - * @group TagInterop - */ - def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] = - throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.") - - /** - * Convert a [[scala.reflect.Manifest]] to a [[scala.reflect.api.TypeTags#TypeTag]]. - * - * Compiler usually generates these conversions automatically, when a manifest for a type `T` is in scope, - * and an implicit of type `TypeTag[T]` is requested, but this method can also be called manually. - * For example: - * {{{ - * manifestToTypeTag(scala.reflect.runtime.currentMirror, implicitly[Manifest[String]]) - * }}} - * @group TagInterop - */ - def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] = - throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.") -} diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index 60e00ca5fd..ff8926651b 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -59,7 +59,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Tree >: Null <: TreeApi + type Tree >: Null <: AnyRef with TreeApi /** The API that all trees support. * The main source of information about trees is the [[scala.reflect.api.Trees]] page. @@ -168,29 +168,6 @@ trait Trees { self: Universe => */ def children: List[Tree] - /** Extracts free term symbols from a tree that is reified or contains reified subtrees. - */ - def freeTerms: List[FreeTermSymbol] - - /** Extracts free type symbols from a tree that is reified or contains reified subtrees. - */ - def freeTypes: List[FreeTypeSymbol] - - /** Substitute symbols in `to` for corresponding occurrences of references to - * symbols `from` in this type. - */ - def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree - - /** Substitute types in `to` for corresponding occurrences of references to - * symbols `from` in this tree. - */ - def substituteTypes(from: List[Symbol], to: List[Type]): Tree - - /** Substitute given tree `to` for occurrences of nodes that represent - * `C.this`, where `C` referes to the given class `clazz`. - */ - def substituteThis(clazz: Symbol, to: Tree): Tree - /** Make a copy of this tree, keeping all attributes, * except that all positions are focused (so nothing * in this tree will be found when searching by position). @@ -216,7 +193,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type TermTree >: Null <: AnyRef with Tree with TermTreeApi + type TermTree >: Null <: TermTreeApi with Tree /** The API that all term trees support * @group API @@ -229,7 +206,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type TypTree >: Null <: AnyRef with Tree with TypTreeApi + type TypTree >: Null <: TypTreeApi with Tree /** The API that all typ trees support * @group API @@ -237,11 +214,14 @@ trait Trees { self: Universe => trait TypTreeApi extends TreeApi { this: TypTree => } - /** A tree with a mutable symbol field, initialized to NoSymbol. + /** A tree that carries a symbol, e.g. by defining it (`DefTree`) or by referring to it (`RefTree`). + * Such trees start their life naked, returning `NoSymbol`, but after being typechecked without errors + * they hold non-empty symbols. + * * @group Trees * @template */ - type SymTree >: Null <: AnyRef with Tree with SymTreeApi + type SymTree >: Null <: SymTreeApi with Tree /** The API that all sym trees support * @group API @@ -251,18 +231,18 @@ trait Trees { self: Universe => def symbol: Symbol } - /** A tree with a name - effectively, a DefTree or RefTree. + /** A tree that carries a name, e.g. by defining it (`DefTree`) or by referring to it (`RefTree`). * @group Trees * @template */ - type NameTree >: Null <: AnyRef with Tree with NameTreeApi + type NameTree >: Null <: NameTreeApi with Tree /** The API that all name trees support * @group API */ trait NameTreeApi extends TreeApi { this: NameTree => /** The underlying name. - * For example, the `<List>` part of `Ident("List": TermName)`. + * For example, the `List` part of `Ident(TermName("List"))`. */ def name: Name } @@ -273,14 +253,14 @@ trait Trees { self: Universe => * @group Trees * @template */ - type RefTree >: Null <: SymTree with NameTree with RefTreeApi + type RefTree >: Null <: RefTreeApi with SymTree with NameTree /** The API that all ref trees support * @group API */ trait RefTreeApi extends SymTreeApi with NameTreeApi { this: RefTree => /** The qualifier of the reference. - * For example, the `<scala>` part of `Select("scala": TermName, "List": TermName)`. + * For example, the `Ident(TermName("scala"))` part of `Select(Ident(TermName("scala")), TermName("List"))`. * `EmptyTree` for `Ident` instances. */ def qualifier: Tree @@ -303,11 +283,14 @@ trait Trees { self: Universe => def unapply(refTree: RefTree): Option[(Tree, Name)] } - /** A tree which defines a symbol-carrying entity. + /** A tree representing a symbol-defining entity: + * 1) A declaration or a definition (type, class, object, package, val, var, or def) + * 2) `Bind` that is used to represent binding occurrences in pattern matches + * 3) `LabelDef` that is used internally to represent while loops * @group Trees * @template */ - type DefTree >: Null <: SymTree with NameTree with DefTreeApi + type DefTree >: Null <: DefTreeApi with SymTree with NameTree /** The API that all def trees support * @group API @@ -322,7 +305,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type MemberDef >: Null <: DefTree with MemberDefApi + type MemberDef >: Null <: MemberDefApi with DefTree /** The API that all member defs support * @group API @@ -336,7 +319,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type PackageDef >: Null <: MemberDef with PackageDefApi + type PackageDef >: Null <: PackageDefApi with MemberDef /** The constructor/extractor for `PackageDef` instances. * @group Extractors @@ -369,7 +352,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type ImplDef >: Null <: MemberDef with ImplDefApi + type ImplDef >: Null <: ImplDefApi with MemberDef /** The API that all impl defs support * @group API @@ -383,7 +366,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type ClassDef >: Null <: ImplDef with ClassDefApi + type ClassDef >: Null <: ClassDefApi with ImplDef /** The constructor/extractor for `ClassDef` instances. * @group Extractors @@ -403,6 +386,10 @@ trait Trees { self: Universe => abstract class ClassDefExtractor { def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template): ClassDef def unapply(classDef: ClassDef): Option[(Modifiers, TypeName, List[TypeDef], Template)] + + /** @see [[InternalApi.classDef]] */ + @deprecated("Use `internal.classDef` instead", "2.11.0") + def apply(sym: Symbol, impl: Template)(implicit token: CompatToken): ClassDef = internal.classDef(sym, impl) } /** The API that all class defs support @@ -428,7 +415,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type ModuleDef >: Null <: ImplDef with ModuleDefApi + type ModuleDef >: Null <: ModuleDefApi with ImplDef /** The constructor/extractor for `ModuleDef` instances. * @group Extractors @@ -448,6 +435,10 @@ trait Trees { self: Universe => abstract class ModuleDefExtractor { def apply(mods: Modifiers, name: TermName, impl: Template): ModuleDef def unapply(moduleDef: ModuleDef): Option[(Modifiers, TermName, Template)] + + /** @see [[InternalApi.moduleDef]] */ + @deprecated("Use `internal.moduleDef` instead", "2.11.0") + def apply(sym: Symbol, impl: Template)(implicit token: CompatToken): ModuleDef = internal.moduleDef(sym, impl) } /** The API that all module defs support @@ -468,14 +459,14 @@ trait Trees { self: Universe => * @group Trees * @template */ - type ValOrDefDef >: Null <: MemberDef with ValOrDefDefApi + type ValOrDefDef >: Null <: ValOrDefDefApi with MemberDef /** The API that all val defs and def defs support * @group API */ trait ValOrDefDefApi extends MemberDefApi { this: ValOrDefDef => /** @inheritdoc */ - def name: Name // can't be a TermName because macros can be type names. + def name: TermName /** The type ascribed to the definition. * An empty `TypeTree` if the type hasn't been specified explicitly @@ -499,7 +490,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type ValDef >: Null <: ValOrDefDef with ValDefApi + type ValDef >: Null <: ValDefApi with ValOrDefDef /** The constructor/extractor for `ValDef` instances. * @group Extractors @@ -524,6 +515,14 @@ trait Trees { self: Universe => abstract class ValDefExtractor { def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef def unapply(valDef: ValDef): Option[(Modifiers, TermName, Tree, Tree)] + + /** @see [[InternalApi.valDef]] */ + @deprecated("Use `internal.valDef` instead", "2.11.0") + def apply(sym: Symbol, rhs: Tree)(implicit token: CompatToken): ValDef = internal.valDef(sym, rhs) + + /** @see [[InternalApi.valDef]] */ + @deprecated("Use `internal.valDef` instead", "2.11.0") + def apply(sym: Symbol)(implicit token: CompatToken): ValDef = internal.valDef(sym) } /** The API that all val defs support @@ -548,7 +547,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type DefDef >: Null <: ValOrDefDef with DefDefApi + type DefDef >: Null <: DefDefApi with ValOrDefDef /** The constructor/extractor for `DefDef` instances. * @group Extractors @@ -567,6 +566,26 @@ trait Trees { self: Universe => abstract class DefDefExtractor { def apply(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef def unapply(defDef: DefDef): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)] + + /** @see [[InternalApi.defDef]] */ + @deprecated("Use `internal.defDef` instead", "2.11.0") + def apply(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, mods, vparamss, rhs) + + /** @see [[InternalApi.defDef]] */ + @deprecated("Use `internal.defDef` instead", "2.11.0") + def apply(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, vparamss, rhs) + + /** @see [[InternalApi.defDef]] */ + @deprecated("Use `internal.defDef` instead", "2.11.0") + def apply(sym: Symbol, mods: Modifiers, rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, mods, rhs) + + /** @see [[InternalApi.defDef]] */ + @deprecated("Use `internal.defDef` instead", "2.11.0") + def apply(sym: Symbol, rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, rhs) + + /** @see [[InternalApi.defDef]] */ + @deprecated("Use `internal.defDef` instead", "2.11.0") + def apply(sym: Symbol, rhs: List[List[Symbol]] => Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, rhs) } /** The API that all def defs support @@ -597,7 +616,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type TypeDef >: Null <: MemberDef with TypeDefApi + type TypeDef >: Null <: TypeDefApi with MemberDef /** The constructor/extractor for `TypeDef` instances. * @group Extractors @@ -619,6 +638,14 @@ trait Trees { self: Universe => abstract class TypeDefExtractor { def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef def unapply(typeDef: TypeDef): Option[(Modifiers, TypeName, List[TypeDef], Tree)] + + /** @see [[InternalApi.typeDef]] */ + @deprecated("Use `internal.typeDef` instead", "2.11.0") + def apply(sym: Symbol, rhs: Tree)(implicit token: CompatToken): TypeDef = internal.typeDef(sym, rhs) + + /** @see [[InternalApi.typeDef]] */ + @deprecated("Use `internal.typeDef` instead", "2.11.0") + def apply(sym: Symbol)(implicit token: CompatToken): TypeDef = internal.typeDef(sym) } /** The API that all type defs support @@ -656,7 +683,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type LabelDef >: Null <: DefTree with TermTree with LabelDefApi + type LabelDef >: Null <: LabelDefApi with DefTree with TermTree /** The constructor/extractor for `LabelDef` instances. * @group Extractors @@ -679,6 +706,10 @@ trait Trees { self: Universe => abstract class LabelDefExtractor { def apply(name: TermName, params: List[Ident], rhs: Tree): LabelDef def unapply(labelDef: LabelDef): Option[(TermName, List[Ident], Tree)] + + /** @see [[InternalApi.labelDef]] */ + @deprecated("Use `internal.labelDef` instead", "2.11.0") + def apply(sym: Symbol, params: List[Symbol], rhs: Tree)(implicit token: CompatToken): LabelDef = internal.labelDef(sym, params, rhs) } /** The API that all label defs support @@ -699,7 +730,7 @@ trait Trees { self: Universe => def rhs: Tree } - /** Import selector + /** Import selector (not a tree, but a component of the `Import` tree) * * Representation of an imported name its optional rename and their optional positions * @@ -758,7 +789,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Import >: Null <: SymTree with ImportApi + type Import >: Null <: ImportApi with SymTree /** The constructor/extractor for `Import` instances. * @group Extractors @@ -810,7 +841,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Template >: Null <: SymTree with TemplateApi + type Template >: Null <: TemplateApi with SymTree /** The constructor/extractor for `Template` instances. * @group Extractors @@ -862,7 +893,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Block >: Null <: TermTree with BlockApi + type Block >: Null <: BlockApi with TermTree /** The constructor/extractor for `Block` instances. * @group Extractors @@ -901,7 +932,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type CaseDef >: Null <: AnyRef with Tree with CaseDefApi + type CaseDef >: Null <: CaseDefApi with Tree /** The constructor/extractor for `CaseDef` instances. * @group Extractors @@ -948,7 +979,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Alternative >: Null <: TermTree with AlternativeApi + type Alternative >: Null <: AlternativeApi with TermTree /** The constructor/extractor for `Alternative` instances. * @group Extractors @@ -980,7 +1011,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Star >: Null <: TermTree with StarApi + type Star >: Null <: StarApi with TermTree /** The constructor/extractor for `Star` instances. * @group Extractors @@ -1015,7 +1046,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Bind >: Null <: DefTree with BindApi + type Bind >: Null <: BindApi with DefTree /** The constructor/extractor for `Bind` instances. * @group Extractors @@ -1078,7 +1109,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type UnApply >: Null <: TermTree with UnApplyApi + type UnApply >: Null <: UnApplyApi with TermTree /** The constructor/extractor for `UnApply` instances. * @group Extractors @@ -1114,7 +1145,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Function >: Null <: TermTree with SymTree with FunctionApi + type Function >: Null <: FunctionApi with TermTree with SymTree /** The constructor/extractor for `Function` instances. * @group Extractors @@ -1152,7 +1183,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Assign >: Null <: TermTree with AssignApi + type Assign >: Null <: AssignApi with TermTree /** The constructor/extractor for `Assign` instances. * @group Extractors @@ -1188,7 +1219,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type AssignOrNamedArg >: Null <: TermTree with AssignOrNamedArgApi + type AssignOrNamedArg >: Null <: AssignOrNamedArgApi with TermTree /** The constructor/extractor for `AssignOrNamedArg` instances. * @group Extractors @@ -1229,7 +1260,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type If >: Null <: TermTree with IfApi + type If >: Null <: IfApi with TermTree /** The constructor/extractor for `If` instances. * @group Extractors @@ -1280,7 +1311,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Match >: Null <: TermTree with MatchApi + type Match >: Null <: MatchApi with TermTree /** The constructor/extractor for `Match` instances. * @group Extractors @@ -1315,7 +1346,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Return >: Null <: TermTree with SymTree with ReturnApi + type Return >: Null <: ReturnApi with SymTree with TermTree /** The constructor/extractor for `Return` instances. * @group Extractors @@ -1347,7 +1378,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Try >: Null <: TermTree with TryApi + type Try >: Null <: TryApi with TermTree /** The constructor/extractor for `Try` instances. * @group Extractors @@ -1385,7 +1416,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Throw >: Null <: TermTree with ThrowApi + type Throw >: Null <: ThrowApi with TermTree /** The constructor/extractor for `Throw` instances. * @group Extractors @@ -1415,7 +1446,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type New >: Null <: TermTree with NewApi + type New >: Null <: NewApi with TermTree /** The constructor/extractor for `New` instances. * @group Extractors @@ -1465,7 +1496,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Typed >: Null <: TermTree with TypedApi + type Typed >: Null <: TypedApi with TermTree /** The constructor/extractor for `Typed` instances. * @group Extractors @@ -1498,7 +1529,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type GenericApply >: Null <: TermTree with GenericApplyApi + type GenericApply >: Null <: GenericApplyApi with TermTree /** The API that all applies support * @group API @@ -1519,7 +1550,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type TypeApply >: Null <: GenericApply with TypeApplyApi + type TypeApply >: Null <: TypeApplyApi with GenericApply /** The constructor/extractor for `TypeApply` instances. * @group Extractors @@ -1557,7 +1588,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Apply >: Null <: GenericApply with ApplyApi + type Apply >: Null <: ApplyApi with GenericApply /** The constructor/extractor for `Apply` instances. * @group Extractors @@ -1594,7 +1625,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Super >: Null <: TermTree with SuperApi + type Super >: Null <: SuperApi with TermTree /** The constructor/extractor for `Super` instances. * @group Extractors @@ -1640,7 +1671,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type This >: Null <: TermTree with SymTree with ThisApi + type This >: Null <: ThisApi with TermTree with SymTree /** The constructor/extractor for `This` instances. * @group Extractors @@ -1675,7 +1706,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Select >: Null <: RefTree with SelectApi + type Select >: Null <: SelectApi with RefTree /** The constructor/extractor for `Select` instances. * @group Extractors @@ -1714,7 +1745,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Ident >: Null <: RefTree with IdentApi + type Ident >: Null <: IdentApi with RefTree /** The constructor/extractor for `Ident` instances. * @group Extractors @@ -1739,65 +1770,18 @@ trait Trees { self: Universe => * @group API */ trait IdentApi extends RefTreeApi { this: Ident => + /** Was this ident created from a backquoted identifier? */ + def isBackquoted: Boolean + /** @inheritdoc */ def name: Name } - /** Marks underlying reference to id as boxed. - * - * <b>Precondition:<\b> id must refer to a captured variable - * A reference such marked will refer to the boxed entity, no dereferencing - * with `.elem` is done on it. - * This tree node can be emitted by macros such as reify that call referenceCapturedVariable. - * It is eliminated in LambdaLift, where the boxing conversion takes place. - * @group Trees - * @template - */ - type ReferenceToBoxed >: Null <: TermTree with ReferenceToBoxedApi - - /** The constructor/extractor for `ReferenceToBoxed` instances. - * @group Extractors - */ - val ReferenceToBoxed: ReferenceToBoxedExtractor - - /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`. - * This AST node does not have direct correspondence to Scala code, - * and is emitted by macros to reference capture vars directly without going through `elem`. - * - * For example: - * - * var x = ... - * fun { x } - * - * Will emit: - * - * Ident(x) - * - * Which gets transformed to: - * - * Select(Ident(x), "elem") - * - * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed. - * @group Extractors - */ - abstract class ReferenceToBoxedExtractor { - def apply(ident: Ident): ReferenceToBoxed - def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident] - } - - /** The API that all references support - * @group API - */ - trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed => - /** The underlying reference. */ - def ident: Tree - } - /** Literal * @group Trees * @template */ - type Literal >: Null <: TermTree with LiteralApi + type Literal >: Null <: LiteralApi with TermTree /** The constructor/extractor for `Literal` instances. * @group Extractors @@ -1830,7 +1814,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type Annotated >: Null <: AnyRef with Tree with AnnotatedApi + type Annotated >: Null <: AnnotatedApi with Tree /** The constructor/extractor for `Annotated` instances. * @group Extractors @@ -1864,7 +1848,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type SingletonTypeTree >: Null <: TypTree with SingletonTypeTreeApi + type SingletonTypeTree >: Null <: SingletonTypeTreeApi with TypTree /** The constructor/extractor for `SingletonTypeTree` instances. * @group Extractors @@ -1894,7 +1878,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi + type SelectFromTypeTree >: Null <: SelectFromTypeTreeApi with TypTree with RefTree /** The constructor/extractor for `SelectFromTypeTree` instances. * @group Extractors @@ -1935,7 +1919,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type CompoundTypeTree >: Null <: TypTree with CompoundTypeTreeApi + type CompoundTypeTree >: Null <: CompoundTypeTreeApi with TypTree /** The constructor/extractor for `CompoundTypeTree` instances. * @group Extractors @@ -1965,7 +1949,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type AppliedTypeTree >: Null <: TypTree with AppliedTypeTreeApi + type AppliedTypeTree >: Null <: AppliedTypeTreeApi with TypTree /** The constructor/extractor for `AppliedTypeTree` instances. * @group Extractors @@ -2007,7 +1991,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type TypeBoundsTree >: Null <: TypTree with TypeBoundsTreeApi + type TypeBoundsTree >: Null <: TypeBoundsTreeApi with TypTree /** The constructor/extractor for `TypeBoundsTree` instances. * @group Extractors @@ -2044,7 +2028,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type ExistentialTypeTree >: Null <: TypTree with ExistentialTypeTreeApi + type ExistentialTypeTree >: Null <: ExistentialTypeTreeApi with TypTree /** The constructor/extractor for `ExistentialTypeTree` instances. * @group Extractors @@ -2085,7 +2069,7 @@ trait Trees { self: Universe => * @group Trees * @template */ - type TypeTree >: Null <: TypTree with TypeTreeApi + type TypeTree >: Null <: TypeTreeApi with TypTree /** The constructor/extractor for `TypeTree` instances. * @group Extractors @@ -2134,78 +2118,6 @@ trait Trees { self: Universe => // ---------------------- factories ---------------------------------------------- - /** A factory method for `ClassDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical ClassDef constructor to create a class and then initialize its position and symbol manually", "2.10.1") - def ClassDef(sym: Symbol, impl: Template): ClassDef - - /** A factory method for `ModuleDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical ModuleDef constructor to create an object and then initialize its position and symbol manually", "2.10.1") - def ModuleDef(sym: Symbol, impl: Template): ModuleDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical ValDef constructor to create a val and then initialize its position and symbol manually", "2.10.1") - def ValDef(sym: Symbol, rhs: Tree): ValDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical ValDef constructor to create a val with an empty right-hand side and then initialize its position and symbol manually", "2.10.1") - def ValDef(sym: Symbol): ValDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1") - def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1") - def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1") - def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1") - def DefDef(sym: Symbol, rhs: Tree): DefDef - - /** A factory method for `ValDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1") - def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef - - /** A factory method for `TypeDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical TypeDef constructor to create a type alias and then initialize its position and symbol manually", "2.10.1") - def TypeDef(sym: Symbol, rhs: Tree): TypeDef - - /** A factory method for `TypeDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical TypeDef constructor to create an abstract type or type parameter and then initialize its position and symbol manually", "2.10.1") - def TypeDef(sym: Symbol): TypeDef - - /** A factory method for `LabelDef` nodes. - * @group Factories - */ - @deprecated("Use the canonical LabelDef constructor to create a label and then initialize its position and symbol manually", "2.10.1") - def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef - /** A factory method for `Block` nodes. * Flattens directly nested blocks. * @group Factories @@ -2313,7 +2225,7 @@ trait Trees { self: Universe => * @template * @group Copying */ - type TreeCopier <: TreeCopierOps + type TreeCopier >: Null <: AnyRef with TreeCopierOps /** The standard (lazy) tree copier. * @group Copying @@ -2489,6 +2401,11 @@ trait Trees { self: Universe => */ def Ident(tree: Tree, name: Name): Ident + /** Creates a `RefTree` node from the given components, having a given `tree` as a prototype. + * Having a tree as a prototype means that the tree's attachments, type and symbol will be copied into the result. + */ + def RefTree(tree: Tree, qualifier: Tree, selector: Name): RefTree + /** Creates a `ReferenceToBoxed` node from the given components, having a given `tree` as a prototype. * Having a tree as a prototype means that the tree's attachments, type and symbol will be copied into the result. */ @@ -2698,7 +2615,7 @@ trait Trees { self: Universe => */ protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree) - /** The type of tree modifiers. + /** The type of tree modifiers (not a tree, but rather part of DefTrees). * @group Traversal */ type Modifiers >: Null <: AnyRef with ModifiersApi diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala index be76758224..1d5bf5d28b 100644 --- a/src/reflect/scala/reflect/api/TypeTags.scala +++ b/src/reflect/scala/reflect/api/TypeTags.scala @@ -326,13 +326,31 @@ trait TypeTags { self: Universe => * Shortcut for `implicitly[WeakTypeTag[T]].tpe` * @group TypeTags */ - def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe + def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = if (attag != null) attag.tpe else typeOf[Null] + + /** + * Type of `x` as derived from a weak type tag. + * @group TypeTags + */ + def weakTypeOf[T: WeakTypeTag](x: => T): Type = weakTypeOf[T] /** * Shortcut for `implicitly[TypeTag[T]].tpe` * @group TypeTags */ - def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe + def typeOf[T](implicit ttag: TypeTag[T]): Type = if (ttag != null) ttag.tpe else typeOf[Null] + + /** + * Type of `x` as derived from a type tag. + * @group TypeTags + */ + def typeOf[T: TypeTag](x: => T): Type = typeOf[T] + + /** + * Type symbol of `x` as derived from a type tag. + * @group TypeTags + */ + def symbolOf[T: WeakTypeTag]: TypeSymbol } private[scala] class SerializedTypeTag(var tpec: TypeCreator, var concrete: Boolean) extends Serializable { diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index 4892b46e16..0e176170f8 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -59,7 +59,7 @@ trait Types { * @template * @group Types */ - type Type >: Null <: TypeApi + type Type >: Null <: AnyRef with TypeApi /** This constant is used as a special value that indicates that no meaningful type exists. * @group Types @@ -76,6 +76,12 @@ trait Types { /** The API of types. * The main source of information about types is the [[scala.reflect.api.Types]] page. * @group API + * + * @define dealiasWidenWarning Note that type aliases can hide beneath + * singleton types and singleton types can hide inside type aliases. + * Moreover, aliases might lurk in the upper bounds of abstract types. + * Therefore careful thought has to be applied to identify and carry out + * unwrapping logic specific to your use case. */ abstract class TypeApi { /** The term symbol associated with the type, or `NoSymbol` for types @@ -88,11 +94,19 @@ trait Types { */ def typeSymbol: Symbol + /** @see [[decl]] */ + @deprecated("Use `decl` instead", "2.11.0") + def declaration(name: Name): Symbol + /** The defined or declared members with name `name` in this type; * an OverloadedSymbol if several exist, NoSymbol if none exist. * Alternatives of overloaded symbol appear in the order they are declared. */ - def declaration(name: Name): Symbol + def decl(name: Name): Symbol + + /** @see [[decls]] */ + @deprecated("Use `decls` instead", "2.11.0") + def declarations: MemberScope /** A `Scope` containing directly declared members of this type. * Unlike `members` this method doesn't returns inherited members. @@ -100,7 +114,7 @@ trait Types { * Members in the returned scope might appear in arbitrary order. * Use `declarations.sorted` to get an ordered list of members. */ - def declarations: MemberScope + def decls: MemberScope /** The member with given name, either directly declared or inherited, * an OverloadedSymbol if several exist, NoSymbol if none exist. @@ -115,6 +129,11 @@ trait Types { */ def members: MemberScope + /** Type signature of the companion of the underlying class symbol. + * NoType if the underlying symbol is not a class symbol, or if it doesn't have a companion. + */ + def companion: Type + /** Is this type a type constructor that is missing its type arguments? */ def takesTypeArgs: Boolean @@ -123,7 +142,7 @@ trait Types { */ def typeConstructor: Type - /** + /** Reduce to beta eta-long normal form. * Expands type aliases and converts higher-kinded TypeRefs to PolyTypes. * Functions on types are also implemented as PolyTypes. * @@ -131,8 +150,18 @@ trait Types { * TypeRef(pre, <List>, List()) is replaced by * PolyType(X, TypeRef(pre, <List>, List(X))) */ + @deprecated("Use `dealias` or `etaExpand` instead", "2.11.0") def normalize: Type + /** Converts higher-kinded TypeRefs to PolyTypes. + * Functions on types are also implemented as PolyTypes. + * + * Example: (in the below, <List> is the type constructor of List) + * TypeRef(pre, <List>, List()) is replaced by + * PolyType(X, TypeRef(pre, <List>, List(X))) + */ + def etaExpand: Type + /** Does this type conform to given type argument `that`? */ def <:< (that: Type): Boolean @@ -205,9 +234,124 @@ trait Types { * class Outer { class C ; val x: C } * val o: Outer * <o.x.type>.widen = o.C + * + * $dealiasWidenWarning */ def widen: Type + /** Expands type aliases arising from type members. + * $dealiasWidenWarning + */ + def dealias: Type + + /******* popular methods from subclasses *******/ + + /** List of type arguments ingrained in this type reference. + * Depending on your use case you might or might not want to call `dealias` first. + * + * {{{ + * scala> type T = List[Int] + * defined type alias T + * + * scala> typeOf[T].typeArgs + * res0: List[reflect.runtime.universe.Type] = List() + * + * scala> typeOf[T].dealias.typeArgs + * res1: List[reflect.runtime.universe.Type] = List(scala.Int) + * }}} + */ + def typeArgs: List[Type] + + /** @see [[paramLists]] */ + @deprecated("Use `paramLists` instead", "2.11.0") + def paramss: List[List[Symbol]] + + /** For a method or poly type, a list of its value parameter sections, + * the empty list of lists for all other types. + */ + def paramLists: List[List[Symbol]] + + /** For a 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 + * (can be a MethodType if the method has multiple argument lists), + * the type itself for all other types. + * + * {{{ + * scala> class C { def foo[T](x: T)(y: T) = ??? } + * defined class C + * + * scala> typeOf[C].member(TermName("foo")).asMethod + * res0: reflect.runtime.universe.MethodSymbol = method foo + * + * scala> res0.info // PolyType wrapping a MethodType + * res1: reflect.runtime.universe.Type = [T](x: T)(y: T)scala.Nothing + * + * scala> res1.resultType // MethodType wrapping a MethodType + * res2: reflect.runtime.universe.Type = (x: T)(y: T)scala.Nothing + * + * scala> res1.resultType.resultType // vanilla MethodType + * res3: reflect.runtime.universe.Type = (y: T)scala.Nothing + * + * scala> res1.resultType.resultType.resultType + * res4: reflect.runtime.universe.Type = scala.Nothing + * + * scala> res1.finalResultType + * res5: reflect.runtime.universe.Type = scala.Nothing + * }}} + * + * @see finalResultType + */ + def resultType: Type + + /** For a curried/nullary method or poly type its non-method result type, + * the type itself for all other types. + * + * {{{ + * scala> class C { + * | def foo[T](x: T)(y: T) = ??? + * | def bar: Int = ??? + * | } + * defined class C + * + * scala> typeOf[C].member(TermName("foo")).asMethod + * res0: reflect.runtime.universe.MethodSymbol = method foo + * + * scala> res0.info // PolyType wrapping a MethodType + * res1: reflect.runtime.universe.Type = [T](x: T)(y: T)scala.Nothing + * + * scala> res1.resultType // MethodType wrapping a MethodType + * res2: reflect.runtime.universe.Type = (x: T)(y: T)scala.Nothing + * + * scala> res1.resultType.resultType // vanilla MethodType + * res3: reflect.runtime.universe.Type = (y: T)scala.Nothing + * + * scala> res1.resultType.resultType.resultType + * res4: reflect.runtime.universe.Type = scala.Nothing + * + * scala> res1.finalResultType + * res5: reflect.runtime.universe.Type = scala.Nothing + * + * scala> typeOf[C].member(TermName("bar")).asMethod + * res6: reflect.runtime.universe.MethodSymbol = method bar + * + * scala> res6.info + * res7: reflect.runtime.universe.Type = => scala.Int + * + * scala> res6.info.resultType + * res8: reflect.runtime.universe.Type = scala.Int + * + * scala> res6.info.finalResultType + * res9: reflect.runtime.universe.Type = scala.Int + * }}} + * + * @see resultType + */ + def finalResultType: Type + /******************* helpers *******************/ /** Provides an alternate if type is NoType. @@ -256,7 +400,12 @@ trait Types { * @template * @group Types */ - type SingletonType >: Null <: Type + type SingletonType >: Null <: SingletonTypeApi with Type + + /** Has no special methods. Is here to provides erased identity for `SingletonType`. + * @group API + */ + trait SingletonTypeApi /** A singleton type that describes types of the form on the left with the * corresponding `ThisType` representation to the right: @@ -266,7 +415,7 @@ trait Types { * @template * @group Types */ - type ThisType >: Null <: AnyRef with SingletonType with ThisTypeApi + type ThisType >: Null <: ThisTypeApi with SingletonType /** The constructor/extractor for `ThisType` instances. * @group Extractors @@ -278,11 +427,11 @@ trait Types { * @group Extractors */ abstract class ThisTypeExtractor { - /** - * Creates a ThisType from the given class symbol. - */ - def apply(sym: Symbol): Type def unapply(tpe: ThisType): Option[Symbol] + + /** @see [[InternalApi.thisType]] */ + @deprecated("Use `internal.thisType` instead", "2.11.0") + def apply(sym: Symbol)(implicit token: CompatToken): Type = internal.thisType(sym) } /** The API that all this types support. @@ -304,7 +453,7 @@ trait Types { * @template * @group Types */ - type SingleType >: Null <: AnyRef with SingletonType with SingleTypeApi + type SingleType >: Null <: SingleTypeApi with SingletonType /** The constructor/extractor for `SingleType` instances. * @group Extractors @@ -317,8 +466,11 @@ trait Types { * @group Extractors */ abstract class SingleTypeExtractor { - def apply(pre: Type, sym: Symbol): Type // not SingleTypebecause of implementation details def unapply(tpe: SingleType): Option[(Type, Symbol)] + + /** @see [[InternalApi.singleType]] */ + @deprecated("Use `ClassSymbol.thisPrefix` or `internal.singleType` instead") + def apply(pre: Type, sym: Symbol)(implicit token: CompatToken): Type = internal.singleType(pre, sym) } /** The API that all single types support. @@ -343,7 +495,7 @@ trait Types { * @template * @group Types */ - type SuperType >: Null <: AnyRef with SingletonType with SuperTypeApi + type SuperType >: Null <: SuperTypeApi with SingletonType /** The constructor/extractor for `SuperType` instances. * @group Extractors @@ -354,8 +506,11 @@ trait Types { * @group Extractors */ abstract class SuperTypeExtractor { - def apply(thistpe: Type, supertpe: Type): Type // not SuperTypebecause of implementation details def unapply(tpe: SuperType): Option[(Type, Type)] + + /** @see [[InternalApi.superType]] */ + @deprecated("Use `ClassSymbol.superPrefix` or `internal.superType` instead", "2.11.0") + def apply(thistpe: Type, supertpe: Type)(implicit token: CompatToken): Type = internal.superType(thistpe, supertpe) } /** The API that all super types support. @@ -382,7 +537,7 @@ trait Types { * @template * @group Types */ - type ConstantType >: Null <: AnyRef with SingletonType with ConstantTypeApi + type ConstantType >: Null <: ConstantTypeApi with SingletonType /** The constructor/extractor for `ConstantType` instances. * @group Extractors @@ -394,8 +549,11 @@ trait Types { * @group Extractors */ abstract class ConstantTypeExtractor { - def apply(value: Constant): ConstantType def unapply(tpe: ConstantType): Option[Constant] + + /** @see [[InternalApi.constantType]] */ + @deprecated("Use `value.tpe` or `internal.constantType` instead", "2.11.0") + def apply(value: Constant)(implicit token: CompatToken): ConstantType = internal.constantType(value) } /** The API that all constant types support. @@ -420,7 +578,7 @@ trait Types { * @template * @group Types */ - type TypeRef >: Null <: AnyRef with Type with TypeRefApi + type TypeRef >: Null <: TypeRefApi with Type /** The constructor/extractor for `TypeRef` instances. * @group Extractors @@ -434,8 +592,11 @@ trait Types { * @group Extractors */ abstract class TypeRefExtractor { - def apply(pre: Type, sym: Symbol, args: List[Type]): Type // not TypeRefbecause of implementation details def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])] + + /** @see [[InternalApi.typeRef]] */ + @deprecated("Use `internal.typeRef` instead", "2.11.0") + def apply(pre: Type, sym: Symbol, args: List[Type])(implicit token: CompatToken): Type = internal.typeRef(pre, sym, args) } /** The API that all type refs support. @@ -461,7 +622,12 @@ trait Types { * @template * @group Types */ - type CompoundType >: Null <: AnyRef with Type + type CompoundType >: Null <: CompoundTypeApi with Type + + /** Has no special methods. Is here to provides erased identity for `CompoundType`. + * @group API + */ + trait CompoundTypeApi /** The `RefinedType` type defines types of any of the forms on the left, * with their RefinedType representations to the right. @@ -473,7 +639,7 @@ trait Types { * @template * @group Types */ - type RefinedType >: Null <: AnyRef with CompoundType with RefinedTypeApi + type RefinedType >: Null <: RefinedTypeApi with CompoundType /** The constructor/extractor for `RefinedType` instances. * @group Extractors @@ -486,13 +652,11 @@ trait Types { * @group Extractors */ abstract class RefinedTypeExtractor { - def apply(parents: List[Type], decls: Scope): RefinedType - - /** An alternative constructor that passes in the synthetic classs symbol - * that backs the refined type. (Normally, a fresh class symbol is created automatically). - */ - def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType def unapply(tpe: RefinedType): Option[(List[Type], Scope)] + + /** @see [[InternalApi.refinedType]] */ + @deprecated("Use `internal.refinedType` instead", "2.11.0") + def apply(parents: List[Type], decls: Scope)(implicit token: CompatToken): RefinedType = internal.refinedType(parents, decls) } /** The API that all refined types support. @@ -504,7 +668,7 @@ trait Types { def parents: List[Type] /** The scope that holds the definitions comprising the type. */ - def decls: Scope + def decls: MemberScope } /** The `ClassInfo` type signature is used to define parents and declarations @@ -519,7 +683,7 @@ trait Types { * @template * @group Types */ - type ClassInfoType >: Null <: AnyRef with CompoundType with ClassInfoTypeApi + type ClassInfoType >: Null <: ClassInfoTypeApi with CompoundType /** The constructor/extractor for `ClassInfoType` instances. * @group Extractors @@ -533,8 +697,11 @@ trait Types { * @group Extractors */ abstract class ClassInfoTypeExtractor { - def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)] + + /** @see [[InternalApi.classInfoType]] */ + @deprecated("Use `internal.classInfoType` instead", "2.11.0") + def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol)(implicit token: CompatToken): ClassInfoType = internal.classInfoType(parents, decls, typeSymbol) } /** The API that all class info types support. @@ -546,7 +713,7 @@ trait Types { def parents: List[Type] /** The scope that holds the definitions comprising the class type. */ - def decls: Scope + def decls: MemberScope /** The symbol underlying the class type. */ def typeSymbol: Symbol @@ -556,7 +723,7 @@ trait Types { * @template * @group Types */ - type MethodType >: Null <: AnyRef with Type with MethodTypeApi + type MethodType >: Null <: MethodTypeApi with Type /** The constructor/extractor for `MethodType` instances. * @group Extractors @@ -579,8 +746,11 @@ trait Types { * @group Extractors */ abstract class MethodTypeExtractor { - def apply(params: List[Symbol], resultType: Type): MethodType def unapply(tpe: MethodType): Option[(List[Symbol], Type)] + + /** @see [[InternalApi.methodType]] */ + @deprecated("Use `internal.methodType` instead", "2.11.0") + def apply(params: List[Symbol], resultType: Type)(implicit token: CompatToken): MethodType = internal.methodType(params, resultType) } /** The API that all method types support. @@ -600,7 +770,7 @@ trait Types { * @template * @group Types */ - type NullaryMethodType >: Null <: AnyRef with Type with NullaryMethodTypeApi + type NullaryMethodType >: Null <: NullaryMethodTypeApi with Type /** The constructor/extractor for `NullaryMethodType` instances. * @group Extractors @@ -612,8 +782,11 @@ trait Types { * @group Extractors */ abstract class NullaryMethodTypeExtractor { - def apply(resultType: Type): NullaryMethodType def unapply(tpe: NullaryMethodType): Option[(Type)] + + /** @see [[InternalApi.nullaryMethodType]] */ + @deprecated("Use `internal.nullaryMethodType` instead", "2.11.0") + def apply(resultType: Type)(implicit token: CompatToken): NullaryMethodType = internal.nullaryMethodType(resultType) } /** The API that all nullary method types support. @@ -630,7 +803,7 @@ trait Types { * @template * @group Types */ - type PolyType >: Null <: AnyRef with Type with PolyTypeApi + type PolyType >: Null <: PolyTypeApi with Type /** The constructor/extractor for `PolyType` instances. * @group Extractors @@ -643,8 +816,11 @@ trait Types { * @group Extractors */ abstract class PolyTypeExtractor { - def apply(typeParams: List[Symbol], resultType: Type): PolyType def unapply(tpe: PolyType): Option[(List[Symbol], Type)] + + /** @see [[InternalApi.polyType]] */ + @deprecated("Use `internal.polyType` instead", "2.11.0") + def apply(typeParams: List[Symbol], resultType: Type)(implicit token: CompatToken): PolyType = internal.polyType(typeParams, resultType) } /** The API that all polymorphic types support. @@ -664,7 +840,7 @@ trait Types { * @template * @group Types */ - type ExistentialType >: Null <: AnyRef with Type with ExistentialTypeApi + type ExistentialType >: Null <: ExistentialTypeApi with Type /** The constructor/extractor for `ExistentialType` instances. * @group Extractors @@ -678,8 +854,11 @@ trait Types { * @group Extractors */ abstract class ExistentialTypeExtractor { - def apply(quantified: List[Symbol], underlying: Type): ExistentialType def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)] + + /** @see [[InternalApi.existentialType]] */ + @deprecated("Use `internal.existentialType` instead", "2.11.0") + def apply(quantified: List[Symbol], underlying: Type)(implicit token: CompatToken): ExistentialType = internal.existentialType(quantified, underlying) } /** The API that all existential types support. @@ -699,7 +878,7 @@ trait Types { * @template * @group Types */ - type AnnotatedType >: Null <: AnyRef with Type with AnnotatedTypeApi + type AnnotatedType >: Null <: AnnotatedTypeApi with Type /** The constructor/extractor for `AnnotatedType` instances. * @group Extractors @@ -713,8 +892,11 @@ trait Types { * @group Extractors */ abstract class AnnotatedTypeExtractor { - def apply(annotations: List[Annotation], underlying: Type): AnnotatedType def unapply(tpe: AnnotatedType): Option[(List[Annotation], Type)] + + /** @see [[InternalApi.annotatedType]] */ + @deprecated("Use `internal.annotatedType` instead", "2.11.0") + def apply(annotations: List[Annotation], underlying: Type)(implicit token: CompatToken): AnnotatedType = internal.annotatedType(annotations, underlying) } /** The API that all annotated types support. @@ -741,7 +923,7 @@ trait Types { * @template * @group Types */ - type TypeBounds >: Null <: AnyRef with Type with TypeBoundsApi + type TypeBounds >: Null <: TypeBoundsApi with Type /** The constructor/extractor for `TypeBounds` instances. * @group Extractors @@ -754,8 +936,11 @@ trait Types { * @group Extractors */ abstract class TypeBoundsExtractor { - def apply(lo: Type, hi: Type): TypeBounds def unapply(tpe: TypeBounds): Option[(Type, Type)] + + /** @see [[InternalApi.typeBounds]] */ + @deprecated("Use `internal.typeBounds` instead", "2.11.0") + def apply(lo: Type, hi: Type)(implicit token: CompatToken): TypeBounds = internal.typeBounds(lo, hi) } /** The API that all type bounds support. @@ -792,7 +977,7 @@ trait Types { * @template * @group Types */ - type BoundedWildcardType >: Null <: AnyRef with Type with BoundedWildcardTypeApi + type BoundedWildcardType >: Null <: BoundedWildcardTypeApi with Type /** The constructor/extractor for `BoundedWildcardType` instances. * @group Extractors @@ -804,8 +989,11 @@ trait Types { * @group Extractors */ abstract class BoundedWildcardTypeExtractor { - def apply(bounds: TypeBounds): BoundedWildcardType def unapply(tpe: BoundedWildcardType): Option[TypeBounds] + + /** @see [[InternalApi.boundedWildcardType]] */ + @deprecated("Use `internal.boundedWildcardType` instead", "2.11.0") + def apply(bounds: TypeBounds)(implicit token: CompatToken): BoundedWildcardType = internal.boundedWildcardType(bounds) } /** The API that all this types support. @@ -827,74 +1015,17 @@ trait Types { */ def glb(ts: List[Type]): Type - // Creators --------------------------------------------------------------- - // too useful and too non-trivial to be left out of public API - - /** The canonical creator for single-types - * @group TypeCreators - */ - def singleType(pre: Type, sym: Symbol): Type - - /** the canonical creator for a refined type with a given scope - * @group TypeCreators - */ - def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type - - /** The canonical creator for a refined type with an initially empty scope. - * @group TypeCreators - */ - def refinedType(parents: List[Type], owner: Symbol): Type - - /** The canonical creator for typerefs - * @group TypeCreators - */ - def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type - - /** A creator for intersection type where intersections of a single type are - * replaced by the type itself. - * @group TypeCreators - */ - def intersectionType(tps: List[Type]): Type - - /** A creator for intersection type where intersections of a single type are - * replaced by the type itself, and repeated parent classes are merged. - * - * !!! Repeated parent classes are not merged - is this a bug in the - * comment or in the code? - * @group TypeCreators - */ - def intersectionType(tps: List[Type], owner: Symbol): Type - /** A creator for type applications - * @group Types + * @group TypeOps */ def appliedType(tycon: Type, args: List[Type]): Type - /** A creator for type parameterizations that strips empty type parameter lists. - * Use this factory method to indicate the type has kind * (it's a polymorphic value) - * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty). - * @group Types - */ - def polyType(tparams: List[Symbol], tpe: Type): Type + /** @see [[appliedType]] */ + def appliedType(tycon: Type, args: Type*): Type - /** A creator for existential types. This generates: - * - * {{{ - * tpe1 where { tparams } - * }}} - * - * where `tpe1` is the result of extrapolating `tpe` with regard to `tparams`. - * Extrapolating means that type variables in `tparams` occurring - * in covariant positions are replaced by upper bounds, (minus any - * SingletonClass markers), type variables in `tparams` occurring in - * contravariant positions are replaced by upper bounds, provided the - * resulting type is legal with regard to stability, and does not contain - * any type variable in `tparams`. - * - * The abstraction drops all type parameters that are not directly or - * indirectly referenced by type `tpe1`. If there are no remaining type - * parameters, simply returns result type `tpe`. - * @group TypeCreators - */ - def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type + /** @see [[appliedType]] */ + def appliedType(sym: Symbol, args: List[Type]): Type + + /** @see [[appliedType]] */ + def appliedType(sym: Symbol, args: Type*): Type } diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala index 85a8ee0185..a3d1d291eb 100644 --- a/src/reflect/scala/reflect/api/Universe.scala +++ b/src/reflect/scala/reflect/api/Universe.scala @@ -69,17 +69,15 @@ abstract class Universe extends Symbols with Positions with Exprs with TypeTags - with TagInterop with ImplicitTags with StandardDefinitions with StandardNames with StandardLiftables - with BuildUtils with Mirrors with Printers - with Importers with Liftables with Quasiquotes + with Internals { /** Use `reify` to produce the abstract syntax tree representing a given Scala expression. * diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index d634034fe9..19e9eef851 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -10,10 +10,12 @@ package internal import pickling.ByteCodecs import scala.annotation.tailrec import scala.collection.immutable.ListMap +import scala.language.postfixOps /** AnnotationInfo and its helpers */ trait AnnotationInfos extends api.Annotations { self: SymbolTable => - import definitions.{ ThrowsClass, ThrowableClass, StaticAnnotationClass, isMetaAnnotation } + import definitions._ + import treeInfo._ // Common annotation code between Symbol and Type. // For methods altering the annotation list, on Symbol it mutates @@ -75,7 +77,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => * - arrays of constants * - or nested classfile annotations */ - sealed abstract class ClassfileAnnotArg extends Product + sealed abstract class ClassfileAnnotArg extends Product with JavaArgumentApi implicit val JavaArgumentTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg]) case object UnmappableAnnotArg extends ClassfileAnnotArg @@ -344,6 +346,63 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => } implicit val AnnotationTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo]) + protected[scala] def annotationToTree(ann: Annotation): Tree = { + def reverseEngineerArgs(): List[Tree] = { + def reverseEngineerArg(jarg: ClassfileAnnotArg): Tree = jarg match { + case LiteralAnnotArg(const) => + val tpe = if (const.tag == UnitTag) UnitTpe else ConstantType(const) + Literal(const) setType tpe + case ArrayAnnotArg(jargs) => + val args = jargs map reverseEngineerArg + // TODO: I think it would be a good idea to typecheck Java annotations using a more traditional algorithm + // sure, we can't typecheck them as is using the `new jann(foo = bar)` syntax (because jann is going to be an @interface) + // however we can do better than `typedAnnotation` by desugaring the aforementioned expression to + // something like `new jann() { override def annotatedType() = ...; override def foo = bar }` + // and then using the results of that typecheck to produce a Java-compatible classfile entry + // in that case we're going to have correctly typed Array.apply calls, however that's 2.12 territory + // and for 2.11 exposing an untyped call to ArrayModule should suffice + Apply(Ident(ArrayModule), args.toList) + case NestedAnnotArg(ann: Annotation) => + annotationToTree(ann) + case _ => + EmptyTree + } + def reverseEngineerArgs(jargs: List[(Name, ClassfileAnnotArg)]): List[Tree] = jargs match { + case (name, jarg) :: rest => AssignOrNamedArg(Ident(name), reverseEngineerArg(jarg)) :: reverseEngineerArgs(rest) + case Nil => Nil + } + if (ann.javaArgs.isEmpty) ann.scalaArgs + else reverseEngineerArgs(ann.javaArgs.toList) + } + + // TODO: at the moment, constructor selection is unattributed, because AnnotationInfos lack necessary information + // later on, in 2.12, for every annotation we could save an entire tree instead of just bits and pieces + // but for 2.11 the current situation will have to do + val ctorSelection = Select(New(TypeTree(ann.atp)), nme.CONSTRUCTOR) + Apply(ctorSelection, reverseEngineerArgs()) setType ann.atp + } + + protected[scala] def treeToAnnotation(tree: Tree): Annotation = tree match { + case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => + def encodeJavaArg(arg: Tree): ClassfileAnnotArg = arg match { + case Literal(const) => LiteralAnnotArg(const) + case Apply(ArrayModule, args) => ArrayAnnotArg(args map encodeJavaArg toArray) + case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => NestedAnnotArg(treeToAnnotation(arg)) + case _ => throw new Exception("unexpected java argument shape $arg: literals, arrays and nested annotations are supported") + } + def encodeJavaArgs(args: List[Tree]): List[(Name, ClassfileAnnotArg)] = args match { + case AssignOrNamedArg(Ident(name), arg) :: rest => (name, encodeJavaArg(arg)) :: encodeJavaArgs(rest) + case arg :: rest => throw new Exception("unexpected java argument shape $arg: only AssignOrNamedArg trees are supported") + case Nil => Nil + } + val atp = tpt.tpe + if (atp != null && (atp.typeSymbol isNonBottomSubClass StaticAnnotationClass)) AnnotationInfo(atp, args, Nil) + else if (atp != null && (atp.typeSymbol isNonBottomSubClass ClassfileAnnotationClass)) AnnotationInfo(atp, Nil, encodeJavaArgs(args)) + else throw new Exception(s"unexpected annotation type $atp: only subclasses of StaticAnnotation and ClassfileAnnotation are supported") + case _ => + throw new Exception("""unexpected tree shape: only q"new $annType(..$args)" is supported""") + } + object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) object ErroneousAnnotation extends CompleteAnnotationInfo(ErrorType, Nil, Nil) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 645d6aa4ff..2567abe51d 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -461,6 +461,9 @@ trait Definitions extends api.StandardDefinitions { def ReflectRuntimeUniverse = ReflectRuntimePackage.map(sym => getMemberValue(sym, nme.universe)) def ReflectRuntimeCurrentMirror = ReflectRuntimePackage.map(sym => getMemberMethod(sym, nme.currentMirror)) + lazy val UniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful + def UniverseInternal = getMemberValue(UniverseClass, nme.internal) + lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifestFactory.type] lazy val FullManifestClass = requiredClass[scala.reflect.Manifest[_]] lazy val FullManifestModule = requiredModule[scala.reflect.ManifestFactory.type] diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala index 799f85054a..ef9c77878f 100644 --- a/src/reflect/scala/reflect/internal/FlagSets.scala +++ b/src/reflect/scala/reflect/internal/FlagSets.scala @@ -42,7 +42,11 @@ trait FlagSets extends api.FlagSets { self: SymbolTable => val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM val PRESUPER : FlagSet = Flags.PRESUPER val DEFAULTINIT : FlagSet = Flags.DEFAULTINIT - val SYNTHETIC : FlagSet = Flags.SYNTHETIC val ENUM : FlagSet = Flags.ENUM + val PARAMACCESSOR : FlagSet = Flags.PARAMACCESSOR + val CASEACCESSOR : FlagSet = Flags.CASEACCESSOR + val SYNTHETIC : FlagSet = Flags.SYNTHETIC + val ARTIFACT : FlagSet = Flags.ARTIFACT + val STABLE : FlagSet = Flags.STABLE } } diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala index e66ed9a3d4..1707061817 100644 --- a/src/reflect/scala/reflect/internal/Flags.scala +++ b/src/reflect/scala/reflect/internal/Flags.scala @@ -118,22 +118,10 @@ class ModifierFlags { final val PRESUPER = 1L << 37 // value is evaluated before super call final val DEFAULTINIT = 1L << 41 // symbol is initialized to the default value: used by -Xcheckinit final val ARTIFACT = 1L << 46 // symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode + // to see which symbols are marked as ARTIFACT, see scaladocs for FlagValues.ARTIFACT final val DEFAULTMETHOD = 1L << 47 // symbol is a java default method final val ENUM = 1L << 48 // symbol is an enum - /** Symbols which are marked ARTIFACT. (Expand this list?) - * - * - $outer fields and accessors - * - super accessors - * - protected accessors - * - lazy local accessors - * - bridge methods - * - default argument getters - * - evaluation-order preserving locals for right-associative and out-of-order named arguments - * - catch-expression storing vals - * - anything else which feels a setFlag(ARTIFACT) - */ - // Overridden. def flagToString(flag: Long): String = "" diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala index 1131c94da0..aa8f4c532e 100644 --- a/src/reflect/scala/reflect/internal/HasFlags.scala +++ b/src/reflect/scala/reflect/internal/HasFlags.scala @@ -83,7 +83,9 @@ trait HasFlags { def hasAccessorFlag = hasFlag(ACCESSOR) def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT def hasEnumFlag = hasFlag(ENUM) + @deprecated("Use isLocalToThis instead", "2.11.0") def hasLocalFlag = hasFlag(LOCAL) + def isLocalToThis = hasFlag(LOCAL) def hasModuleFlag = hasFlag(MODULE) def hasPackageFlag = hasFlag(PACKAGE) def hasStableFlag = hasFlag(STABLE) @@ -106,6 +108,7 @@ trait HasFlags { def isOverride = hasFlag(OVERRIDE) def isParamAccessor = hasFlag(PARAMACCESSOR) def isPrivate = hasFlag(PRIVATE) + @deprecated ("Use `hasPackageFlag` instead", "2.11.0") def isPackage = hasFlag(PACKAGE) def isPrivateLocal = hasAllFlags(PrivateLocal) def isProtected = hasFlag(PROTECTED) diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala index ff91b08ea1..dc4ad25ef2 100644 --- a/src/reflect/scala/reflect/internal/Importers.scala +++ b/src/reflect/scala/reflect/internal/Importers.scala @@ -7,19 +7,9 @@ import scala.ref.WeakReference import scala.reflect.internal.Flags._ // SI-6241: move importers to a mirror -trait Importers extends api.Importers { to: SymbolTable => +trait Importers { to: SymbolTable => - /** Attachment that knows how to import itself into another universe. */ - trait ImportableAttachment { - def importAttachment(importer: Importer): this.type - } - - /** Attachment that doesn't contain any reflection artificats and can be imported as-is. */ - trait PlainAttachment extends ImportableAttachment { - def importAttachment(importer: Importer): this.type = this - } - - def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( + override def mkImporter(from0: api.Universe): Importer { val from: from0.type } = ( if (to eq from0) { new Importer { val from = from0 diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala new file mode 100644 index 0000000000..e8bf842e6e --- /dev/null +++ b/src/reflect/scala/reflect/internal/Internals.scala @@ -0,0 +1,173 @@ +package scala +package reflect +package internal + +import scala.language.implicitConversions +import scala.language.higherKinds +import scala.collection.mutable.WeakHashMap +import scala.ref.WeakReference +import scala.reflect.api.Universe +import scala.reflect.macros.Attachments +import scala.reflect.internal.util.FreshNameCreator +import scala.reflect.internal.Flags._ +import scala.reflect.internal.util.ListOfNil + +trait Internals extends api.Internals { + self: SymbolTable => + + type Internal = MacroInternalApi + lazy val internal: Internal = new SymbolTableInternal {} + + type Compat = MacroCompatApi + lazy val compat: Compat = new Compat {} + + trait SymbolTableInternal extends MacroInternalApi { + lazy val reificationSupport: ReificationSupportApi = self.build + + def createImporter(from0: Universe): Importer { val from: from0.type } = self.mkImporter(from0) + + def newScopeWith(elems: Symbol*): Scope = self.newScopeWith(elems: _*) + def enter(scope: Scope, sym: Symbol): scope.type = { scope.enter(sym); scope } + def unlink(scope: Scope, sym: Symbol): scope.type = { scope.unlink(sym); scope } + + def freeTerms(tree: Tree): List[FreeTermSymbol] = tree.freeTerms + def freeTypes(tree: Tree): List[FreeTypeSymbol] = tree.freeTypes + def substituteSymbols(tree: Tree, from: List[Symbol], to: List[Symbol]): Tree = tree.substituteSymbols(from, to) + def substituteTypes(tree: Tree, from: List[Symbol], to: List[Type]): Tree = tree.substituteTypes(from, to) + def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree = tree.substituteThis(clazz, to) + def attachments(tree: Tree): Attachments { type Pos = Position } = tree.attachments + def updateAttachment[T: ClassTag](tree: Tree, attachment: T): tree.type = tree.updateAttachment(attachment) + def removeAttachment[T: ClassTag](tree: Tree): tree.type = tree.removeAttachment[T] + def setPos(tree: Tree, newpos: Position): tree.type = tree.setPos(newpos) + def setType(tree: Tree, tp: Type): tree.type = tree.setType(tp) + def defineType(tree: Tree, tp: Type): tree.type = tree.defineType(tp) + def setSymbol(tree: Tree, sym: Symbol): tree.type = tree.setSymbol(sym) + def setOriginal(tt: TypeTree, tree: Tree): TypeTree = tt.setOriginal(tree) + + def captureVariable(vble: Symbol): Unit = self.captureVariable(vble) + def referenceCapturedVariable(vble: Symbol): Tree = self.referenceCapturedVariable(vble) + def capturedVariableType(vble: Symbol): Type = self.capturedVariableType(vble) + + def classDef(sym: Symbol, impl: Template): ClassDef = self.ClassDef(sym, impl) + def moduleDef(sym: Symbol, impl: Template): ModuleDef = self.ModuleDef(sym, impl) + def valDef(sym: Symbol, rhs: Tree): ValDef = self.ValDef(sym, rhs) + def valDef(sym: Symbol): ValDef = self.ValDef(sym) + def defDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = self.DefDef(sym, mods, vparamss, rhs) + def defDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = self.DefDef(sym, vparamss, rhs) + def defDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = self.DefDef(sym, mods, rhs) + def defDef(sym: Symbol, rhs: Tree): DefDef = self.DefDef(sym, rhs) + def defDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = self.DefDef(sym, rhs) + def typeDef(sym: Symbol, rhs: Tree): TypeDef = self.TypeDef(sym, rhs) + def typeDef(sym: Symbol): TypeDef = self.TypeDef(sym) + def labelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = self.LabelDef(sym, params, rhs) + + def changeOwner(tree: Tree, prev: Symbol, next: Symbol): tree.type = { + object changeOwnerAndModuleClassTraverser extends ChangeOwnerTraverser(prev, next) { + override def traverse(tree: Tree) { + tree match { + case _: DefTree => change(tree.symbol.moduleClass) + case _ => // do nothing + } + super.traverse(tree) + } + } + changeOwnerAndModuleClassTraverser.traverse(tree) + tree + } + + lazy val gen = self.treeBuild + + def isFreeTerm(symbol: Symbol): Boolean = symbol.isFreeTerm + def asFreeTerm(symbol: Symbol): FreeTermSymbol = symbol.asFreeTerm + def isFreeType(symbol: Symbol): Boolean = symbol.isFreeType + def asFreeType(symbol: Symbol): FreeTypeSymbol = symbol.asFreeType + def newTermSymbol(symbol: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = symbol.newTermSymbol(name, pos, flags) + def newModuleAndClassSymbol(symbol: Symbol, name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = symbol.newModuleAndClassSymbol(name, pos, flags) + def newMethodSymbol(symbol: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol = symbol.newMethodSymbol(name, pos, flags) + def newTypeSymbol(symbol: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = symbol.newTypeSymbol(name, pos, flags) + def newClassSymbol(symbol: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = symbol.newClassSymbol(name, pos, flags) + def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol = reificationSupport.newFreeTerm(name, value, flags, origin) + def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol = reificationSupport.newFreeType(name, flags, origin) + def isErroneous(symbol: Symbol): Boolean = symbol.isErroneous + def isSkolem(symbol: Symbol): Boolean = symbol.isSkolem + def deSkolemize(symbol: Symbol): Symbol = symbol.deSkolemize + def initialize(symbol: Symbol): symbol.type = symbol.initialize + def fullyInitialize(symbol: Symbol): symbol.type = definitions.fullyInitializeSymbol(symbol).asInstanceOf[symbol.type] + def fullyInitialize(tp: Type): tp.type = definitions.fullyInitializeType(tp).asInstanceOf[tp.type] + def fullyInitialize(scope: Scope): scope.type = definitions.fullyInitializeScope(scope).asInstanceOf[scope.type] + def flags(symbol: Symbol): FlagSet = symbol.flags + def attachments(symbol: Symbol): Attachments { type Pos = Position } = symbol.attachments + def updateAttachment[T: ClassTag](symbol: Symbol, attachment: T): symbol.type = symbol.updateAttachment(attachment) + def removeAttachment[T: ClassTag](symbol: Symbol): symbol.type = symbol.removeAttachment[T] + def setOwner(symbol: Symbol, newowner: Symbol): symbol.type = { symbol.owner = newowner; symbol } + def setInfo(symbol: Symbol, tpe: Type): symbol.type = symbol.setInfo(tpe) + def setAnnotations(symbol: Symbol, annots: Annotation*): symbol.type = symbol.setAnnotations(annots: _*) + def setName(symbol: Symbol, name: Name): symbol.type = symbol.setName(name) + def setPrivateWithin(symbol: Symbol, sym: Symbol): symbol.type = symbol.setPrivateWithin(sym) + def setFlag(symbol: Symbol, flags: FlagSet): symbol.type = symbol.setFlag(flags) + def resetFlag(symbol: Symbol, flags: FlagSet): symbol.type = symbol.resetFlag(flags) + + def thisType(sym: Symbol): Type = self.ThisType(sym) + def singleType(pre: Type, sym: Symbol): Type = self.SingleType(pre, sym) + def superType(thistpe: Type, supertpe: Type): Type = self.SuperType(thistpe, supertpe) + def constantType(value: Constant): ConstantType = self.ConstantType(value) + def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = self.TypeRef(pre, sym, args) + def refinedType(parents: List[Type], decls: Scope): RefinedType = self.RefinedType(parents, decls) + def refinedType(parents: List[Type], owner: Symbol): Type = self.refinedType(parents, owner) + def refinedType(parents: List[Type], owner: Symbol, decls: Scope): Type = self.RefinedType(parents, decls, owner) + def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type = self.refinedType(parents, owner, decls, pos) + def intersectionType(tps: List[Type]): Type = self.intersectionType(tps) + def intersectionType(tps: List[Type], owner: Symbol): Type = self.intersectionType(tps, owner) + def classInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType = self.ClassInfoType(parents, decls, typeSymbol) + def methodType(params: List[Symbol], resultType: Type): MethodType = self.MethodType(params, resultType) + def nullaryMethodType(resultType: Type): NullaryMethodType = self.NullaryMethodType(resultType) + def polyType(typeParams: List[Symbol], resultType: Type): PolyType = self.PolyType(typeParams, resultType) + def existentialType(quantified: List[Symbol], underlying: Type): ExistentialType = self.ExistentialType(quantified, underlying) + def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type = self.existentialAbstraction(tparams, tpe0) + def annotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType = self.AnnotatedType(annotations, underlying) + def typeBounds(lo: Type, hi: Type): TypeBounds = self.TypeBounds(lo, hi) + def boundedWildcardType(bounds: TypeBounds): BoundedWildcardType = self.BoundedWildcardType(bounds) + + def subpatterns(tree: Tree): Option[List[Tree]] = tree.attachments.get[SubpatternsAttachment].map(_.patterns.map(_.duplicate)) + + type Decorators = MacroDecoratorApi + lazy val decorators: Decorators = new MacroDecoratorApi { + override type ScopeDecorator[T <: Scope] = MacroScopeDecoratorApi[T] + override implicit def scopeDecorator[T <: Scope](scope: T): ScopeDecorator[T] = new MacroScopeDecoratorApi[T](scope) + override type TreeDecorator[T <: Tree] = MacroTreeDecoratorApi[T] + override implicit def treeDecorator[T <: Tree](tree: T): TreeDecorator[T] = new MacroTreeDecoratorApi[T](tree) + override type TypeTreeDecorator[T <: TypeTree] = MacroTypeTreeDecoratorApi[T] + override implicit def typeTreeDecorator[T <: TypeTree](tt: T): TypeTreeDecorator[T] = new MacroTypeTreeDecoratorApi[T](tt) + override type SymbolDecorator[T <: Symbol] = MacroSymbolDecoratorApi[T] + override implicit def symbolDecorator[T <: Symbol](symbol: T): SymbolDecorator[T] = new MacroSymbolDecoratorApi[T](symbol) + override type TypeDecorator[T <: Type] = TypeDecoratorApi[T] + override implicit def typeDecorator[T <: Type](tp: T): TypeDecorator[T] = new TypeDecoratorApi[T](tp) + } + } + + lazy val treeBuild = new self.TreeGen { + def mkAttributedQualifier(tpe: Type): Tree = self.gen.mkAttributedQualifier(tpe) + def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = self.gen.mkAttributedQualifier(tpe, termSym) + def mkAttributedRef(pre: Type, sym: Symbol): RefTree = self.gen.mkAttributedRef(pre, sym) + def mkAttributedRef(sym: Symbol): RefTree = self.gen.mkAttributedRef(sym) + def stabilize(tree: Tree): Tree = self.gen.stabilize(tree) + def mkAttributedStableRef(pre: Type, sym: Symbol): Tree = self.gen.mkAttributedStableRef(pre, sym) + def mkAttributedStableRef(sym: Symbol): Tree = self.gen.mkAttributedStableRef(sym) + def mkUnattributedRef(sym: Symbol): RefTree = self.gen.mkUnattributedRef(sym) + def mkUnattributedRef(fullName: Name): RefTree = self.gen.mkUnattributedRef(fullName) + def mkAttributedThis(sym: Symbol): This = self.gen.mkAttributedThis(sym) + def mkAttributedIdent(sym: Symbol): RefTree = self.gen.mkAttributedIdent(sym) + def mkAttributedSelect(qual: Tree, sym: Symbol): RefTree = self.gen.mkAttributedSelect(qual, sym) + def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(receiver, methodName, targs, args) + def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(method, targs, args) + def mkMethodCall(method: Symbol, args: List[Tree]): Tree = self.gen.mkMethodCall(method, args) + def mkMethodCall(target: Tree, args: List[Tree]): Tree = self.gen.mkMethodCall(target, args) + def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree = self.gen.mkMethodCall(receiver, methodName, args) + def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(receiver, method, targs, args) + def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(target, targs, args) + def mkNullaryCall(method: Symbol, targs: List[Type]): Tree = self.gen.mkNullaryCall(method, targs) + def mkRuntimeUniverseRef: Tree = self.gen.mkRuntimeUniverseRef + def mkZero(tp: Type): Tree = self.gen.mkZero(tp) + def mkCast(tree: Tree, pt: Type): Tree = self.gen.mkCast(tree, pt) + } +}
\ No newline at end of file diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 6cf4944d18..7065a8cd6d 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -117,14 +117,15 @@ trait Mirrors extends api.Mirrors { * Compiler might ignore them, but they should be loadable with macros. */ override def staticClass(fullname: String): ClassSymbol = - ensureClassSymbol(fullname, staticModuleOrClass(newTypeNameCached(fullname))) + try ensureClassSymbol(fullname, staticModuleOrClass(newTypeNameCached(fullname))) + catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) } /************************ loaders of module symbols ************************/ private def ensureModuleSymbol(fullname: String, sym: Symbol, allowPackages: Boolean): ModuleSymbol = sym match { - case x: ModuleSymbol if allowPackages || !x.isPackage => x - case _ => MissingRequirementError.notFound("object " + fullname) + case x: ModuleSymbol if allowPackages || !x.hasPackageFlag => x + case _ => MissingRequirementError.notFound("object " + fullname) } def getModuleByName(fullname: Name): ModuleSymbol = @@ -155,14 +156,15 @@ trait Mirrors extends api.Mirrors { * Compiler might ignore them, but they should be loadable with macros. */ override def staticModule(fullname: String): ModuleSymbol = - ensureModuleSymbol(fullname, staticModuleOrClass(newTermNameCached(fullname)), allowPackages = false) + try ensureModuleSymbol(fullname, staticModuleOrClass(newTermNameCached(fullname)), allowPackages = false) + catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) } /************************ loaders of package symbols ************************/ private def ensurePackageSymbol(fullname: String, sym: Symbol, allowModules: Boolean): ModuleSymbol = sym match { - case x: ModuleSymbol if allowModules || x.isPackage => x - case _ => MissingRequirementError.notFound("package " + fullname) + case x: ModuleSymbol if allowModules || x.hasPackageFlag => x + case _ => MissingRequirementError.notFound("package " + fullname) } def getPackage(fullname: TermName): ModuleSymbol = @@ -186,18 +188,19 @@ trait Mirrors extends api.Mirrors { def getPackageObjectIfDefined(fullname: TermName): Symbol = wrapMissing(getPackageObject(fullname)) - + final def getPackageObjectWithMember(pre: Type, sym: Symbol): Symbol = { // The owner of a symbol which requires package qualification may be the // package object iself, but it also could be any superclass of the package // object. In the latter case, we must go through the qualifier's info // to obtain the right symbol. - if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object + if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object else pre member nme.PACKAGE // otherwise we have to findMember } override def staticPackage(fullname: String): ModuleSymbol = - ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false) + try ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false) + catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) } /************************ helpers ************************/ diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala index 73ce59feb2..ae9f2da4e5 100644 --- a/src/reflect/scala/reflect/internal/Names.scala +++ b/src/reflect/scala/reflect/internal/Names.scala @@ -535,7 +535,7 @@ trait Names extends api.Names { } // SYNCNOTE: caller to constructor must synchronize if `synchronizeNames` is enabled - sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) { + sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) with TermNameApi { type ThisNameType = TermName protected[this] def thisName: TermName = this val next: TermName = termHashtable(hash) @@ -572,7 +572,7 @@ trait Names extends api.Names { def unapply(name: TermName): Option[String] = Some(name.toString) } - sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) { + sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) with TypeNameApi { type ThisNameType = TypeName protected[this] def thisName: TypeName = this diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index 6734a2bd5a..b1d76b6056 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -1214,17 +1214,17 @@ trait Printers extends api.Printers { self: SymbolTable => } def show(name: Name): String = name match { - case tpnme.WILDCARD => "tpnme.WILDCARD" - case tpnme.EMPTY => "tpnme.EMPTY" - case tpnme.ERROR => "tpnme.ERROR" - case tpnme.PACKAGE => "tpnme.PACKAGE" - case tpnme.WILDCARD_STAR => "tpnme.WILDCARD_STAR" - case nme.WILDCARD => "nme.WILDCARD" - case nme.EMPTY => "nme.EMPTY" - case nme.ERROR => "tpnme.ERROR" - case nme.PACKAGE => "nme.PACKAGE" - case nme.CONSTRUCTOR => "nme.CONSTRUCTOR" - case nme.ROOTPKG => "nme.ROOTPKG" + case tpnme.WILDCARD => "typeNames.WILDCARD" + case tpnme.EMPTY => "typeNames.EMPTY" + case tpnme.ERROR => "typeNames.ERROR" + case tpnme.PACKAGE => "typeNames.PACKAGE" + case tpnme.WILDCARD_STAR => "typeNames.WILDCARD_STAR" + case nme.WILDCARD => "termNames.WILDCARD" + case nme.EMPTY => "termNames.EMPTY" + case nme.ERROR => "termNames.ERROR" + case nme.PACKAGE => "termNames.PACKAGE" + case nme.CONSTRUCTOR => "termNames.CONSTRUCTOR" + case nme.ROOTPKG => "termNames.ROOTPKG" case _ => val prefix = if (name.isTermName) "TermName(\"" else "TypeName(\"" prefix + name.toString + "\")" @@ -1240,4 +1240,13 @@ trait Printers extends api.Printers { self: SymbolTable => s_flags mkString " | " } } + + def show(position: Position): String = { + position.show + } + + def showDecl(sym: Symbol): String = { + if (!isCompilerUniverse) definitions.fullyInitializeSymbol(sym) + sym.defString + } } diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala index 0c7930f673..087d4186be 100644 --- a/src/reflect/scala/reflect/internal/BuildUtils.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -5,10 +5,11 @@ package internal import Flags._ import util._ -trait BuildUtils { self: SymbolTable => +trait ReificationSupport { self: SymbolTable => import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass} + import internal._ - class BuildImpl extends BuildApi { + class ReificationSupportImpl extends ReificationSupportApi { def selectType(owner: Symbol, name: String): TypeSymbol = select(owner, newTypeName(name)).asType @@ -22,14 +23,15 @@ trait BuildUtils { self: SymbolTable => val result = owner.info decl name if (result ne NoSymbol) result else - mirrorThatLoaded(owner).missingHook(owner, name) orElse - MissingRequirementError.notFound("%s %s in %s".format(if (name.isTermName) "term" else "type", name, owner.fullName)) + mirrorThatLoaded(owner).missingHook(owner, name) orElse { + throw new ScalaReflectionException("%s %s in %s not found".format(if (name.isTermName) "term" else "type", name, owner.fullName)) + } } def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = { val result = owner.info.decl(newTermName(name)).alternatives(index) if (result ne NoSymbol) result.asMethod - else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName)) + else throw new ScalaReflectionException("overloaded method %s #%d in %s not found".format(name, index, owner.fullName)) } def newFreeTerm(name: String, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol = @@ -41,19 +43,50 @@ trait BuildUtils { self: SymbolTable => def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol = owner.newNestedSymbol(name, pos, flags, isClass).markFlagsCompleted(mask = AllFlags) + def newScopeWith(elems: Symbol*): Scope = + self.newScopeWith(elems: _*) + def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S = sym.setAnnotations(annots) - def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S = - sym.setTypeSignature(tpe).markAllCompleted() + def setInfo[S <: Symbol](sym: S, tpe: Type): S = + sym.setInfo(tpe).markAllCompleted() + + def mkThis(sym: Symbol): Tree = self.This(sym) + + def mkSelect(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym) + + def mkIdent(sym: Symbol): Ident = self.Ident(sym) + + def mkTypeTree(tp: Type): TypeTree = self.TypeTree(tp) + + def ThisType(sym: Symbol): Type = self.ThisType(sym) + + def SingleType(pre: Type, sym: Symbol): Type = self.SingleType(pre, sym) + + def SuperType(thistpe: Type, supertpe: Type): Type = self.SuperType(thistpe, supertpe) + + def ConstantType(value: Constant): ConstantType = self.ConstantType(value) + + def TypeRef(pre: Type, sym: Symbol, args: List[Type]): Type = self.TypeRef(pre, sym, args) + + def RefinedType(parents: List[Type], decls: Scope, typeSymbol: Symbol): RefinedType = self.RefinedType(parents, decls, typeSymbol) + + def ClassInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType = self.ClassInfoType(parents, decls, typeSymbol) + + def MethodType(params: List[Symbol], resultType: Type): MethodType = self.MethodType(params, resultType) + + def NullaryMethodType(resultType: Type): NullaryMethodType = self.NullaryMethodType(resultType) + + def PolyType(typeParams: List[Symbol], resultType: Type): PolyType = self.PolyType(typeParams, resultType) - def This(sym: Symbol): Tree = self.This(sym) + def ExistentialType(quantified: List[Symbol], underlying: Type): ExistentialType = self.ExistentialType(quantified, underlying) - def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym) + def AnnotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType = self.AnnotatedType(annotations, underlying) - def Ident(sym: Symbol): Ident = self.Ident(sym) + def TypeBounds(lo: Type, hi: Type): TypeBounds = self.TypeBounds(lo, hi) - def TypeTree(tp: Type): TypeTree = self.TypeTree(tp) + def BoundedWildcardType(bounds: TypeBounds): BoundedWildcardType = self.BoundedWildcardType(bounds) def thisPrefix(sym: Symbol): Type = sym.thisPrefix @@ -141,7 +174,7 @@ trait BuildUtils { self: SymbolTable => def mkEarlyDef(defns: List[Tree]): List[Tree] = defns.map(mkEarlyDef) - def RefTree(qual: Tree, sym: Symbol) = self.RefTree(qual, sym.name) setSymbol sym + def mkRefTree(qual: Tree, sym: Symbol) = self.RefTree(qual, sym.name) setSymbol sym def freshTermName(prefix: String = nme.FRESH_TERM_NAME_PREFIX): TermName = self.freshTermName(prefix) @@ -953,5 +986,5 @@ trait BuildUtils { self: SymbolTable => } } - val build: BuildImpl = new BuildImpl + val build = new ReificationSupportImpl } diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala index 139a79ffe1..614e71b597 100644 --- a/src/reflect/scala/reflect/internal/StdAttachments.scala +++ b/src/reflect/scala/reflect/internal/StdAttachments.scala @@ -22,6 +22,16 @@ trait StdAttachments { def setPos(newpos: Position): this.type = { pos = newpos; this } } + /** Attachment that knows how to import itself into another universe. */ + trait ImportableAttachment { + def importAttachment(importer: Importer): this.type + } + + /** Attachment that doesn't contain any reflection artificats and can be imported as-is. */ + trait PlainAttachment extends ImportableAttachment { + def importAttachment(importer: Importer): this.type = this + } + /** Stores the trees that give rise to a refined type to be used in reification. * Unfortunately typed `CompoundTypeTree` is lacking essential info, and the reifier cannot use `CompoundTypeTree.tpe`. * Therefore we need this hack (see `Reshape.toPreTyperTypeTree` for a detailed explanation). diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index aad5f32b5f..b95c83d6cb 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -319,7 +319,7 @@ trait StdNames { val FAKE_LOCAL_THIS: NameType = "this$" val LAZY_LOCAL: NameType = "$lzy" val LAZY_SLOW_SUFFIX: NameType = "$lzycompute" - val UNIVERSE_BUILD_PREFIX: NameType = "$u.build." + val UNIVERSE_BUILD_PREFIX: NameType = "$u.internal.reificationSupport." val UNIVERSE_PREFIX: NameType = "$u." val UNIVERSE_SHORT: NameType = "$u" val MIRROR_PREFIX: NameType = "$m." @@ -578,10 +578,13 @@ trait StdNames { val Annotation: NameType = "Annotation" val Any: NameType = "Any" val AnyVal: NameType = "AnyVal" + val Apply: NameType = "Apply" val ArrayAnnotArg: NameType = "ArrayAnnotArg" + val ClassInfoType: NameType = "ClassInfoType" val ConstantType: NameType = "ConstantType" val EmptyPackage: NameType = "EmptyPackage" val EmptyPackageClass: NameType = "EmptyPackageClass" + val ExistentialType: NameType = "ExistentialType" val Flag : NameType = "Flag" val FlagsRepr: NameType = "FlagsRepr" val Ident: NameType = "Ident" @@ -589,18 +592,25 @@ trait StdNames { val Import: NameType = "Import" val Literal: NameType = "Literal" val LiteralAnnotArg: NameType = "LiteralAnnotArg" + val MethodType: NameType = "MethodType" val Modifiers: NameType = "Modifiers" val NestedAnnotArg: NameType = "NestedAnnotArg" + val New: NameType = "New" val NoFlags: NameType = "NoFlags" val NoSymbol: NameType = "NoSymbol" val NoMods: NameType = "NoMods" val Nothing: NameType = "Nothing" val Null: NameType = "Null" + val NullaryMethodType: NameType = "NullaryMethodType" val Object: NameType = "Object" + val PolyType: NameType = "PolyType" + val RefinedType: NameType = "RefinedType" val RootPackage: NameType = "RootPackage" val RootClass: NameType = "RootClass" val Select: NameType = "Select" val SelectFromTypeTree: NameType = "SelectFromTypeTree" + val SingleType: NameType = "SingleType" + val SuperType: NameType = "SuperType" val SyntacticApplied: NameType = "SyntacticApplied" val SyntacticAssign: NameType = "SyntacticAssign" val SyntacticBlock: NameType = "SyntacticBlock" @@ -632,6 +642,7 @@ trait StdNames { val ThisType: NameType = "ThisType" val Tuple2: NameType = "Tuple2" val TYPE_ : NameType = "TYPE" + val TypeBounds: NameType = "TypeBounds" val TypeRef: NameType = "TypeRef" val TypeTree: NameType = "TypeTree" val UNIT : NameType = "UNIT" @@ -654,7 +665,6 @@ trait StdNames { val asInstanceOf_ : NameType = "asInstanceOf" val asInstanceOf_Ob : NameType = "$asInstanceOf" val box: NameType = "box" - val build : NameType = "build" val bytes: NameType = "bytes" val c: NameType = "c" val canEqual_ : NameType = "canEqual" @@ -696,6 +706,7 @@ trait StdNames { val immutable: NameType = "immutable" val implicitly: NameType = "implicitly" val in: NameType = "in" + val internal: NameType = "internal" val inlinedEquals: NameType = "inlinedEquals" val isArray: NameType = "isArray" val isDefinedAt: NameType = "isDefinedAt" @@ -717,8 +728,13 @@ trait StdNames { val moduleClass : NameType = "moduleClass" val mkAnnotation: NameType = "mkAnnotation" val mkEarlyDef: NameType = "mkEarlyDef" + val mkIdent: NameType = "mkIdent" val mkPackageStat: NameType = "mkPackageStat" val mkRefineStat: NameType = "mkRefineStat" + val mkRefTree: NameType = "mkRefTree" + val mkSelect: NameType = "mkSelect" + val mkThis: NameType = "mkThis" + val mkTypeTree: NameType = "mkTypeTree" val ne: NameType = "ne" val newArray: NameType = "newArray" val newFreeTerm: NameType = "newFreeTerm" @@ -736,11 +752,11 @@ trait StdNames { val productPrefix: NameType = "productPrefix" val readResolve: NameType = "readResolve" val reify : NameType = "reify" + val reificationSupport : NameType = "reificationSupport" val rootMirror : NameType = "rootMirror" val runtime: NameType = "runtime" val runtimeClass: NameType = "runtimeClass" val runtimeMirror: NameType = "runtimeMirror" - val RefTree: NameType = "RefTree" val scala_ : NameType = "scala" val selectDynamic: NameType = "selectDynamic" val selectOverloadedMethod: NameType = "selectOverloadedMethod" @@ -748,9 +764,9 @@ trait StdNames { val selectType: NameType = "selectType" val self: NameType = "self" val setAnnotations: NameType = "setAnnotations" + val setInfo: NameType = "setInfo" val setSymbol: NameType = "setSymbol" val setType: NameType = "setType" - val setTypeSignature: NameType = "setTypeSignature" val splice: NameType = "splice" val staticClass : NameType = "staticClass" val staticModule : NameType = "staticModule" @@ -771,6 +787,7 @@ trait StdNames { val tree : NameType = "tree" val true_ : NameType = "true" val typedProductIterator: NameType = "typedProductIterator" + val typeOf: NameType = "typeOf" val TypeName: NameType = "TypeName" val typeTagToManifest: NameType = "typeTagToManifest" val unapply: NameType = "unapply" @@ -785,6 +802,7 @@ trait StdNames { val valueOf : NameType = "valueOf" val values : NameType = "values" val wait_ : NameType = "wait" + val weakTypeOf: NameType = "weakTypeOf" val withFilter: NameType = "withFilter" val zero: NameType = "zero" @@ -989,6 +1007,8 @@ trait StdNames { val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values } + lazy val typeNames: tpnme.type = tpnme + object tpnme extends TypeNames { } /** For fully qualified type names. @@ -1009,6 +1029,8 @@ trait StdNames { val javanme = nme.javaKeywords + lazy val termNames: nme.type = nme + object nme extends TermNames { def moduleVarName(name: TermName): TermName = newTermNameCached("" + name + MODULE_VAR_SUFFIX) diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala index 802bd18a4e..e50c65c9ca 100644 --- a/src/reflect/scala/reflect/internal/SymbolTable.scala +++ b/src/reflect/scala/reflect/internal/SymbolTable.scala @@ -11,6 +11,7 @@ import scala.annotation.elidable import scala.collection.{ mutable, immutable } import util._ import java.util.concurrent.TimeUnit +import scala.reflect.internal.{TreeGen => InternalTreeGen} abstract class SymbolTable extends macros.Universe with Collections @@ -40,14 +41,14 @@ abstract class SymbolTable extends macros.Universe with CapturedVariables with StdAttachments with StdCreators - with BuildUtils + with ReificationSupport with PrivateWithin with pickling.Translations with FreshNames + with Internals { - val gen = new TreeGen { val global: SymbolTable.this.type = SymbolTable.this } - lazy val treeBuild = gen + val gen = new InternalTreeGen { val global: SymbolTable.this.type = SymbolTable.this } def log(msg: => AnyRef): Unit def warning(msg: String): Unit = Console.err.println(msg) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 02616d1ba6..5fa4772d60 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -77,9 +77,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => } } - abstract class SymbolContextApiImpl extends SymbolContextApi { + def symbolOf[T: WeakTypeTag]: TypeSymbol = weakTypeOf[T].typeSymbolDirect.asType + + abstract class SymbolContextApiImpl extends SymbolApi { this: Symbol => + def isFreeTerm: Boolean = false + def asFreeTerm: FreeTermSymbol = throw new ScalaReflectionException(s"$this is not a free term") + def isFreeType: Boolean = false + def asFreeType: FreeTypeSymbol = throw new ScalaReflectionException(s"$this is not a free type") + def isExistential: Boolean = this.isExistentiallyBound def isParamWithDefault: Boolean = this.hasDefault // `isByNameParam` is only true for a call-by-name parameter of a *method*, @@ -89,6 +96,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isJava: Boolean = isJavaDefined def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable + def isAbstract: Boolean = isAbstractClass || isDeferred || isAbstractType + def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL) + def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL) def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) @@ -110,6 +120,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def baseClasses = info.baseClasses def module = sourceModule def thisPrefix: Type = thisType + def superPrefix(supertpe: Type): Type = SuperType(thisType, supertpe) // automatic full initialization on access to info from reflection API is a double-edged sword // on the one hand, it's convenient so that the users don't have to deal with initialization themselves before printing out stuff @@ -123,11 +134,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => def toType: Type = tpe def toTypeIn(site: Type): Type = site.memberType(this) def toTypeConstructor: Type = typeConstructor - def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this } def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this } def getter: Symbol = getter(owner) def setter: Symbol = setter(owner) + + def companion: Symbol = { + if (isModule && !isPackage) companionSymbol + else if (isModuleClass && !isPackageClass) sourceModule.companionSymbol + else if (isClass && !isModuleClass && !isPackageClass) companionSymbol + else NoSymbol + } + + def infoIn(site: Type): Type = typeSignatureIn(site) + def overrides: List[Symbol] = allOverriddenSymbols + def paramLists: List[List[Symbol]] = paramss } private[reflect] case class SymbolKind(accurate: String, sanitized: String, abbreviation: String) @@ -633,7 +654,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * (i.e. the pickle not only contains info about directly nested classes/modules, but also about * classes/modules nested into those and so on). * - * Unpickling is triggered automatically whenever typeSignature (info in compiler parlance) is called. + * Unpickling is triggered automatically whenever info (info in compiler parlance) is called. * This happens because package symbols assign completer thunks to the dummies they create. * Therefore metadata loading happens lazily and transparently. * @@ -643,7 +664,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * produces incorrect results. * * One might think that the solution is simple: automatically call the completer - * whenever one needs flags, annotations and privateWithin - just like it's done for typeSignature. + * whenever one needs flags, annotations and privateWithin - just like it's done for info. * Unfortunately, this leads to weird crashes in scalac, and currently we can't attempt * to fix the core of the compiler risk stability a few weeks before the final release. * upd. Haha, "a few weeks before the final release". This surely sounds familiar :) @@ -904,7 +925,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => || isModuleOrModuleClass && (isTopLevel || !settings.overrideObjects) || isTerm && ( isPrivate - || isLocal + || isLocalToBlock || isNotOverridden ) ) @@ -912,9 +933,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Is this symbol owned by a package? */ final def isTopLevel = owner.isPackageClass - /** Is this symbol locally defined? I.e. not accessed from outside `this` instance */ + /** Is this symbol defined in a block? */ + @deprecated("Use isLocalToBlock instead", "2.11.0") final def isLocal: Boolean = owner.isTerm + /** Is this symbol defined in a block? */ + final def isLocalToBlock: Boolean = owner.isTerm + /** Is this symbol a constant? */ final def isConstant: Boolean = isStable && isConstantType(tpe.resultType) @@ -1257,7 +1282,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * as public. */ def accessBoundary(base: Symbol): Symbol = { - if (hasFlag(PRIVATE) || isLocal) owner + if (hasFlag(PRIVATE) || isLocalToBlock) owner else if (hasAllFlags(PROTECTED | STATIC | JAVA)) enclosingRootClass else if (hasAccessBoundary && !phase.erasedTypes) privateWithin else if (hasFlag(PROTECTED)) base @@ -1861,7 +1886,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The next enclosing method. */ def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod - /** The primary constructor of a class. */ def primaryConstructor: Symbol = NoSymbol /** The self symbol (a TermSymbol) of a class with explicit self type, or else the @@ -2272,7 +2296,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => * seen from class `base`. This symbol is always concrete. * pre: `this.owner` is in the base class sequence of `base`. */ - final def superSymbol(base: Symbol): Symbol = { + @deprecated("Use `superSymbolIn` instead", "2.11.0") + final def superSymbol(base: Symbol): Symbol = superSymbolIn(base) + + final def superSymbolIn(base: Symbol): Symbol = { var bcs = base.info.baseClasses dropWhile (owner != _) drop 1 var sym: Symbol = NoSymbol while (!bcs.isEmpty && sym == NoSymbol) { @@ -2286,7 +2313,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The getter of this value or setter definition in class `base`, or NoSymbol if * none exists. */ - final def getter(base: Symbol): Symbol = + @deprecated("Use `getterIn` instead", "2.11.0") + final def getter(base: Symbol): Symbol = getterIn(base) + + final def getterIn(base: Symbol): Symbol = base.info decl getterName filter (_.hasAccessorFlag) def getterName: TermName = name.getterName @@ -2409,7 +2439,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else if (isClass) "class" else if (isType && !isParameter) "type" else if (isVariable) "var" - else if (isPackage) "package" + else if (hasPackageFlag) "package" else if (isModule) "object" else if (isSourceMethod) "def" else if (isTerm && (!isParameter || isParamAccessor)) "val" @@ -2420,8 +2450,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => if (isTermMacro) ("term macro", "macro method", "MACM") else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE") else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY") - else if (isPackage) ("package", "package", "PK") else if (isPackageClass) ("package class", "package", "PKC") + else if (isPackage) ("package", "package", "PK") else if (isPackageObject) ("package object", "package", "PKO") else if (isPackageObjectClass) ("package object class", "package", "PKOC") else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC") @@ -2509,6 +2539,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * If hasMeaninglessName is true, uses the owner's name to disambiguate identity. */ override def toString: String = { + if (!isCompilerUniverse) fullyInitializeSymbol(this) if (isPackageObjectOrClass && !settings.debug) s"package object ${owner.decodedName}" else compose( @@ -2649,7 +2680,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => (infos ne null) && infos.info.isInstanceOf[OverloadedType] ) ***/ - override def isPackage = this hasFlag PACKAGE override def isValueParameter = this hasFlag PARAM override def isSetterParameter = isValueParameter && owner.isSetter @@ -2822,13 +2852,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => } loop(info) } + + override def exceptions = annotations flatMap ThrownException.unapply } implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol]) class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends TypeSymbol(initOwner, initPos, initName) { type TypeOfClonedSymbol = TypeSymbol - override def variance = if (hasLocalFlag) Bivariant else info.typeSymbol.variance + override def variance = if (isLocalToThis) Bivariant else info.typeSymbol.variance override def isContravariant = variance.isContravariant override def isCovariant = variance.isCovariant final override def isAliasType = true @@ -3114,7 +3146,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ override def isLocalClass = ( isAnonOrRefinementClass - || isLocal + || isLocalToBlock || !isTopLevel && owner.isLocalClass ) @@ -3139,13 +3171,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def primaryConstructor = { val c = info decl primaryConstructorName - if (c.isOverloaded) c.alternatives.head else c + if (isJavaDefined) NoSymbol // need to force info before checking the flag + else if (c.isOverloaded) c.alternatives.head else c } override def associatedFile = ( if (!isTopLevel) super.associatedFile - else if (_associatedFile eq null) NoAbstractFile // guarantee not null, but save cost of initializing the var - else _associatedFile + else { + if (_associatedFile eq null) NoAbstractFile // guarantee not null, but save cost of initializing the var + else _associatedFile + } ) override def associatedFile_=(f: AbstractFile) { _associatedFile = f } @@ -3354,11 +3389,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => def origin: String } class FreeTermSymbol(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol with FreeTermSymbolApi { + final override def isFreeTerm = true + final override def asFreeTerm = this def value = value0 } implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol]) - class FreeTypeSymbol(name0: TypeName, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi + class FreeTypeSymbol(name0: TypeName, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi { + final override def isFreeType = true + final override def asFreeType = this + } implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol]) /** An object representing a missing symbol */ diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index e7675eb4bf..6011289baf 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -6,7 +6,7 @@ import Flags._ import util._ import scala.collection.mutable.ListBuffer -abstract class TreeGen extends macros.TreeBuilder { +abstract class TreeGen { val global: SymbolTable import global._ @@ -186,7 +186,7 @@ abstract class TreeGen extends macros.TreeBuilder { ) val needsPackageQualifier = ( (sym ne null) - && qualsym.isPackage + && qualsym.hasPackageFlag && !(sym.isDefinedInPackage || sym.moduleClass.isDefinedInPackage) // SI-7817 work around strangeness in post-flatten `Symbol#owner` ) val pkgQualifier = @@ -893,4 +893,7 @@ abstract class TreeGen extends macros.TreeBuilder { def mkSyntheticParam(pname: TermName) = ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree) + + def mkCast(tree: Tree, pt: Type): Tree = + atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = true, wrapInApply = false)) } diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 91e80f8989..7a6862a770 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -99,7 +99,7 @@ trait Trees extends api.Trees { (duplicator transform this).asInstanceOf[this.type] } - abstract class TreeContextApiImpl extends TreeContextApi { this: Tree => + abstract class TreeContextApiImpl extends TreeApi { this: Tree => override def orElse(alt: => Tree) = if (!isEmpty) this else alt @@ -158,8 +158,8 @@ trait Trees extends api.Trees { productIterator.toList flatMap subtrees } - override def freeTerms: List[FreeTermSymbol] = freeSyms[FreeTermSymbol](_.isFreeTerm, _.termSymbol) - override def freeTypes: List[FreeTypeSymbol] = freeSyms[FreeTypeSymbol](_.isFreeType, _.typeSymbol) + def freeTerms: List[FreeTermSymbol] = freeSyms[FreeTermSymbol](_.isFreeTerm, _.termSymbol) + def freeTypes: List[FreeTypeSymbol] = freeSyms[FreeTypeSymbol](_.isFreeType, _.typeSymbol) private def freeSyms[S <: Symbol](isFree: Symbol => Boolean, symOfType: Type => Symbol): List[S] = { val s = mutable.LinkedHashSet[S]() @@ -175,13 +175,13 @@ trait Trees extends api.Trees { s.toList } - override def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = + def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = new TreeSymSubstituter(from, to)(this) - override def substituteTypes(from: List[Symbol], to: List[Type]): Tree = + def substituteTypes(from: List[Symbol], to: List[Type]): Tree = new TreeTypeSubstituter(from, to)(this) - override def substituteThis(clazz: Symbol, to: Tree): Tree = + def substituteThis(clazz: Symbol, to: Tree): Tree = new ThisSubstituter(clazz, to) transform this def hasExistingSymbol = (symbol ne null) && (symbol ne NoSymbol) @@ -235,7 +235,7 @@ trait Trees extends api.Trees { trait TypTree extends Tree with TypTreeApi - abstract class SymTree extends Tree with SymTreeContextApi { + abstract class SymTree extends Tree with SymTreeApi { override def hasSymbolField = true override var symbol: Symbol = NoSymbol } @@ -296,14 +296,42 @@ trait Trees extends api.Trees { case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template) extends ImplDef with ClassDefApi - object ClassDef extends ClassDefExtractor + object ClassDef extends ClassDefExtractor { + /** @param sym the class symbol + * @param impl the implementation template + * @return the class definition + */ + def apply(sym: Symbol, impl: Template): ClassDef = + atPos(sym.pos) { + ClassDef(Modifiers(sym.flags), + sym.name.toTypeName, + sym.typeParams map TypeDef.apply, + impl) setSymbol sym + } + + /** @param sym the class symbol + * @param body trees that constitute the body of the class + * @return the class definition + */ + def apply(sym: Symbol, body: List[Tree]): ClassDef = + ClassDef(sym, Template(sym, body)) + } case class ModuleDef(mods: Modifiers, name: TermName, impl: Template) extends ImplDef with ModuleDefApi - object ModuleDef extends ModuleDefExtractor + object ModuleDef extends ModuleDefExtractor { + /** + * @param sym the class symbol + * @param impl the implementation template + */ + def apply(sym: Symbol, impl: Template): ModuleDef = + atPos(sym.pos) { + ModuleDef(Modifiers(sym.flags), sym.name.toTermName, impl) setSymbol sym + } + } abstract class ValOrDefDef extends MemberDef with ValOrDefDefApi { - def name: Name + def name: TermName def tpt: Tree def rhs: Tree } @@ -317,19 +345,37 @@ trait Trees extends api.Trees { } case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi - object ValDef extends ValDefExtractor + object ValDef extends ValDefExtractor { + def apply(sym: Symbol): ValDef = newValDef(sym, EmptyTree)() + def apply(sym: Symbol, rhs: Tree): ValDef = newValDef(sym, rhs)() + } case class DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef with DefDefApi - object DefDef extends DefDefExtractor + object DefDef extends DefDefExtractor { + def apply(sym: Symbol, rhs: Tree): DefDef = newDefDef(sym, rhs)() + def apply(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(vparamss = vparamss) + def apply(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods) + def apply(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods, vparamss = vparamss) + def apply(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = newDefDef(sym, rhs(sym.info.paramss))() + } case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) extends MemberDef with TypeDefApi - object TypeDef extends TypeDefExtractor + object TypeDef extends TypeDefExtractor { + /** A TypeDef node which defines abstract type or type parameter for given `sym` */ + def apply(sym: Symbol): TypeDef = newTypeDef(sym, TypeBoundsTree(sym))() + def apply(sym: Symbol, rhs: Tree): TypeDef = newTypeDef(sym, rhs)() + } case class LabelDef(name: TermName, params: List[Ident], rhs: Tree) extends DefTree with TermTree with LabelDefApi - object LabelDef extends LabelDefExtractor + object LabelDef extends LabelDefExtractor { + def apply(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = + atPos(sym.pos) { + LabelDef(sym.name.toTermName, params map Ident, rhs) setSymbol sym + } + } case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) extends ImportSelectorApi object ImportSelector extends ImportSelectorExtractor { @@ -488,7 +534,7 @@ trait Trees extends api.Trees { } object Select extends SelectExtractor - case class Ident(name: Name) extends RefTree with IdentContextApi { + case class Ident(name: Name) extends RefTree with IdentApi { def qualifier: Tree = EmptyTree def isBackquoted = this.hasAttachment[BackquotedIdentifierAttachment.type] } @@ -545,7 +591,7 @@ trait Trees extends api.Trees { extends TypTree with ExistentialTypeTreeApi object ExistentialTypeTree extends ExistentialTypeTreeExtractor - case class TypeTree() extends TypTree with TypeTreeContextApi { + case class TypeTree() extends TypTree with TypeTreeApi { private var orig: Tree = null /** Was this type tree originally empty? That is, does it now contain * an inferred type that must be forgotten in `resetAttrs` to @@ -590,14 +636,14 @@ trait Trees extends api.Trees { def TypeTree(tp: Type): TypeTree = TypeTree() setType tp private def TypeTreeMemberType(sym: Symbol): TypeTree = { // Needed for pos/t4970*.scala. See SI-7853 - val resType = (if (sym.isLocal) sym.tpe else (sym.owner.thisType memberType sym)).finalResultType + val resType = (if (sym.isLocalToBlock) sym.tpe else (sym.owner.thisType memberType sym)).finalResultType atPos(sym.pos.focus)(TypeTree(resType)) } def TypeBoundsTree(bounds: TypeBounds): TypeBoundsTree = TypeBoundsTree(TypeTree(bounds.lo), TypeTree(bounds.hi)) def TypeBoundsTree(sym: Symbol): TypeBoundsTree = atPos(sym.pos)(TypeBoundsTree(sym.info.bounds)) - override type TreeCopier <: InternalTreeCopierOps + override type TreeCopier >: Null <: InternalTreeCopierOps abstract class InternalTreeCopierOps extends TreeCopierOps { def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue @@ -676,6 +722,8 @@ trait Trees extends api.Trees { new Select(qualifier, selector).copyAttrs(tree) def Ident(tree: Tree, name: Name) = new Ident(name) copyAttrs tree + def RefTree(tree: Tree, qualifier: Tree, selector: Name) = + self.RefTree(qualifier, selector) copyAttrs tree def ReferenceToBoxed(tree: Tree, idt: Ident) = new ReferenceToBoxed(idt).copyAttrs(tree) def Literal(tree: Tree, value: Constant) = @@ -866,6 +914,11 @@ trait Trees extends api.Trees { if name0 == name => t case _ => treeCopy.Ident(tree, name) } + def RefTree(tree: Tree, qualifier: Tree, selector: Name) = tree match { + case t @ Select(qualifier0, selector0) + if (qualifier0 == qualifier) && (selector0 == selector) => t + case _ => treeCopy.RefTree(tree, qualifier, selector) + } def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match { case t @ ReferenceToBoxed(idt0) if (idt0 == idt) => t @@ -1000,25 +1053,6 @@ trait Trees extends api.Trees { // ---- values and creators --------------------------------------- - /** @param sym the class symbol - * @param impl the implementation template - * @return the class definition - */ - def ClassDef(sym: Symbol, impl: Template): ClassDef = - atPos(sym.pos) { - ClassDef(Modifiers(sym.flags), - sym.name.toTypeName, - sym.typeParams map TypeDef, - impl) setSymbol sym - } - - /** @param sym the class symbol - * @param body trees that constitute the body of the class - * @return the class definition - */ - def ClassDef(sym: Symbol, body: List[Tree]): ClassDef = - ClassDef(sym, Template(sym, body)) - /** @param sym the template's symbol * @param body trees that constitute the body of the template * @return the template @@ -1031,15 +1065,6 @@ trait Trees extends api.Trees { } } - /** - * @param sym the class symbol - * @param impl the implementation template - */ - def ModuleDef(sym: Symbol, impl: Template): ModuleDef = - atPos(sym.pos) { - ModuleDef(Modifiers(sym.flags), sym.name.toTermName, impl) setSymbol sym - } - trait CannotHaveAttrs extends Tree { super.setPos(NoPosition) super.setType(NoType) @@ -1076,8 +1101,8 @@ trait Trees extends api.Trees { def newDefDef(sym: Symbol, rhs: Tree)( mods: Modifiers = Modifiers(sym.flags), name: TermName = sym.name.toTermName, - tparams: List[TypeDef] = sym.typeParams map TypeDef, - vparamss: List[List[ValDef]] = mapParamss(sym)(ValDef), + tparams: List[TypeDef] = sym.typeParams map TypeDef.apply, + vparamss: List[List[ValDef]] = mapParamss(sym)(ValDef.apply), tpt: Tree = TypeTreeMemberType(sym) ): DefDef = ( atPos(sym.pos)(DefDef(mods, name, tparams, vparamss, tpt, rhs)) setSymbol sym @@ -1086,29 +1111,11 @@ trait Trees extends api.Trees { def newTypeDef(sym: Symbol, rhs: Tree)( mods: Modifiers = Modifiers(sym.flags), name: TypeName = sym.name.toTypeName, - tparams: List[TypeDef] = sym.typeParams map TypeDef + tparams: List[TypeDef] = sym.typeParams map TypeDef.apply ): TypeDef = ( atPos(sym.pos)(TypeDef(mods, name, tparams, rhs)) setSymbol sym ) - def DefDef(sym: Symbol, rhs: Tree): DefDef = newDefDef(sym, rhs)() - def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(vparamss = vparamss) - def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods) - def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods, vparamss = vparamss) - def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = newDefDef(sym, rhs(sym.info.paramss))() - - def ValDef(sym: Symbol): ValDef = newValDef(sym, EmptyTree)() - def ValDef(sym: Symbol, rhs: Tree): ValDef = newValDef(sym, rhs)() - - /** A TypeDef node which defines abstract type or type parameter for given `sym` */ - def TypeDef(sym: Symbol): TypeDef = newTypeDef(sym, TypeBoundsTree(sym))() - def TypeDef(sym: Symbol, rhs: Tree): TypeDef = newTypeDef(sym, rhs)() - - def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = - atPos(sym.pos) { - LabelDef(sym.name.toTermName, params map Ident, rhs) setSymbol sym - } - /** casedef shorthand */ def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body) @@ -1851,8 +1858,8 @@ trait Trees extends api.Trees { implicit val NameTreeTag = ClassTag[NameTree](classOf[NameTree]) implicit val NewTag = ClassTag[New](classOf[New]) implicit val PackageDefTag = ClassTag[PackageDef](classOf[PackageDef]) - implicit val RefTreeTag = ClassTag[RefTree](classOf[RefTree]) implicit val ReferenceToBoxedTag = ClassTag[ReferenceToBoxed](classOf[ReferenceToBoxed]) + implicit val RefTreeTag = ClassTag[RefTree](classOf[RefTree]) implicit val ReturnTag = ClassTag[Return](classOf[Return]) implicit val SelectFromTypeTreeTag = ClassTag[SelectFromTypeTree](classOf[SelectFromTypeTree]) implicit val SelectTag = ClassTag[Select](classOf[Select]) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index d60ea73814..3ede21d5e3 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -195,6 +195,7 @@ trait Types override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = underlying.instantiateTypeParams(formals, actuals) override def skolemizeExistential(owner: Symbol, origin: AnyRef) = underlying.skolemizeExistential(owner, origin) override def normalize = maybeRewrap(underlying.normalize) + override def etaExpand = maybeRewrap(underlying.etaExpand) override def dealias = maybeRewrap(underlying.dealias) override def cloneInfo(owner: Symbol) = maybeRewrap(underlying.cloneInfo(owner)) override def atOwner(owner: Symbol) = maybeRewrap(underlying.atOwner(owner)) @@ -243,6 +244,16 @@ trait Types def isSpliceable = { this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential } + + def companion = { + val sym = typeSymbolDirect + if (sym.isModule && !sym.isPackage) sym.companionSymbol.tpe + else if (sym.isModuleClass && !sym.isPackageClass) sym.sourceModule.companionSymbol.tpe + else if (sym.isClass && !sym.isModuleClass && !sym.isPackageClass) sym.companionSymbol.info + else NoType + } + + def paramLists: List[List[Symbol]] = paramss } /** The base class for all types */ @@ -499,6 +510,8 @@ trait Types */ def normalize = this // @MAT + def etaExpand = this + /** Expands type aliases. */ def dealias = this @@ -908,7 +921,10 @@ trait Types * after `maxTostringRecursions` recursion levels. Uses `safeToString` * to produce a string on each level. */ - override final def toString: String = typeToString(this) + override final def toString: String = { + if (!isCompilerUniverse) fullyInitializeType(this) + typeToString(this) + } /** Method to be implemented in subclasses. * Converts this type to a string in calling toString for its parts. @@ -1056,7 +1072,7 @@ trait Types /** A base class for types that represent a single value * (single-types and this-types). */ - abstract class SingletonType extends SubType with SimpleTypeProxy { + abstract class SingletonType extends SubType with SimpleTypeProxy with SingletonTypeApi { def supertype = underlying override def isTrivial = false override def widen: Type = underlying.widen @@ -1324,7 +1340,7 @@ trait Types /** A common base class for intersection types and class types */ - abstract class CompoundType extends Type { + abstract class CompoundType extends Type with CompoundTypeApi { private[reflect] var baseTypeSeqCache: BaseTypeSeq = _ private[reflect] var baseTypeSeqPeriod = NoPeriod @@ -1590,20 +1606,27 @@ trait Types } else if (flattened != parents) { refinedType(flattened, if (typeSymbol eq NoSymbol) NoSymbol else typeSymbol.owner, decls, NoPosition) } else if (isHigherKinded) { - // MO to AM: This is probably not correct - // If they are several higher-kinded parents with different bounds we need - // to take the intersection of their bounds - typeFun( - typeParams, - RefinedType( - parents map { - case TypeRef(pre, sym, List()) => TypeRef(pre, sym, dummyArgs) - case p => p - }, - decls, - typeSymbol)) + etaExpand } else super.normalize } + + final override def etaExpand: Type = { + // MO to AM: This is probably not correct + // If they are several higher-kinded parents with different bounds we need + // to take the intersection of their bounds + // !!! inconsistent with TypeRef.etaExpand that uses initializedTypeParams + if (!isHigherKinded) this + else typeFun( + typeParams, + RefinedType( + parents map { + case TypeRef(pre, sym, List()) => TypeRef(pre, sym, dummyArgs) + case p => p + }, + decls, + typeSymbol)) + } + override def kind = "RefinedType" } @@ -2153,7 +2176,7 @@ trait Types || pre.isGround && args.forall(_.isGround) ) - def etaExpand: Type = { + final override def etaExpand: Type = { // must initialise symbol, see test/files/pos/ticket0137.scala val tpars = initializedTypeParams if (tpars.isEmpty) this @@ -3155,9 +3178,13 @@ trait Types if (instValid) inst // get here when checking higher-order subtyping of the typevar by itself // TODO: check whether this ever happens? - else if (isHigherKinded) logResult("Normalizing HK $this")(typeFun(params, applyArgs(params map (_.typeConstructor)))) + else if (isHigherKinded) etaExpand else super.normalize ) + override def etaExpand: Type = ( + if (!isHigherKinded) this + else logResult("Normalizing HK $this")(typeFun(params, applyArgs(params map (_.typeConstructor)))) + ) override def typeSymbol = origin.typeSymbol private def tparamsOfSym(sym: Symbol) = sym.info match { @@ -3532,6 +3559,12 @@ trait Types } } + def appliedType(tycon: Type, args: Type*): Type = + appliedType(tycon, args.toList) + + def appliedType(tyconSym: Symbol, args: List[Type]): Type = + appliedType(tyconSym.typeConstructor, args) + /** Very convenient. */ def appliedType(tyconSym: Symbol, args: Type*): Type = appliedType(tyconSym.typeConstructor, args.toList) diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index a7cac5254c..ca43fdcb63 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -33,10 +33,10 @@ trait Variances { /** Is every symbol in the owner chain between `site` and the owner of `sym` * either a term symbol or private[this]? If not, add `sym` to the set of * esacped locals. - * @pre sym.hasLocalFlag + * @pre sym.isLocalToThis */ @tailrec final def checkForEscape(sym: Symbol, site: Symbol) { - if (site == sym.owner || site == sym.owner.moduleClass || site.isPackage) () // done + if (site == sym.owner || site == sym.owner.moduleClass || site.hasPackageFlag) () // done else if (site.isTerm || site.isPrivateLocal) checkForEscape(sym, site.owner) // ok - recurse to owner else escapedLocals += sym } @@ -53,8 +53,8 @@ trait Variances { // return Bivariant if `sym` is local to a term // or is private[this] or protected[this] def isLocalOnly(sym: Symbol) = !sym.owner.isClass || ( - sym.isTerm - && (sym.hasLocalFlag || sym.isSuperAccessor) // super accessors are implicitly local #4345 + sym.isTerm // ?? shouldn't this be sym.owner.isTerm according to the comments above? + && (sym.isLocalToThis || sym.isSuperAccessor) // super accessors are implicitly local #4345 && !escapedLocals(sym) ) @@ -143,7 +143,7 @@ trait Variances { // Or constructors, or case class factory or extractor. def skip = ( sym == NoSymbol - || sym.hasLocalFlag + || sym.isLocalToThis || sym.owner.isConstructor || sym.owner.isCaseApplyOrUnapply ) diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index 07c9242bf3..6d83032c2d 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -1099,7 +1099,7 @@ private[internal] trait TypeMaps { tp } case SingleType(pre, sym) => - if (sym.isPackage) tp + if (sym.hasPackageFlag) tp else { val pre1 = this(pre) try { diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index 786ff2210c..d5b5967145 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -74,7 +74,7 @@ trait Erasure { // // This requires that cls.isClass. protected def rebindInnerClass(pre: Type, cls: Symbol): Type = - if (cls.isTopLevel || cls.isLocal) pre else cls.owner.tpe_* + if (cls.isTopLevel || cls.isLocalToBlock) pre else cls.owner.tpe_* /** The type of the argument of a value class reference after erasure * This method needs to be called at a phase no later than erasurephase diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala index f3eedb88e7..0192d31806 100644 --- a/src/reflect/scala/reflect/internal/util/Position.scala +++ b/src/reflect/scala/reflect/internal/util/Position.scala @@ -8,43 +8,7 @@ package reflect package internal package util -/** The Position class and its subclasses represent positions of ASTs and symbols. - * Every subclass of DefinedPosition refers to a SourceFile and three character - * offsets within it: start, end, and point. The point is where the ^ belongs when - * issuing an error message, usually a Name. A range position can be designated - * as transparent, which excuses it from maintaining the invariants to follow. If - * a transparent position has opaque children, those are considered as if they were - * the direct children of the transparent position's parent. - * - * Note: some of these invariants actually apply to the trees which carry - * the positions, but they are phrased as if the positions themselves were - * the parent/children for conciseness. - * - * Invariant 1: in a focused/offset position, start == point == end - * Invariant 2: in a range position, start <= point < end - * Invariant 3: an offset position never has a child with a range position - * Invariant 4: every range position child of a range position parent is contained within its parent - * Invariant 5: opaque range position siblings overlap at most at a single point - * - * The following tests are useful on positions: - * - * pos.isDefined true if position is not an UndefinedPosition (those being NoPosition and FakePos) - * pos.isRange true if position is a range (opaque or transparent) which implies start < end - * pos.isOpaqueRange true if position is an opaque range - * - * The following accessor methods are provided - an exception will be thrown if - * point/start/end are attempted on an UndefinedPosition. - * - * pos.source The source file of the position, or NoSourceFile if unavailable - * pos.point The offset of the point - * pos.start The (inclusive) start offset, or the point of an offset position - * pos.end The (exclusive) end offset, or the point of an offset position - * - * The following conversion methods are often used: - * - * pos.focus Converts a range position to an offset position focused on the point - * pos.makeTransparent Convert an opaque range into a transparent range - */ +/** @inheritdoc */ class Position extends scala.reflect.api.Position with InternalPositionImpl with DeprecatedPosition { type Pos = Position def pos: Position = this diff --git a/src/reflect/scala/reflect/io/NoAbstractFile.scala b/src/reflect/scala/reflect/io/NoAbstractFile.scala index a4e869ed41..18eca7698d 100644 --- a/src/reflect/scala/reflect/io/NoAbstractFile.scala +++ b/src/reflect/scala/reflect/io/NoAbstractFile.scala @@ -31,4 +31,5 @@ object NoAbstractFile extends AbstractFile { def output: java.io.OutputStream = null def path: String = "" override def toByteArray = Array[Byte]() + override def toString = "<no file>" } diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala index d2b878d081..bd918bbe56 100644 --- a/src/reflect/scala/reflect/macros/Aliases.scala +++ b/src/reflect/scala/reflect/macros/Aliases.scala @@ -110,10 +110,25 @@ trait Aliases { /** * Shortcut for `implicitly[WeakTypeTag[T]].tpe` */ - def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe + def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = if (attag != null) attag.tpe else typeOf[Null] + + /** + * Type of `x` as derived from a weak type tag. + */ + def weakTypeOf[T: WeakTypeTag](x: => T): Type = weakTypeOf[T] /** * Shortcut for `implicitly[TypeTag[T]].tpe` */ def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe + + /** + * Type of `x` as derived from a type tag. + */ + def typeOf[T: TypeTag](x: => T): Type = typeOf[T] + + /** + * Type symbol of `x` as derived from a type tag. + */ + def symbolOf[T: WeakTypeTag]: universe.TypeSymbol = universe.symbolOf[T] } diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala index 1ced2e54c6..69ede42cc7 100644 --- a/src/reflect/scala/reflect/macros/Enclosures.scala +++ b/src/reflect/scala/reflect/macros/Enclosures.scala @@ -20,7 +20,8 @@ import scala.language.existentials // SI-6541 * This is somewhat aligned with the overall evolution of macros during the 2.11 development cycle, where we played with * `c.introduceTopLevel` and `c.introduceMember`, but at the end of the day decided to reject them. * - * If you're relying on the now deprecated APIs, consider reformulating your macros in terms of completely local expansion + * If you're relying on the now deprecated APIs, consider using the new [[c.internal.enclosingOwner]] method that can be used to obtain + * the names of enclosing definitions. Alternatively try reformulating your macros in terms of completely local expansion * and/or joining a discussion of a somewhat related potential language feature at [[https://groups.google.com/forum/#!topic/scala-debate/f4CLmYShX6Q]]. * We also welcome questions and suggestions on our mailing lists, where we would be happy to further discuss this matter. */ diff --git a/src/reflect/scala/reflect/macros/Internals.scala b/src/reflect/scala/reflect/macros/Internals.scala new file mode 100644 index 0000000000..75164344da --- /dev/null +++ b/src/reflect/scala/reflect/macros/Internals.scala @@ -0,0 +1,79 @@ +package scala +package reflect +package macros + +/** + * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> + * @see [[scala.reflect.api.Internals]] + */ +trait Internals { + self: blackbox.Context => + + /** @see [[scala.reflect.api.Internals]] */ + val internal: ContextInternalApi + + /** @see [[scala.reflect.api.Internals]] */ + trait ContextInternalApi extends universe.MacroInternalApi { + /** Symbol associated with the innermost enclosing lexical context. + * Walking the owner chain of this symbol will reveal information about more and more enclosing contexts. + */ + def enclosingOwner: Symbol + + /** Functions that are available during [[transform]]. + * @see [[transform]] + */ + trait TransformApi { + /** Calls the current transformer on the given tree. + * Current transformer = argument to the `transform` call. + */ + def recur(tree: Tree): Tree + + /** Calls the default transformer on the given tree. + * Default transformer = recur into tree's children and assemble the results. + */ + def default(tree: Tree): Tree + } + + /** Transforms a given tree using the provided function. + * @see [[TransformApi]] + */ + // TODO: explore a more concise notation that Denys and I discussed today + // when transformer is PartialFunction[Tree, Tree]] and TransformApi is passed magically + // also cf. https://github.com/dsl-paradise/dsl-paradise + def transform(tree: Tree)(transformer: (Tree, TransformApi) => Tree): Tree + + /** Functions that are available during [[typingTransform]]. + * @see [[typingTransform]] + */ + trait TypingTransformApi extends TransformApi { + /** Temporarily pushes the given symbol onto the owner stack, creating a new local typer, + * invoke the given operation and then rollback the changes to the owner stack. + */ + def atOwner[T](owner: Symbol)(op: => T): T + + /** Temporarily pushes the given tree onto the recursion stack, and then calls `atOwner(symbol)(trans)`. + */ + def atOwner[T](tree: Tree, owner: Symbol)(op: => T): T + + /** Returns the symbol currently on the top of the owner stack. + * If we're not inside any `atOwner` call, then macro application's context owner will be used. + */ + def currentOwner: Symbol + + /** Typechecks the given tree using the local typer currently on the top of the owner stack. + * If we're not inside any `atOwner` call, then macro application's callsite typer will be used. + */ + def typecheck(tree: Tree): Tree + } + + /** Transforms a given tree using the provided function. + * @see [[TypingTransformApi]] + */ + def typingTransform(tree: Tree)(transformer: (Tree, TypingTransformApi) => Tree): Tree + + /** Transforms a given tree at a given owner using the provided function. + * @see [[TypingTransformApi]] + */ + def typingTransform(tree: Tree, owner: Symbol)(transformer: (Tree, TypingTransformApi) => Tree): Tree + } +} diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala index ff1f7a3b28..e35a5c8622 100644 --- a/src/reflect/scala/reflect/macros/Reifiers.scala +++ b/src/reflect/scala/reflect/macros/Reifiers.scala @@ -15,7 +15,7 @@ trait Reifiers { * For more information and examples see the documentation for `Universe.reify`. * * The produced tree will be bound to the specified `universe` and `mirror`. - * Possible values for `universe` include `universe.treeBuild.mkRuntimeUniverseRef`. + * Possible values for `universe` include `universe.internal.gen.mkRuntimeUniverseRef`. * Possible values for `mirror` include `EmptyTree` (in that case the reifier will automatically pick an appropriate mirror). * * This function is deeply connected to `Universe.reify`, a macro that reifies arbitrary expressions into runtime trees. diff --git a/src/reflect/scala/reflect/macros/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala deleted file mode 100644 index 7f57274347..0000000000 --- a/src/reflect/scala/reflect/macros/TreeBuilder.scala +++ /dev/null @@ -1,97 +0,0 @@ -package scala -package reflect -package macros - -/** - * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> - * - * A helper available in [[scala.reflect.macros.Universe]] that defines shorthands for the - * most common tree-creating functions. - */ -@deprecated("Use quasiquotes instead", "2.11.0") -abstract class TreeBuilder { - val global: Universe - - import global._ - - /** Builds a reference to value whose type is given stable prefix. - * The type must be suitable for this. For example, it - * must not be a TypeRef pointing to an abstract type variable. - */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedQualifier(tpe: Type): Tree - - /** Builds a reference to value whose type is given stable prefix. - * If the type is unsuitable, e.g. it is a TypeRef for an - * abstract type variable, then an Ident will be made using - * termSym as the Ident's symbol. In that case, termSym must - * not be NoSymbol. - */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree - - /** Builds a typed reference to given symbol with given stable prefix. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedRef(pre: Type, sym: Symbol): RefTree - - /** Builds a typed reference to given symbol. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedRef(sym: Symbol): RefTree - - /** Builds an untyped reference to given symbol. Requires the symbol to be static. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkUnattributedRef(sym: Symbol): RefTree - - /** Builds an untyped reference to symbol with given name. Requires the symbol to be static. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkUnattributedRef(fullName: Name): RefTree - - /** Builds a typed This reference to given symbol. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedThis(sym: Symbol): This - - /** Builds a typed Ident with an underlying symbol. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedIdent(sym: Symbol): RefTree - - /** Builds a typed Select with an underlying symbol. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkAttributedSelect(qual: Tree, sym: Symbol): RefTree - - /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...) - * There are a number of variations. - * - * @param receiver symbol of the method receiver - * @param methodName name of the method to call - * @param targs type arguments (if Nil, no TypeApply node will be generated) - * @param args value arguments - * @return the newly created trees. - */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(method: Symbol, args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(target: Tree, args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree - - @deprecated("Use quasiquotes instead", "2.11.0") - def mkNullaryCall(method: Symbol, targs: List[Type]): Tree - - /** A tree that refers to the runtime reflexive universe, `scala.reflect.runtime.universe`. */ - @deprecated("Use quasiquotes instead", "2.11.0") - def mkRuntimeUniverseRef: Tree -} diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala index 6c077de1d2..d0dccb469d 100644 --- a/src/reflect/scala/reflect/macros/Typers.scala +++ b/src/reflect/scala/reflect/macros/Typers.scala @@ -2,6 +2,8 @@ package scala package reflect package macros +import scala.reflect.internal.{Mode => InternalMode} + /** * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> * @@ -23,13 +25,43 @@ trait Typers { */ def openMacros: List[blackbox.Context] + /** Represents mode of operations of the typechecker underlying `c.typecheck` calls. + * Is necessary since the shape of the typechecked tree alone is not enough to guess how it should be typechecked. + * Can be EXPRmode (typecheck as a term), TYPEmode (typecheck as a type) or PATTERNmode (typecheck as a pattern). + */ + // I'd very much like to make use of https://github.com/dsl-paradise/dsl-paradise here! + type TypecheckMode + + /** Indicates that an argument to `c.typecheck` should be typechecked as a term. + * This is the default typechecking mode in Scala 2.11 and the only one supported in Scala 2.10. + */ + val TERMmode: TypecheckMode + + /** Indicates that an argument to `c.typecheck` should be typechecked as a type. + */ + val TYPEmode: TypecheckMode + + /** Indicates that an argument to `c.typecheck` should be typechecked as a pattern. + */ + val PATTERNmode: TypecheckMode + + /** @see `scala.reflect.macros.TypecheckException` + */ + type TypecheckException = scala.reflect.macros.TypecheckException + + /** @see `scala.reflect.macros.TypecheckException` + */ + val TypecheckException = scala.reflect.macros.TypecheckException + /** @see `Typers.typecheck` */ @deprecated("Use `c.typecheck` instead", "2.11.0") def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = - typecheck(tree, pt, silent, withImplicitViewsDisabled, withMacrosDisabled) + typecheck(tree, TERMmode, pt, silent, withImplicitViewsDisabled, withMacrosDisabled) - /** 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 + * under typechecking mode specified in `mode` with [[EXPRmode]] being default. + * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings. * * If `silent` is false, `TypecheckException` 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. @@ -42,7 +74,7 @@ trait Typers { * * @throws [[scala.reflect.macros.TypecheckException]] */ - def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree + def typecheck(tree: Tree, mode: TypecheckMode = TERMmode, pt: Type = universe.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. diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala index bc5c8b2840..1eb67215bb 100644 --- a/src/reflect/scala/reflect/macros/Universe.scala +++ b/src/reflect/scala/reflect/macros/Universe.scala @@ -2,6 +2,9 @@ package scala package reflect package macros +import scala.language.implicitConversions +import scala.language.higherKinds + /** * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> * @@ -17,109 +20,93 @@ package macros */ abstract class Universe extends scala.reflect.api.Universe { - /** A factory that encapsulates common tree-building functions. - * @group Macros - */ - @deprecated("Use quasiquotes instead", "2.11.0") - val treeBuild: TreeBuilder { val global: Universe.this.type } + /** @inheritdoc */ + override type Internal <: MacroInternalApi - /** The API of reflection artifacts that support [[scala.reflect.macros.Attachments]]. - * These artifacts are trees and symbols. - * @group Macros - */ - trait AttachableApi { - /** The attachment of the reflection artifact. */ - def attachments: Attachments { type Pos = Position } + /** @inheritdoc */ + trait MacroInternalApi extends InternalApi { internal => - /** Updates the attachment with the payload slot of T added/updated with the provided value. - * Replaces an existing payload of the same type, if exists. - * Returns the reflection artifact itself. + /** Adds a given symbol to the given scope. */ - def updateAttachment[T: ClassTag](attachment: T): AttachableApi.this.type + def enter(scope: Scope, sym: Symbol): scope.type - /** Update the attachment with the payload of the given class type `T` removed. - * Returns the reflection artifact itself. + /** Removes a given symbol to the given scope. */ - def removeAttachment[T: ClassTag]: AttachableApi.this.type - } + def unlink(scope: Scope, sym: Symbol): scope.type - // Symbol extensions --------------------------------------------------------------- + /** Collects all the symbols defined by subtrees of `tree` that are owned by `prev`, + * and then changes their owner to point to `next`. + * + * This is an essential tool to battle owner chain corruption when moving trees + * from one lexical context to another. Whenever you take an attributed tree that + * has been typechecked under the Context owned by some symbol (let's call it `x`) + * and splice it elsewhere, into the Context owned by another symbol (let's call it `y`), + * it is imperative that you either call `untypecheck` or do `changeOwner(tree, x, y)`. + * + * Since at the moment `untypecheck` has fundamental problem that can sometimes lead to tree corruption, + * `changeOwner` becomes an indispensible tool in building 100% robust macros. + * Future versions of the reflection API might obviate the need in taking care of + * these low-level details, but at the moment this is what we've got. + */ + def changeOwner(tree: Tree, prev: Symbol, next: Symbol): tree.type - /** The `Symbol` API is extended for macros: See [[SymbolContextApi]] for details. - * - * @group Macros - */ - override type Symbol >: Null <: SymbolContextApi + /** Advanced tree factories */ + val gen: TreeGen - /** The extended API of symbols that's supported in macro context universes - * @group API - */ - trait SymbolContextApi extends SymbolApi with AttachableApi { self: Symbol => + /** The attachment of the symbol. */ + def attachments(symbol: Symbol): Attachments { type Pos = Position } - /** If this symbol is a skolem, its corresponding type parameter, otherwise the symbol itself. - * - * [[https://groups.google.com/forum/#!msg/scala-internals/0j8laVNTQsI/kRXMF_c8bGsJ To quote Martin Odersky]], - * skolems are synthetic type "constants" that are copies of existentially bound or universally - * bound type variables. E.g. if one is inside the right-hand side of a method: - * - * {{{ - * def foo[T](x: T) = ... foo[List[T]].... - * }}} - * - * the skolem named `T` refers to the unknown type instance of `T` when `foo` is called. It needs to be different - * from the type parameter because in a recursive call as in the `foo[List[T]]` above the type parameter gets - * substituted with `List[T]`, but the ''type skolem'' stays what it is. - * - * The other form of skolem is an ''existential skolem''. Say one has a function - * - * {{{ - * def bar(xs: List[T] forSome { type T }) = xs.head - * }}} - * - * then each occurrence of `xs` on the right will have type `List[T']` where `T'` is a fresh copy of `T`. + /** Updates the attachment with the payload slot of T added/updated with the provided value. + * Replaces an existing payload of the same type, if exists. + * Returns the symbol itself. */ - def deSkolemize: Symbol + def updateAttachment[T: ClassTag](symbol: Symbol, attachment: T): symbol.type - /** The position of this symbol. */ - def pos: Position + /** Update the attachment with the payload of the given class type `T` removed. + * Returns the symbol itself. + */ + def removeAttachment[T: ClassTag](symbol: Symbol): symbol.type + + /** Sets the `owner` of the symbol. */ + def setOwner(symbol: Symbol, newowner: Symbol): symbol.type - /** Sets the `typeSignature` of the symbol. */ - def setTypeSignature(tpe: Type): Symbol + /** Sets the `info` of the symbol. */ + def setInfo(symbol: Symbol, tpe: Type): symbol.type /** Sets the `annotations` of the symbol. */ - def setAnnotations(annots: Annotation*): Symbol + def setAnnotations(symbol: Symbol, annots: Annotation*): symbol.type /** Sets the `name` of the symbol. */ - def setName(name: Name): Symbol + def setName(symbol: Symbol, name: Name): symbol.type /** Sets the `privateWithin` of the symbol. */ - def setPrivateWithin(sym: Symbol): Symbol - } + def setPrivateWithin(symbol: Symbol, sym: Symbol): symbol.type - // Tree extensions --------------------------------------------------------------- + /** Enables `flags` on the symbol. */ + def setFlag(symbol: Symbol, flags: FlagSet): symbol.type - /** The `Tree` API is extended for macros: See [[TreeContextApi]] for details. - * - * @group Macros - */ - override type Tree >: Null <: TreeContextApi + /** Disables `flags` on the symbol. */ + def resetFlag(symbol: Symbol, flags: FlagSet): symbol.type - /** The extended API of trees that's supported in macro context universes - * @group API - */ - trait TreeContextApi extends TreeApi with AttachableApi { self: Tree => + /** The attachment of the tree. */ + def attachments(tree: Tree): Attachments { type Pos = Position } - /** Sets the `pos` of the tree. Returns `Unit`. */ - def pos_=(pos: Position): Unit + /** Updates the attachment with the payload slot of T added/updated with the provided value. + * Replaces an existing payload of the same type, if exists. + * Returns the tree itself. + */ + def updateAttachment[T: ClassTag](tree: Tree, attachment: T): tree.type - /** Sets the `pos` of the tree. Returns the tree itself. */ - def setPos(newpos: Position): Tree + /** Update the attachment with the payload of the given class type `T` removed. + * Returns the tree itself. + */ + def removeAttachment[T: ClassTag](tree: Tree): tree.type - /** Sets the `tpe` of the tree. Returns `Unit`. */ - @deprecated("Use setType", "2.11.0") def tpe_=(t: Type): Unit + /** Sets the `pos` of the tree. Returns the tree itself. */ + def setPos(tree: Tree, newpos: Position): tree.type /** Sets the `tpe` of the tree. Returns the tree itself. */ - def setType(tp: Type): Tree + def setType(tree: Tree, tp: Type): tree.type /** Like `setType`, but if this is a previously empty TypeTree that * fact is remembered so that `untypecheck` will snap back. @@ -139,63 +126,315 @@ abstract class Universe extends scala.reflect.api.Universe { * and therefore should be abandoned if the current line of type * inquiry doesn't work out. */ - def defineType(tp: Type): Tree - - /** Sets the `symbol` of the tree. Returns `Unit`. */ - def symbol_=(sym: Symbol): Unit + def defineType(tree: Tree, tp: Type): tree.type /** Sets the `symbol` of the tree. Returns the tree itself. */ - def setSymbol(sym: Symbol): Tree - } + def setSymbol(tree: Tree, sym: Symbol): tree.type - /** @inheritdoc */ - override type SymTree >: Null <: Tree with SymTreeContextApi + /** Sets the `original` field of the type tree. */ + def setOriginal(tt: TypeTree, original: Tree): TypeTree - /** The extended API of sym trees that's supported in macro context universes - * @group API - */ - trait SymTreeContextApi extends SymTreeApi { this: SymTree => - /** Sets the `symbol` field of the sym tree. */ - var symbol: Symbol - } + /** Mark a variable as captured; i.e. force boxing in a *Ref type. + * @group Macros + */ + def captureVariable(vble: Symbol): Unit - /** @inheritdoc */ - override type TypeTree >: Null <: TypTree with TypeTreeContextApi + /** Mark given identifier as a reference to a captured variable itself + * suppressing dereferencing with the `elem` field. + * @group Macros + */ + def referenceCapturedVariable(vble: Symbol): Tree - /** The extended API of sym trees that's supported in macro context universes - * @group API - */ - trait TypeTreeContextApi extends TypeTreeApi { this: TypeTree => - /** Sets the `original` field of the type tree. */ - def setOriginal(tree: Tree): this.type + /** Convert type of a captured variable to *Ref type. + * @group Macros + */ + def capturedVariableType(vble: Symbol): Type + + /** Retrieves the untyped list of subpatterns attached to selector dummy of an UnApply node. + * Useful in writing quasiquoting macros that do pattern matching. + */ + def subpatterns(tree: Tree): Option[List[Tree]] + + /** @inheritdoc */ + override type Decorators <: MacroDecoratorApi + + /** @inheritdoc */ + trait MacroDecoratorApi extends DecoratorApi { + /** Extension methods for scopes */ + type ScopeDecorator[T <: Scope] <: MacroScopeDecoratorApi[T] + + /** @see [[ScopeDecorator]] */ + implicit def scopeDecorator[T <: Scope](tree: T): ScopeDecorator[T] + + /** @see [[ScopeDecorator]] */ + class MacroScopeDecoratorApi[T <: Scope](val scope: T) { + /** @see [[internal.enter]] */ + def enter(sym: Symbol): T = internal.enter(scope, sym) + + /** @see [[internal.unlink]] */ + def unlink(sym: Symbol): T = internal.unlink(scope, sym) + } + + /** @inheritdoc */ + override type TreeDecorator[T <: Tree] <: MacroTreeDecoratorApi[T] + + /** @see [[TreeDecorator]] */ + class MacroTreeDecoratorApi[T <: Tree](override val tree: T) extends TreeDecoratorApi[T](tree) { + /** @see [[internal.changeOwner]] */ + def changeOwner(prev: Symbol, next: Symbol): tree.type = internal.changeOwner(tree, prev, next) + + /** @see [[internal.attachments]] */ + def attachments: Attachments { type Pos = Position } = internal.attachments(tree) + + /** @see [[internal.updateAttachment]] */ + def updateAttachment[A: ClassTag](attachment: A): tree.type = internal.updateAttachment(tree, attachment) + + /** @see [[internal.removeAttachment]] */ + def removeAttachment[A: ClassTag]: T = internal.removeAttachment[A](tree) + + /** @see [[internal.setPos]] */ + def setPos(newpos: Position): T = internal.setPos(tree, newpos) + + /** @see [[internal.setType]] */ + def setType(tp: Type): T = internal.setType(tree, tp) + + /** @see [[internal.defineType]] */ + def defineType(tp: Type): T = internal.defineType(tree, tp) + + /** @see [[internal.setSymbol]] */ + def setSymbol(sym: Symbol): T = internal.setSymbol(tree, sym) + } + + /** Extension methods for typetrees */ + type TypeTreeDecorator[T <: TypeTree] <: MacroTypeTreeDecoratorApi[T] + + /** @see [[TypeTreeDecorator]] */ + implicit def typeTreeDecorator[T <: TypeTree](tt: T): TypeTreeDecorator[T] + + /** @see [[TypeTreeDecorator]] */ + class MacroTypeTreeDecoratorApi[T <: TypeTree](val tt: T) { + /** @see [[internal.setOriginal]] */ + def setOriginal(tree: Tree): TypeTree = internal.setOriginal(tt, tree) + } + + /** @inheritdoc */ + override type SymbolDecorator[T <: Symbol] <: MacroSymbolDecoratorApi[T] + + /** @see [[TreeDecorator]] */ + class MacroSymbolDecoratorApi[T <: Symbol](override val symbol: T) extends SymbolDecoratorApi[T](symbol) { + /** @see [[internal.attachments]] */ + def attachments: Attachments { type Pos = Position } = internal.attachments(symbol) + + /** @see [[internal.updateAttachment]] */ + def updateAttachment[A: ClassTag](attachment: A): T = internal.updateAttachment(symbol, attachment) + + /** @see [[internal.removeAttachment]] */ + def removeAttachment[A: ClassTag]: T = internal.removeAttachment[A](symbol) + + /** @see [[internal.setOwner]] */ + def setOwner(newowner: Symbol): T = internal.setOwner(symbol, newowner) + + /** @see [[internal.setInfo]] */ + def setInfo(tpe: Type): T = internal.setInfo(symbol, tpe) + + /** @see [[internal.setAnnotations]] */ + def setAnnotations(annots: Annotation*): T = internal.setAnnotations(symbol, annots: _*) + + /** @see [[internal.setName]] */ + def setName(name: Name): T = internal.setName(symbol, name) + + /** @see [[internal.setPrivateWithin]] */ + def setPrivateWithin(sym: Symbol): T = internal.setPrivateWithin(symbol, sym) + + /** @see [[internal.setFlag]] */ + def setFlag(flags: FlagSet): T = internal.setFlag(symbol, flags) + + /** @see [[internal.setFlag]] */ + def resetFlag(flags: FlagSet): T = internal.resetFlag(symbol, flags) + } + } } - /** @inheritdoc */ - override type Ident >: Null <: RefTree with IdentContextApi + /** @group Internal */ + trait TreeGen { + /** Builds a reference to value whose type is given stable prefix. + * The type must be suitable for this. For example, it + * must not be a TypeRef pointing to an abstract type variable. + */ + def mkAttributedQualifier(tpe: Type): Tree - /** The extended API of idents that's supported in macro context universes - * @group API - */ - trait IdentContextApi extends IdentApi { this: Ident => - /** Was this ident created from a backquoted identifier? */ - def isBackquoted: Boolean + /** Builds a reference to value whose type is given stable prefix. + * If the type is unsuitable, e.g. it is a TypeRef for an + * abstract type variable, then an Ident will be made using + * termSym as the Ident's symbol. In that case, termSym must + * not be NoSymbol. + */ + def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree + + /** Builds a typed reference to given symbol with given stable prefix. */ + def mkAttributedRef(pre: Type, sym: Symbol): RefTree + + /** Builds a typed reference to given symbol. */ + def mkAttributedRef(sym: Symbol): RefTree + + def stabilize(tree: Tree): Tree + + def mkAttributedStableRef(pre: Type, sym: Symbol): Tree + + def mkAttributedStableRef(sym: Symbol): Tree + + /** Builds an untyped reference to given symbol. Requires the symbol to be static. */ + def mkUnattributedRef(sym: Symbol): RefTree + + /** Builds an untyped reference to symbol with given name. Requires the symbol to be static. */ + def mkUnattributedRef(fullName: Name): RefTree + + /** Builds a typed This reference to given symbol. */ + def mkAttributedThis(sym: Symbol): This + + /** Builds a typed Ident with an underlying symbol. */ + def mkAttributedIdent(sym: Symbol): RefTree + + /** Builds a typed Select with an underlying symbol. */ + def mkAttributedSelect(qual: Tree, sym: Symbol): RefTree + + /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...) + * There are a number of variations. + * + * @param receiver symbol of the method receiver + * @param methodName name of the method to call + * @param targs type arguments (if Nil, no TypeApply node will be generated) + * @param args value arguments + * @return the newly created trees. + */ + def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree + + def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree + + def mkMethodCall(method: Symbol, args: List[Tree]): Tree + + def mkMethodCall(target: Tree, args: List[Tree]): Tree + + def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree + + def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree + + def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree + + def mkNullaryCall(method: Symbol, targs: List[Type]): Tree + + /** A tree that refers to the runtime reflexive universe, `scala.reflect.runtime.universe`. */ + def mkRuntimeUniverseRef: Tree + + def mkZero(tp: Type): Tree + + def mkCast(tree: Tree, pt: Type): Tree } - /** Mark a variable as captured; i.e. force boxing in a *Ref type. - * @group Macros - */ - def captureVariable(vble: Symbol): Unit + /** @see [[internal.gen]] */ + @deprecated("Use `internal.gen` instead", "2.11.0") + val treeBuild: TreeGen - /** Mark given identifier as a reference to a captured variable itself - * suppressing dereferencing with the `elem` field. - * @group Macros - */ - def referenceCapturedVariable(vble: Symbol): Tree + /** @inheritdoc */ + type Compat <: MacroCompatApi - /** Convert type of a captured variable to *Ref type. - * @group Macros + /** @see [[compat]] + * @group Internal */ - def capturedVariableType(vble: Symbol): Type + trait MacroCompatApi extends CompatApi { + /** Scala 2.10 compatibility enrichments for Symbol. */ + implicit class MacroCompatibleSymbol(symbol: Symbol) { + /** @see [[InternalMacroApi.attachments]] */ + @deprecated("Use `internal.attachments` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def attachments: Attachments { type Pos = Position } = internal.attachments(symbol) + + /** @see [[InternalMacroApi.updateAttachment]] */ + @deprecated("Use `internal.updateAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def updateAttachment[T: ClassTag](attachment: T): Symbol = internal.updateAttachment[T](symbol, attachment) + + /** @see [[InternalMacroApi.removeAttachment]] */ + @deprecated("Use `internal.removeAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def removeAttachment[T: ClassTag]: Symbol = internal.removeAttachment[T](symbol) + + /** @see [[InternalMacroApi.setInfo]] */ + @deprecated("Use `internal.setInfo` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setTypeSignature(tpe: Type): Symbol = internal.setInfo(symbol, tpe) + + /** @see [[InternalMacroApi.setAnnotations]] */ + @deprecated("Use `internal.setAnnotations` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setAnnotations(annots: Annotation*): Symbol = internal.setAnnotations(symbol, annots: _*) + + /** @see [[InternalMacroApi.setName]] */ + @deprecated("Use `internal.setName` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setName(name: Name): Symbol = internal.setName(symbol, name) + + /** @see [[InternalMacroApi.setPrivateWithin]] */ + @deprecated("Use `internal.setPrivateWithin` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setPrivateWithin(sym: Symbol): Symbol = internal.setPrivateWithin(symbol, sym) + } + + /** Scala 2.10 compatibility enrichments for TypeTree. */ + implicit class MacroCompatibleTree(tree: Tree) { + /** @see [[InternalMacroApi.attachments]] */ + @deprecated("Use `internal.attachments` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def attachments: Attachments { type Pos = Position } = internal.attachments(tree) + + /** @see [[InternalMacroApi.updateAttachment]] */ + @deprecated("Use `internal.updateAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def updateAttachment[T: ClassTag](attachment: T): Tree = internal.updateAttachment[T](tree, attachment) + + /** @see [[InternalMacroApi.removeAttachment]] */ + @deprecated("Use `internal.removeAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def removeAttachment[T: ClassTag]: Tree = internal.removeAttachment[T](tree) + + /** @see [[InternalMacroApi.setPos]] */ + @deprecated("Use `internal.setPos` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def pos_=(pos: Position): Unit = internal.setPos(tree, pos) + + /** @see [[InternalMacroApi.setPos]] */ + @deprecated("Use `internal.setPos` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setPos(newpos: Position): Tree = internal.setPos(tree, newpos) + + /** @see [[InternalMacroApi.setType]] */ + @deprecated("Use `internal.setType` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def tpe_=(t: Type): Unit = internal.setType(tree, t) + + /** @see [[InternalMacroApi.setType]] */ + @deprecated("Use `internal.setType` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setType(tp: Type): Tree = internal.setType(tree, tp) + + /** @see [[InternalMacroApi.defineType]] */ + @deprecated("Use `internal.defineType` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def defineType(tp: Type): Tree = internal.defineType(tree, tp) + + /** @see [[InternalMacroApi.setSymbol]] */ + @deprecated("Use `internal.setSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def symbol_=(sym: Symbol): Unit = internal.setSymbol(tree, sym) + + /** @see [[InternalMacroApi.setSymbol]] */ + @deprecated("Use `internal.setSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setSymbol(sym: Symbol): Tree = internal.setSymbol(tree, sym) + } + + /** Scala 2.10 compatibility enrichments for TypeTree. */ + implicit class CompatibleTypeTree(tt: TypeTree) { + /** @see [[InternalMacroApi.setOriginal]] */ + @deprecated("Use `internal.setOriginal` instead or import `internal.decorators._` for infix syntax", "2.11.0") + def setOriginal(tree: Tree): TypeTree = internal.setOriginal(tt, tree) + } + + /** @see [[InternalMacroApi.captureVariable]] */ + @deprecated("Use `internal.captureVariable` instead", "2.11.0") + def captureVariable(vble: Symbol): Unit = internal.captureVariable(vble) + + /** @see [[InternalMacroApi.captureVariable]] */ + @deprecated("Use `internal.referenceCapturedVariable` instead", "2.11.0") + def referenceCapturedVariable(vble: Symbol): Tree = internal.referenceCapturedVariable(vble) + + /** @see [[InternalMacroApi.captureVariable]] */ + @deprecated("Use `internal.capturedVariableType` instead", "2.11.0") + def capturedVariableType(vble: Symbol): Type = internal.capturedVariableType(vble) + } /** The type of compilation runs. * @see [[scala.reflect.macros.Enclosures]] diff --git a/src/reflect/scala/reflect/macros/blackbox/Context.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala index 05d9595c3a..2f9c512efa 100644 --- a/src/reflect/scala/reflect/macros/blackbox/Context.scala +++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala @@ -42,7 +42,8 @@ trait Context extends Aliases with Typers with Parsers with Evals - with ExprUtils { + with ExprUtils + with Internals { /** The compile-time universe. */ val universe: Universe diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index bc95b839b7..f5bddb1784 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -22,7 +22,7 @@ import ReflectionUtils._ import scala.language.existentials import scala.runtime.{ScalaRunTime, BoxesRunTime} -private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable => +private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable => private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]() @@ -33,9 +33,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni jm } - override type RuntimeClass = java.lang.Class[_] - override type Mirror = JavaMirror + implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[JavaMirror]) override lazy val rootMirror: Mirror = createMirror(NoSymbol, rootClassLoader) @@ -81,10 +80,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni // the same thing is done by the `missingHook` below override def staticPackage(fullname: String): ModuleSymbol = try super.staticPackage(fullname) - catch { - case _: MissingRequirementError => - makeScalaPackage(fullname) - } + catch { case _: ScalaReflectionException => makeScalaPackage(fullname) } // ----------- Caching ------------------------------------------------------------------ @@ -146,7 +142,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni object ConstantArg { def enumToSymbol(enum: Enum[_]): Symbol = { val staticPartOfEnum = classToScala(enum.getClass).companionSymbol - staticPartOfEnum.typeSignature.declaration(enum.name: TermName) + staticPartOfEnum.info.declaration(enum.name: TermName) } def unapply(schemaAndValue: (jClass[_], Any)): Option[Any] = schemaAndValue match { @@ -270,7 +266,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val isDerivedValueClass = symbol.isDerivedValueClass lazy val boxer = runtimeClass(symbol.toType).getDeclaredConstructors().head lazy val unboxer = { - val fields @ (field :: _) = symbol.toType.declarations.collect{ case ts: TermSymbol if ts.isParamAccessor && ts.isMethod => ts }.toList + val fields @ (field :: _) = symbol.toType.decls.collect{ case ts: TermSymbol if ts.isParamAccessor && ts.isMethod => ts }.toList assert(fields.length == 1, s"$symbol: $fields") runtimeClass(symbol.asClass).getDeclaredMethod(field.name.toString) } @@ -293,32 +289,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni jfield.set(receiver, if (isDerivedValueClass) unboxer.invoke(value) else 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.paramss.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.paramss) - } - sig += s": ${symbol.returnType}" - sig + override def toString = s"field mirror for ${showDecl(symbol)} (bound to $receiver)" } // the "symbol == Any_getClass || symbol == Object_getClass" test doesn't cut it @@ -373,7 +344,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni override def toString = { val what = if (symbol.isConstructor) "constructor mirror" else "method mirror" - s"$what for ${showMethodSig(symbol)} (bound to $receiver)" + s"$what for ${showDecl(symbol)} (bound to $receiver)" } } @@ -469,7 +440,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni private class BytecodelessMethodMirror[T: ClassTag](val receiver: T, val symbol: MethodSymbol) extends MethodMirror { def bind(newReceiver: Any) = new BytecodelessMethodMirror(newReceiver.asInstanceOf[T], symbol) - override def toString = s"bytecodeless method mirror for ${showMethodSig(symbol)} (bound to $receiver)" + override def toString = s"bytecodeless method mirror for ${showDecl(symbol)} (bound to $receiver)" def apply(args: Any*): Any = { // checking type conformance is too much of a hassle, so we don't do it here @@ -483,7 +454,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni if (!perfectMatch && !varargMatch) { val n_arguments = if (isVarArgsList(params)) s"${params.length - 1} or more" else s"${params.length}" val s_arguments = if (params.length == 1 && !isVarArgsList(params)) "argument" else "arguments" - abort(s"${showMethodSig(symbol)} takes $n_arguments $s_arguments") + abort(s"${showDecl(symbol)} takes $n_arguments $s_arguments") } def objReceiver = receiver.asInstanceOf[AnyRef] @@ -640,6 +611,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni info(s"unpickling Scala $clazz and $module, owner = ${clazz.owner}") val bytes = ssig.getBytes val len = ByteCodecs.decode(bytes) + assignAssociatedFile(clazz, module, jclazz) unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) markAllCompleted(clazz, module) case None => @@ -649,6 +621,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val encoded = slsig flatMap (_.getBytes) val len = ByteCodecs.decode(encoded) val decoded = encoded.take(len) + assignAssociatedFile(clazz, module, jclazz) unpickler.unpickle(decoded, 0, clazz, module, jclazz.getName) markAllCompleted(clazz, module) case None => @@ -690,6 +663,12 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni } } + private def assignAssociatedFile(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = { + val associatedFile = ReflectionUtils.associatedFile(jclazz) + clazz.associatedFile = associatedFile + if (module != NoSymbol) module.associatedFile = associatedFile + } + /** * Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`. * Also creates `@throws` annotations if necessary. @@ -745,6 +724,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym) + assignAssociatedFile(clazz, module, jclazz) propagatePackageBoundary(jclazz, relatedSymbols: _*) copyAnnotations(clazz, jclazz) // to do: annotations to set also for module? @@ -961,7 +941,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni val owner = ownerModule.moduleClass val name = (fullname: TermName) drop split + 1 val opkg = owner.info decl name - if (opkg.isPackage) + if (opkg.hasPackageFlag) opkg.asModule else if (opkg == NoSymbol) { val pkg = owner.newPackage(name) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala index f6556a442d..b5446694ed 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala @@ -2,33 +2,66 @@ package scala package reflect package runtime +import scala.reflect.internal.{TreeInfo, SomePhase} +import scala.reflect.internal.{SymbolTable => InternalSymbolTable} +import scala.reflect.runtime.{SymbolTable => RuntimeSymbolTable} +import scala.reflect.api.{TreeCreator, TypeCreator, Universe} + /** An implementation of [[scala.reflect.api.Universe]] for runtime reflection using JVM classloaders. * * Should not be instantiated directly, use [[scala.reflect.runtime.universe]] instead. * * @contentDiagram hideNodes "*Api" "*Extractor" */ -class JavaUniverse extends internal.SymbolTable with JavaUniverseForce with ReflectSetup with runtime.SymbolTable { self => +class JavaUniverse extends InternalSymbolTable with JavaUniverseForce with ReflectSetup with RuntimeSymbolTable { self => override def inform(msg: String): Unit = log(msg) - def picklerPhase = internal.SomePhase - def erasurePhase = internal.SomePhase - + def picklerPhase = SomePhase + def erasurePhase = SomePhase lazy val settings = new Settings private val isLogging = sys.props contains "scala.debug.reflect" def log(msg: => AnyRef): Unit = if (isLogging) Console.err.println("[reflect] " + msg) type TreeCopier = InternalTreeCopierOps + implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier]) def newStrictTreeCopier: TreeCopier = new StrictTreeCopier def newLazyTreeCopier: TreeCopier = new LazyTreeCopier def currentFreshNameCreator = globalFreshNameCreator + override lazy val internal: Internal = new SymbolTableInternal { + override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: Universe # TypeTag[T]): Manifest[T] = { + // SI-6239: make this conversion more precise + val mirror = mirror0.asInstanceOf[Mirror] + val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe) + Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]] + } + override def manifestToTypeTag[T](mirror0: Any, manifest: Manifest[T]): Universe # TypeTag[T] = + TypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator { + def apply[U <: Universe with Singleton](mirror: scala.reflect.api.Mirror[U]): U # Type = { + mirror.universe match { + case ju: JavaUniverse => + val jm = mirror.asInstanceOf[ju.Mirror] + val sym = jm.classSymbol(manifest.runtimeClass) + val tpe = + if (manifest.typeArguments.isEmpty) sym.toType + else { + val tags = manifest.typeArguments map (targ => ju.internal.manifestToTypeTag(jm, targ)) + ju.appliedType(sym.toTypeConstructor, tags map (_.in(jm).tpe)) + } + tpe.asInstanceOf[U # Type] + case u => + u.internal.manifestToTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe + } + } + }) + } + // can't put this in runtime.Trees since that's mixed with Global in ReflectGlobal, which has the definition from internal.Trees object treeInfo extends { val global: JavaUniverse.this.type = JavaUniverse.this - } with internal.TreeInfo + } with TreeInfo init() diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 0fcf215580..dcd262c288 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -26,11 +26,13 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => TypeTag.Null.tpe this.settings + this.internal this.treeInfo this.rootMirror - this.treeBuild this.traceSymbols this.perRunCaches + this.compat + this.treeBuild this.FreshNameExtractor this.FixedMirrorTreeCreator this.FixedMirrorTypeCreator @@ -106,9 +108,11 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.UnmappableAnnotation this.ErroneousAnnotation this.ThrownException + this.typeNames this.tpnme this.fulltpnme this.binarynme + this.termNames this.nme this.sn this.Constant @@ -279,6 +283,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.ReflectPackage definitions.ReflectApiPackage definitions.ReflectRuntimePackage + definitions.UniverseClass definitions.PartialManifestModule definitions.FullManifestClass definitions.FullManifestModule diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala index d642b25127..a4bd698068 100644 --- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala +++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala @@ -9,6 +9,8 @@ package reflect.runtime import java.lang.{Class => jClass} import java.lang.reflect.{ Method, InvocationTargetException, UndeclaredThrowableException } import scala.reflect.internal.util.AbstractFileClassLoader +import scala.reflect.io._ +import java.io.{File => JFile} /** A few java-reflection oriented utility functions useful during reflection bootstrapping. */ @@ -97,5 +99,74 @@ object ReflectionUtils { object EnclosedInConstructor extends EnclosedIn(_.getEnclosingConstructor) object EnclosedInClass extends EnclosedIn(_.getEnclosingClass) object EnclosedInPackage extends EnclosedIn(_.getPackage) + + def associatedFile(clazz: Class[_]): AbstractFile = { + // TODO: I agree with Jason - this implementation isn't something that we'd like to support + // therefore I'm having it commented out and this function will now return NoAbstractFile + // I think we can keep the source code though, because it can be useful to the others + // + // def inferAssociatedFile(clazz: Class[_]): AbstractFile = { + // // http://stackoverflow.com/questions/227486/find-where-java-class-is-loaded-from + // try { + // var cl = clazz.getClassLoader() + // if (cl == null) { + // cl = ClassLoader.getSystemClassLoader() + // while (cl != null && cl.getParent != null) cl = cl.getParent + // } + // var result: AbstractFile = null + // if (cl != null) { + // val name = clazz.getCanonicalName() + // val resource = cl.getResource(name.replace(".", "/") + ".class") + // if (resource != null) { + // def fromFile(file: String) = AbstractFile.getFile(file) + // def fromJarEntry(jarfile: String, entrypath: String) = { + // val jar = fromFile(jarfile) + // new VirtualFile(clazz.getName, entrypath) { + // lazy val impl: AbstractFile = { + // def loop(root: AbstractFile, path: List[String]): AbstractFile = { + // def find(name: String) = root.iterator.find(_.name == name).getOrElse(NoAbstractFile) + // path match { + // case step :: Nil => find(step) + // case step :: rest => loop(find(step), rest) + // case Nil => NoAbstractFile + // } + // } + // loop(ZipArchive.fromFile(new JFile(jarfile)), entrypath.split("/").toList) + // } + // override def container = impl.container + // override def lastModified = impl.lastModified + // override def input = impl.input + // override def sizeOption = impl.sizeOption + // override def underlyingSource = Some(jar) + // override def toString = jarfile + "(" + entrypath + ")" + // } + // } + // def fallback() = new VirtualFile(clazz.getName, resource.toString) + // result = resource.getProtocol match { + // case "file" => + // fromFile(resource.getFile) + // case "jar" => + // val intrajarUrl = new java.net.URL(resource.getFile) + // intrajarUrl.getProtocol match { + // case "file" => + // val file = intrajarUrl.getFile() + // val expectedSuffix = "!/" + name.replace(".", "/") + ".class" + // if (file.endsWith(expectedSuffix)) fromJarEntry(file.stripSuffix(expectedSuffix), expectedSuffix.substring(2)) + // else fallback() + // case _ => fallback() + // } + // case _ => + // fallback() + // } + // } + // } + // if (result != null) result else NoAbstractFile + // } catch { + // case _: Exception => NoAbstractFile + // } + // } + // inferAssociatedFile(clazz) + NoAbstractFile + } } diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala index d261fc5be9..8bb5757bbb 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -1031,7 +1031,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set def lastWarnings = mostRecentWarnings private lazy val importToGlobal = global mkImporter ru - private lazy val importToRuntime = ru mkImporter global + private lazy val importToRuntime = ru.internal createImporter global private lazy val javaMirror = ru.rootMirror match { case x: ru.JavaMirror => x case _ => null diff --git a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala index 53c7c82e89..c1122d4223 100644 --- a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala +++ b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala @@ -48,7 +48,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput // compiler to crash for reasons not yet known. def members = exitingTyper((effectiveTp.nonPrivateMembers.toList ++ anyMembers) filter (_.isPublic)) def methods = members.toList filter (_.isMethod) - def packages = members.toList filter (_.isPackage) + def packages = members.toList filter (_.hasPackageFlag) def aliases = members.toList filter (_.isAliasType) def memberNames = members map tos diff --git a/src/repl/scala/tools/nsc/interpreter/package.scala b/src/repl/scala/tools/nsc/interpreter/package.scala index 5dc9b65436..079097d7a2 100644 --- a/src/repl/scala/tools/nsc/interpreter/package.scala +++ b/src/repl/scala/tools/nsc/interpreter/package.scala @@ -157,7 +157,7 @@ package object interpreter extends ReplConfig with ReplStrings { def echoKind(tpe: Type, kind: Kind, verbose: Boolean) { def typeString(tpe: Type): String = { tpe match { - case TypeRef(_, sym, _) => typeString(sym.typeSignature) + case TypeRef(_, sym, _) => typeString(sym.info) case RefinedType(_, _) => tpe.toString case _ => tpe.typeSymbol.fullName } |