diff options
Diffstat (limited to 'src/reflect/scala/reflect/internal/TreeGen.scala')
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeGen.scala | 73 |
1 files changed, 61 insertions, 12 deletions
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index 201b727ed6..ade9ee84ac 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -117,6 +117,30 @@ abstract class TreeGen { case _ => qual } + + + // val selType = testedBinder.info + // + // // See the test for SI-7214 for motivation for dealias. Later `treeCondStrategy#outerTest` + // // generates an outer test based on `patType.prefix` with automatically dealiases. + // // Prefixes can have all kinds of shapes SI-9110 + // val patPre = expectedTp.dealiasWiden.prefix + // val selPre = selType.dealiasWiden.prefix + // + // // Optimization: which prefixes can we disqualify from the need for an outer reference check? + // // - classes in static owners do not get outer pointers + // // - if the prefixes are statically known to be equal, the type system ensures an outer test is redundant + // !((patPre eq NoPrefix) || (selPre eq NoPrefix) + // || patPre.typeSymbol.isPackageClass + // || selPre =:= patPre) + + def mkAttributedQualifierIfPossible(prefix: Type): Option[Tree] = prefix match { + case NoType | NoPrefix | ErrorType => None + case TypeRef(_, sym, _) if sym.isModule || sym.isClass || sym.isType => None + case pre => Some(mkAttributedQualifier(prefix)) + } + + /** Builds a reference to given symbol with given stable prefix. */ def mkAttributedRef(pre: Type, sym: Symbol): RefTree = { val qual = mkAttributedQualifier(pre) @@ -129,7 +153,16 @@ abstract class TreeGen { /** Builds a reference to given symbol. */ def mkAttributedRef(sym: Symbol): RefTree = - if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym) + if (sym.owner.isStaticOwner) { + if (sym.owner.isRoot) + mkAttributedIdent(sym) + else { + val ownerModule = sym.owner.sourceModule + assert(ownerModule != NoSymbol, sym.owner) + mkAttributedSelect(mkAttributedRef(sym.owner.sourceModule), sym) + } + } + else if (sym.owner.isClass) mkAttributedRef(sym.owner.thisType, sym) else mkAttributedIdent(sym) def mkUnattributedRef(sym: Symbol): RefTree = mkUnattributedRef(sym.fullNameAsName('.')) @@ -191,8 +224,8 @@ abstract class TreeGen { ) val pkgQualifier = if (needsPackageQualifier) { - val packageObject = rootMirror.getPackageObjectWithMember(qual.tpe, sym) - Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject) + val packageObject = qualsym.packageObject + Select(qual, nme.PACKAGE) setSymbol packageObject setType packageObject.typeOfThis } else qual @@ -277,13 +310,16 @@ abstract class TreeGen { /** Builds a tuple */ def mkTuple(elems: List[Tree], flattenUnary: Boolean = true): Tree = elems match { case Nil => - Literal(Constant(())) + mkLiteralUnit case tree :: Nil if flattenUnary => tree case _ => Apply(scalaDot(TupleClass(elems.length).name.toTermName), elems) } + def mkLiteralUnit: Literal = Literal(Constant(())) + def mkUnitBlock(expr: Tree): Block = Block(List(expr), mkLiteralUnit) + def mkTupleType(elems: List[Tree], flattenUnary: Boolean = true): Tree = elems match { case Nil => scalaDot(tpnme.Unit) @@ -362,7 +398,7 @@ abstract class TreeGen { if (body forall treeInfo.isInterfaceMember) None else Some( atPos(wrappingPos(superPos, lvdefs)) ( - DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, Literal(Constant(())))))) + DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(lvdefs, mkLiteralUnit)))) } else { // convert (implicit ... ) to ()(implicit ... ) if it's the only parameter section @@ -376,7 +412,7 @@ abstract class TreeGen { // therefore here we emit a dummy which gets populated when the template is named and typechecked Some( atPos(wrappingPos(superPos, lvdefs ::: vparamss1.flatten).makeTransparent) ( - DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant(())))))) + DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), mkLiteralUnit)))) } } constr foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus = false)) @@ -448,7 +484,7 @@ abstract class TreeGen { * written by end user. It's important to distinguish the two so that * quasiquotes can strip synthetic ones away. */ - def mkSyntheticUnit() = Literal(Constant(())).updateAttachment(SyntheticUnitAttachment) + def mkSyntheticUnit() = mkLiteralUnit.updateAttachment(SyntheticUnitAttachment) /** Create block of statements `stats` */ def mkBlock(stats: List[Tree], doFlatten: Boolean = true): Tree = @@ -761,7 +797,7 @@ abstract class TreeGen { /** Create tree for for-comprehension generator <val pat0 <- rhs0> */ def mkGenerator(pos: Position, pat: Tree, valeq: Boolean, rhs: Tree)(implicit fresh: FreshNameCreator): Tree = { - val pat1 = patvarTransformer.transform(pat) + val pat1 = patvarTransformerForFor.transform(pat) if (valeq) ValEq(pat1, rhs).setPos(pos) else ValFrom(pat1, mkCheckIfRefutable(pat1, rhs)).setPos(pos) } @@ -858,11 +894,15 @@ abstract class TreeGen { * x becomes x @ _ * x: T becomes x @ (_: T) */ - object patvarTransformer extends Transformer { + class PatvarTransformer(forFor: Boolean) extends Transformer { override def transform(tree: Tree): Tree = tree match { - case Ident(name) if (treeInfo.isVarPattern(tree) && name != nme.WILDCARD) => - atPos(tree.pos)(Bind(name, atPos(tree.pos.focus) (Ident(nme.WILDCARD)))) - case Typed(id @ Ident(name), tpt) if (treeInfo.isVarPattern(id) && name != nme.WILDCARD) => + case Ident(name) if treeInfo.isVarPattern(tree) && name != nme.WILDCARD => + atPos(tree.pos) { + val b = Bind(name, atPos(tree.pos.focus) (Ident(nme.WILDCARD))) + if (!forFor && isPatVarWarnable) b + else b updateAttachment AtBoundIdentifierAttachment + } + case Typed(id @ Ident(name), tpt) if treeInfo.isVarPattern(id) && name != nme.WILDCARD => atPos(tree.pos.withPoint(id.pos.point)) { Bind(name, atPos(tree.pos.withStart(tree.pos.point)) { Typed(Ident(nme.WILDCARD), tpt) @@ -883,6 +923,15 @@ abstract class TreeGen { } } + /** Can be overridden to depend on settings.warnUnusedPatvars. */ + def isPatVarWarnable: Boolean = true + + /** Not in for comprehensions, whether to warn unused pat vars depends on flag. */ + object patvarTransformer extends PatvarTransformer(forFor = false) + + /** Tag pat vars in for comprehensions. */ + object patvarTransformerForFor extends PatvarTransformer(forFor = true) + // annotate the expression with @unchecked def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) { // This can't be "Annotated(New(UncheckedClass), expr)" because annotations |