diff options
Diffstat (limited to 'src')
3 files changed, 27 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala index 546186479f..3a5845c8ca 100644 --- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala +++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala @@ -25,7 +25,7 @@ trait MethodSynthesis { type TT[T] = ru.TypeTag[T] type CT[T] = ClassTag[T] - def ValOrDefDef(sym: Symbol, body: Tree) = + def newValOrDefDef(sym: Symbol, body: Tree) = if (sym.isLazy) ValDef(sym, body) else DefDef(sym, body) @@ -67,7 +67,7 @@ trait MethodSynthesis { } private def finishMethod(method: Symbol, f: Symbol => Tree): Tree = - localTyper typed ValOrDefDef(method, f(method)) + localTyper typed newValOrDefDef(method, f(method)) private def createInternal(name: Name, f: Symbol => Tree, info: Type): Tree = { val name1 = name.toTermName diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 47c859bb5c..0e2c836860 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -12,8 +12,7 @@ import symtab.Flags._ * @author Martin Odersky * @version 1.0 */ -trait Unapplies extends ast.TreeDSL -{ +trait Unapplies extends ast.TreeDSL { self: Analyzer => import global._ @@ -21,7 +20,8 @@ trait Unapplies extends ast.TreeDSL import CODE.{ CASE => _, _ } import treeInfo.{ isRepeatedParamType, isByNameParamType } - private val unapplyParamName = nme.x_0 + private def unapplyParamName = nme.x_0 + private def caseMods = Modifiers(SYNTHETIC | CASE) // In the typeCompleter (templateSig) of a case class (resp it's module), // synthetic `copy` (reps `apply`, `unapply`) methods are added. To compute @@ -47,16 +47,10 @@ trait Unapplies extends ast.TreeDSL } /** returns unapply or unapplySeq if available */ - def unapplyMember(tp: Type): Symbol = (tp member nme.unapply) match { - case NoSymbol => tp member nme.unapplySeq - case unapp => unapp - } + def unapplyMember(tp: Type): Symbol = (tp member nme.unapply) orElse (tp member nme.unapplySeq) object ExtractorType { - def unapply(tp: Type): Option[Symbol] = { - val member = unapplyMember(tp) - if (member.exists) Some(member) else None - } + def unapply(tp: Type): Option[Symbol] = unapplyMember(tp).toOption } /** returns unapply member's parameter type. */ @@ -93,25 +87,19 @@ trait Unapplies extends ast.TreeDSL */ private def caseClassUnapplyReturnValue(param: Name, caseclazz: ClassDef) = { def caseFieldAccessorValue(selector: ValDef): Tree = { - val accessorName = selector.name - val privateLocalParamAccessor = caseclazz.impl.body.collectFirst { - case dd: ValOrDefDef if dd.name == accessorName && dd.mods.isPrivateLocal => dd.symbol - } - privateLocalParamAccessor match { - case None => - // Selecting by name seems to be the most straight forward way here to - // avoid forcing the symbol of the case class in order to list the accessors. - val maybeRenamedAccessorName = caseAccessorName(caseclazz.symbol, accessorName) - Ident(param) DOT maybeRenamedAccessorName - case Some(sym) => - // But, that gives a misleading error message in neg/t1422.scala, where a case - // class has an illegal private[this] parameter. We can detect this by checking - // the modifiers on the param accessors. - // - // We just generate a call to that param accessor here, which gives us an inaccessible - // symbol error, as before. - Ident(param) DOT sym + // Selecting by name seems to be the most straight forward way here to + // avoid forcing the symbol of the case class in order to list the accessors. + def selectByName = Ident(param) DOT caseAccessorName(caseclazz.symbol, selector.name) + // But, that gives a misleading error message in neg/t1422.scala, where a case + // class has an illegal private[this] parameter. We can detect this by checking + // the modifiers on the param accessors. + // We just generate a call to that param accessor here, which gives us an inaccessible + // symbol error, as before. + def localAccessor = caseclazz.impl.body find { + case t @ ValOrDefDef(mods, selector.name, _, _) => mods.isPrivateLocal + case _ => false } + localAccessor.fold(selectByName)(Ident(param) DOT _.symbol) } // Working with trees, rather than symbols, to avoid cycles like SI-5082 @@ -153,8 +141,6 @@ trait Unapplies extends ast.TreeDSL gen.mkTemplate(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus)) } - private val caseMods = Modifiers(SYNTHETIC | CASE) - /** The apply method corresponding to a case class */ def factoryMeth(mods: Modifiers, name: TermName, cdef: ClassDef): DefDef = { diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 02bee5e369..2d01840602 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -309,6 +309,14 @@ trait Trees extends api.Trees { self: SymbolTable => def rhs: Tree } + object ValOrDefDef { + def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)] = tree match { + case ValDef(mods, name, tpt, rhs) => Some((mods, name, tpt, rhs)) + case DefDef(mods, name, _, _, tpt, rhs) => Some((mods, name, tpt, rhs)) + case _ => None + } + } + case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi object ValDef extends ValDefExtractor |