diff options
Diffstat (limited to 'compiler/src/dotty/tools/dotc/transform')
14 files changed, 73 insertions, 49 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala index 331fce46a..9f1e42e31 100644 --- a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala +++ b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala @@ -64,7 +64,7 @@ class CollectEntryPoints extends MiniPhaseTransform { val hasApproximate = possibles exists { m => m.info match { - case MethodType(_, p :: Nil) => + case MethodTpe(_, p :: Nil, _) => p.typeSymbol == defn.ArrayClass case _ => false } @@ -87,8 +87,8 @@ class CollectEntryPoints extends MiniPhaseTransform { m.symbol.info match { case t: PolyType => fail("main methods cannot be generic.") - case t@MethodType(paramNames, paramTypes) => - if (t.resultType :: paramTypes exists (_.typeSymbol.isAbstractType)) + case t: MethodType => + if (t.resultType :: t.paramTypes exists (_.typeSymbol.isAbstractType)) fail("main methods cannot refer to type parameters or abstract types.", m.symbol.pos) else javaPlatform.isJavaMainMethod(m.symbol) || fail("main method must have exact signature (Array[String])Unit", m.symbol.pos) diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala index 0e187fc2e..59da78590 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala @@ -92,8 +92,8 @@ class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransform arg } - val MethodType(_, formals) = tree.fun.tpe.widen - val args1 = tree.args.zipWithConserve(formals)(transformArg) + val mt @ MethodType(_) = tree.fun.tpe.widen + val args1 = tree.args.zipWithConserve(mt.paramTypes)(transformArg) cpy.Apply(tree)(tree.fun, args1) } diff --git a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala index 258b7f234..ae3259509 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -32,11 +32,24 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = elimRepeated(tp) + + override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = + super.transform(ref) match { + case ref1: SymDenotation if (ref1 ne ref) && overridesJava(ref1.symbol) => + // This method won't override the corresponding Java method at the end of this phase, + // only the bridge added by `addVarArgsBridge` will. + ref1.copySymDenotation(initFlags = ref1.flags &~ Override) + case ref1 => + ref1 + } + override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym is Method + private def overridesJava(sym: Symbol)(implicit ctx: Context) = sym.allOverriddenSymbols.exists(_ is JavaDefined) + private def elimRepeated(tp: Type)(implicit ctx: Context): Type = tp.stripTypeVar match { - case tp @ MethodType(paramNames, paramTypes) => - val resultType1 = elimRepeated(tp.resultType) + case tp @ MethodTpe(paramNames, paramTypes, resultType) => + val resultType1 = elimRepeated(resultType) val paramTypes1 = if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam) { val last = paramTypes.last.underlyingIfRepeated(tp.isJava) @@ -93,10 +106,9 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati */ override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = { assert(ctx.phase == thisTransformer) - def overridesJava = tree.symbol.allOverriddenSymbols.exists(_ is JavaDefined) - if (tree.symbol.info.isVarArgsMethod && overridesJava) - addVarArgsBridge(tree)(ctx.withPhase(thisTransformer.next)) - else + if (tree.symbol.info.isVarArgsMethod && overridesJava(tree.symbol)) + addVarArgsBridge(tree) + else tree } @@ -120,6 +132,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati .appliedToArgs(vrefs :+ TreeGen.wrapArray(varArgRef, elemtp)) .appliedToArgss(vrefss1) }) + Thicket(ddef, bridgeDef) } diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala index 3857b405f..f9c7a8e1e 100644 --- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala +++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala @@ -40,8 +40,8 @@ class Erasure extends Phase with DenotTransformer { thisTransformer => def isCompacted(sym: Symbol) = sym.isAnonymousFunction && { sym.info(ctx.withPhase(ctx.phase.next)) match { - case MethodType(nme.ALLARGS :: Nil, _) => true - case _ => false + case MethodType(nme.ALLARGS :: Nil) => true + case _ => false } } @@ -269,7 +269,7 @@ object Erasure extends TypeTestsCasts{ def adaptToType(tree: Tree, pt: Type)(implicit ctx: Context): Tree = if (pt.isInstanceOf[FunProto]) tree else tree.tpe.widen match { - case MethodType(Nil, _) if tree.isTerm => + case MethodType(Nil) if tree.isTerm => adaptToType(tree.appliedToNone, pt) case tpw => if (pt.isInstanceOf[ProtoType] || tree.tpe <:< pt) @@ -697,9 +697,10 @@ object Erasure extends TypeTestsCasts{ val rhs = paramss.foldLeft(sel)((fun, vparams) => fun.tpe.widen match { - case MethodType(names, types) => Apply(fun, (vparams, types).zipped.map(adapt(_, _, untpd.EmptyTree))) - case a => error(s"can not resolve apply type $a") - + case mt: MethodType => + Apply(fun, (vparams, mt.paramTypes).zipped.map(adapt(_, _, untpd.EmptyTree))) + case a => + error(s"can not resolve apply type $a") }) adapt(rhs, resultType) }) diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala index 91399f91a..7b15b7e54 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala @@ -53,7 +53,7 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer => val applyRhs: Tree = applyDef.rhs val applyFn = applyDef.symbol.asTerm - val MethodType(paramNames, paramTypes) = applyFn.info + val MethodTpe(paramNames, paramTypes, _) = applyFn.info val isDefinedAtFn = applyFn.copy( name = nme.isDefinedAt, flags = Synthetic | Method, diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala index d75c32fcc..f17808e62 100644 --- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -16,7 +16,9 @@ import SymUtils._ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Phases.Phase import util.Property + import collection.mutable +import scala.annotation.tailrec /** This phase adds outer accessors to classes and traits that need them. * Compared to Scala 2.x, it tries to minimize the set of classes @@ -328,9 +330,9 @@ object ExplicitOuter { /** If `cls` has an outer parameter add one to the method type `tp`. */ def addParam(cls: ClassSymbol, tp: Type): Type = if (hasOuterParam(cls)) { - val mt @ MethodType(pnames, ptypes) = tp + val mt @ MethodTpe(pnames, ptypes, restpe) = tp mt.derivedMethodType( - nme.OUTER :: pnames, cls.owner.enclosingClass.typeRef :: ptypes, mt.resultType) + nme.OUTER :: pnames, cls.owner.enclosingClass.typeRef :: ptypes, restpe) } else tp /** If function in an apply node is a constructor that needs to be passed an @@ -367,7 +369,7 @@ object ExplicitOuter { def path(start: Tree = This(ctx.owner.lexicallyEnclosingClass.asClass), toCls: Symbol = NoSymbol, count: Int = -1): Tree = try { - def loop(tree: Tree, count: Int): Tree = { + @tailrec def loop(tree: Tree, count: Int): Tree = { val treeCls = tree.tpe.widen.classSymbol val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore ctx.log(i"outer to $toCls of $tree: ${tree.tpe}, looking for ${outerAccName(treeCls.asClass)(outerAccessorCtx)} in $treeCls") @@ -389,7 +391,7 @@ object ExplicitOuter { /** The outer parameter definition of a constructor if it needs one */ def paramDefs(constr: Symbol): List[ValDef] = if (constr.isConstructor && hasOuterParam(constr.owner.asClass)) { - val MethodType(outerName :: _, outerType :: _) = constr.info + val MethodTpe(outerName :: _, outerType :: _, _) = constr.info val outerSym = ctx.newSymbol(constr, outerName, Param, outerType) ValDef(outerSym) :: Nil } diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala index 597146514..8328e43de 100644 --- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -29,8 +29,11 @@ import StdNames._ * - eliminates some kinds of trees: Imports, NamedArgs * - stubs out native methods * - eliminates self tree in Template and self symbol in ClassInfo - * - collapsess all type trees to trees of class TypeTree + * - collapses all type trees to trees of class TypeTree * - converts idempotent expressions with constant types + * - drops branches of ifs using the rules + * if (true) A else B --> A + * if (false) A else B --> B */ class FirstTransform extends MiniPhaseTransform with InfoTransformer with AnnotationTransformer { thisTransformer => import ast.tpd._ @@ -148,7 +151,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo): Tree = { cpy.Template(impl)(self = EmptyValDef) } - + override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = { if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) { ddef.symbol.resetFlag(Deferred) @@ -168,13 +171,13 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota } override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = - if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) + if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else constToLiteral(tree) override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = - if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) + if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else constToLiteral(tree) - + override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo) = constToLiteral(tree) @@ -183,10 +186,16 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota override def transformTyped(tree: Typed)(implicit ctx: Context, info: TransformerInfo) = constToLiteral(tree) - + override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo) = constToLiteral(tree) + override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo) = + tree.cond match { + case Literal(Constant(c: Boolean)) => if (c) tree.thenp else tree.elsep + case _ => tree + } + // invariants: all modules have companion objects // all types are TypeTrees // all this types are explicit diff --git a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala index 9e43fc999..0cb453b4c 100644 --- a/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala +++ b/compiler/src/dotty/tools/dotc/transform/FullParameterization.scala @@ -12,8 +12,6 @@ import NameOps._ import ast._ import ast.Trees._ -import scala.reflect.internal.util.Collections - /** Provides methods to produce fully parameterized versions of instance methods, * where the `this` of the enclosing class is abstracted out in an extra leading * `$this` parameter and type parameters of the class become additional type @@ -107,8 +105,9 @@ trait FullParameterization { def resultType(mapClassParams: Type => Type) = { val thisParamType = mapClassParams(clazz.classInfo.selfType) val firstArgType = if (liftThisType) thisParamType & clazz.thisType else thisParamType - MethodType(nme.SELF :: Nil, firstArgType :: Nil)(mt => - mapClassParams(origResult).substThisUnlessStatic(clazz, MethodParam(mt, 0))) + MethodType(nme.SELF :: Nil)( + mt => firstArgType :: Nil, + mt => mapClassParams(origResult).substThisUnlessStatic(clazz, MethodParam(mt, 0))) } /** Replace class type parameters by the added type parameters of the polytype `pt` */ @@ -234,8 +233,8 @@ trait FullParameterization { fun.appliedToArgss(originalDef.vparamss.nestedMap(vparam => ref(vparam.symbol))) else { // this type could have changed on forwarding. Need to insert a cast. - val args = Collections.map2(originalDef.vparamss, fun.tpe.paramTypess)((vparams, paramTypes) => - Collections.map2(vparams, paramTypes)((vparam, paramType) => { + val args = (originalDef.vparamss, fun.tpe.paramTypess).zipped.map((vparams, paramTypes) => + (vparams, paramTypes).zipped.map((vparam, paramType) => { assert(vparam.tpe <:< paramType.widen) // type should still conform to widened type ref(vparam.symbol).ensureConforms(paramType) }) @@ -254,10 +253,10 @@ object FullParameterization { def memberSignature(info: Type)(implicit ctx: Context): Signature = info match { case info: PolyType => memberSignature(info.resultType) - case info @ MethodType(nme.SELF :: Nil, _) => - info.resultType.ensureMethodic.signature - case info @ MethodType(nme.SELF :: otherNames, thisType :: otherTypes) => - info.derivedMethodType(otherNames, otherTypes, info.resultType).signature + case MethodTpe(nme.SELF :: Nil, _, restpe) => + restpe.ensureMethodic.signature + case info @ MethodTpe(nme.SELF :: otherNames, thisType :: otherTypes, restpe) => + info.derivedMethodType(otherNames, otherTypes, restpe).signature case _ => Signature.NotAMethod } diff --git a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala index b603a53dc..7578b57f1 100644 --- a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -352,12 +352,12 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform } private def liftedInfo(local: Symbol)(implicit ctx: Context): Type = local.info match { - case mt @ MethodType(pnames, ptypes) => + case MethodTpe(pnames, ptypes, restpe) => val ps = proxies(local) MethodType( ps.map(_.name.asTermName) ++ pnames, ps.map(_.info) ++ ptypes, - mt.resultType) + restpe) case info => info } diff --git a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala index a6ac71286..2035fb04b 100644 --- a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala +++ b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala @@ -139,7 +139,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer { val holderSymbol = ctx.newSymbol(x.symbol.owner, holderName, containerFlags, holderImpl.typeRef, coord = x.pos) val initSymbol = ctx.newSymbol(x.symbol.owner, initName, initFlags, MethodType(Nil, tpe), coord = x.pos) - val result = ref(holderSymbol).select(lazyNme.value) + val result = ref(holderSymbol).select(lazyNme.value).withPos(x.pos) val flag = ref(holderSymbol).select(lazyNme.initialized) val initer = valueInitter.changeOwnerAfter(x.symbol, initSymbol, this) val initBody = diff --git a/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala b/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala index a72e10681..859ac8b06 100644 --- a/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala +++ b/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala @@ -27,7 +27,7 @@ class ParamForwarding(thisTransformer: DenotTransformer) { val (superArgs, superParamNames) = impl.parents match { case superCall @ Apply(fn, args) :: _ => fn.tpe.widen match { - case MethodType(paramNames, _) => (args, paramNames) + case MethodType(paramNames) => (args, paramNames) case _ => (Nil, Nil) } case _ => (Nil, Nil) diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 7c49e68dd..7576ccc05 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -30,8 +30,6 @@ import dotty.tools.dotc.util.Positions.Position import dotty.tools.dotc.core.Decorators._ import dotty.tools.dotc.core.Flags -import scala.reflect.internal.util.Collections - /** This transform eliminates patterns. Right now it's a dummy. * Awaiting the real pattern matcher. * elimRepeated is required @@ -166,7 +164,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer { } def emitValDefs: List[ValDef] = { - Collections.map2(lhs, rhs)((symbol, tree) => ValDef(symbol.asTerm, tree.ensureConforms(symbol.info))) + (lhs, rhs).zipped.map((symbol, tree) => ValDef(symbol.asTerm, tree.ensureConforms(symbol.info))) } } object NoRebindings extends Rebindings(Nil, Nil) @@ -609,7 +607,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer { // only store binders actually used val (subPatBindersStored, subPatRefsStored) = stored.filter{case (b, _) => usedBinders(b)}.unzip - Block(Collections.map2(subPatBindersStored.toList, subPatRefsStored.toList)((bind, ref) => { + Block((subPatBindersStored.toList, subPatRefsStored.toList).zipped.map((bind, ref) => { // required in case original pattern had a more precise type // eg case s@"foo" => would be otherwise translated to s with type String instead of String("foo") def refTpeWiden = ref.tpe.widen diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala index 05305575e..105f54d3a 100644 --- a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala +++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala @@ -12,7 +12,9 @@ import StdNames._ import NameOps._ import Flags._ import Annotations._ + import language.implicitConversions +import scala.annotation.tailrec object SymUtils { implicit def decorateSymbol(sym: Symbol): SymUtils = new SymUtils(sym) @@ -59,14 +61,14 @@ class SymUtils(val self: Symbol) extends AnyVal { } /** The closest enclosing method or class of this symbol */ - final def enclosingMethodOrClass(implicit ctx: Context): Symbol = + @tailrec final def enclosingMethodOrClass(implicit ctx: Context): Symbol = if (self.is(Method, butNot = Label) || self.isClass) self else if (self.exists) self.owner.enclosingMethodOrClass else NoSymbol /** Apply symbol/symbol substitution to this symbol */ def subst(from: List[Symbol], to: List[Symbol]): Symbol = { - def loop(from: List[Symbol], to: List[Symbol]): Symbol = + @tailrec def loop(from: List[Symbol], to: List[Symbol]): Symbol = if (from.isEmpty) self else if (self eq from.head) to.head else loop(from.tail, to.tail) diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index 7a4af647f..51e2469b2 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -446,7 +446,7 @@ class TreeChecker extends Phase with SymTransformer { super.typedStats(trees, exprOwner) } - override def ensureNoLocalRefs(tree: Tree, pt: Type, localSyms: => List[Symbol], forcedDefined: Boolean = false)(implicit ctx: Context): Tree = + override def ensureNoLocalRefs(tree: Tree, pt: Type, localSyms: => List[Symbol])(implicit ctx: Context): Tree = tree override def adapt(tree: Tree, pt: Type, original: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context) = { |