summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/internal/TreeInfo.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect/scala/reflect/internal/TreeInfo.scala')
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 4657fa0000..933afbea2b 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -18,7 +18,7 @@ abstract class TreeInfo {
val global: SymbolTable
import global._
- import definitions.{ isTupleSymbol, isVarArgsList, isCastSymbol, ThrowableClass, TupleClass, uncheckedStableClass, isBlackboxMacroBundleType, isWhiteboxContextType }
+ import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass, uncheckedStableClass, isBlackboxMacroBundleType, isWhiteboxContextType }
/* Does not seem to be used. Not sure what it does anyway.
def isOwnerDefinition(tree: Tree): Boolean = tree match {
@@ -128,6 +128,7 @@ abstract class TreeInfo {
symOk(tree.symbol)
&& tree.symbol.isStable
&& !definitions.isByNameParamType(tree.tpe)
+ && !definitions.isByName(tree.symbol)
&& (allowVolatile || !tree.symbol.hasVolatileType) // TODO SPEC: not required by spec
)
@@ -262,11 +263,18 @@ abstract class TreeInfo {
true
}
+ def isFunctionMissingParamType(tree: Tree): Boolean = tree match {
+ case Function(vparams, _) => vparams.exists(_.tpt.isEmpty)
+ case _ => false
+ }
+
+
/** Is symbol potentially a getter of a variable?
*/
def mayBeVarGetter(sym: Symbol): Boolean = sym.info match {
case NullaryMethodType(_) => sym.owner.isClass && !sym.isStable
case PolyType(_, NullaryMethodType(_)) => sym.owner.isClass && !sym.isStable
+ case PolyType(_, mt @ MethodType(_, _))=> mt.isImplicit && sym.owner.isClass && !sym.isStable
case mt @ MethodType(_, _) => mt.isImplicit && sym.owner.isClass && !sym.isStable
case _ => false
}
@@ -286,6 +294,26 @@ abstract class TreeInfo {
}
}
+
+ // No field for these vals, which means the ValDef carries the symbol of the getter (and not the field symbol)
+ // - abstract vals have no value we could store (until they become concrete, potentially)
+ // - lazy vals: the ValDef carries the symbol of the lazy accessor.
+ // The sausage factory will spew out the inner workings during the fields phase (actual bitmaps won't follow
+ // until lazyvals & mixins, though we should move this stuff from mixins to lazyvals now that fields takes care of mixing in lazy vals)
+ // - concrete vals in traits don't yield a field here either (their getter's RHS has the initial value)
+ // Constructors will move the assignment to the constructor, abstracting over the field using the field setter,
+ // and Fields will add a field to the class that mixes in the trait, implementing the accessors in terms of it
+ //
+ // The following case does receive a field symbol (until it's eliminated during the fields phase):
+ // - a concrete val with a statically known value (ConstantType)
+ // performs its side effect according to lazy/strict semantics, but doesn't need to store its value
+ // each access will "evaluate" the RHS (a literal) again
+ //
+ // We would like to avoid emitting unnecessary fields, but the required knowledge isn't available until after typer.
+ // The only way to avoid emitting & suppressing, is to not emit at all until we are sure to need the field, as dotty does.
+ def noFieldFor(vd: ValDef, owner: Symbol) = vd.mods.isDeferred || vd.mods.isLazy || (owner.isTrait && !vd.mods.hasFlag(PRESUPER))
+
+
def isDefaultGetter(tree: Tree) = {
tree.symbol != null && tree.symbol.isDefaultGetter
}
@@ -453,7 +481,8 @@ abstract class TreeInfo {
} map { dd =>
val DefDef(dmods, dname, _, _, _, drhs) = dd
// get access flags from DefDef
- val vdMods = (vmods &~ Flags.AccessFlags) | (dmods & Flags.AccessFlags).flags
+ val defDefMask = Flags.AccessFlags | OVERRIDE | IMPLICIT | DEFERRED
+ val vdMods = (vmods &~ defDefMask) | (dmods & defDefMask).flags
// for most cases lazy body should be taken from accessor DefDef
val vdRhs = if (vmods.isLazy) lazyValDefRhs(drhs) else vrhs
copyValDef(vd)(mods = vdMods, name = dname, rhs = vdRhs)