Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/dotty/tools/backend/jvm/CollectEntryPoints.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,22 @@ class CollectEntryPoints extends MiniPhaseTransform {
}

object CollectEntryPoints{
def isJavaMainMethod(sym: Symbol)(implicit ctx: Context) = {
val d = ctx.definitions
val StringType = d.StringType

(sym.name == nme.main) && (sym.info match {
case r@MethodType(_, List(d.ArrayType(t))) =>
(t.widenDealias =:= StringType) && (
r.resultType.widenDealias =:= d.UnitType)
case _ => false
})
}

def isJavaEntyPoint(sym: Symbol)(implicit ctx: Context): Boolean = {
import Types.MethodType
val d = ctx.definitions
val StringType = d.StringType
def isJavaMainMethod(sym: Symbol) = (sym.name == nme.main) && (toDenot(sym).info match {
case r@ MethodType(_, List(d.ArrayType(StringType))) => r.resultType eq d.UnitType
case _ => false
})
// The given class has a main method.
def hasJavaMainMethod(sym: Symbol): Boolean =
(toDenot(sym).info member nme.main).alternatives exists(x => isJavaMainMethod(x.symbol))
Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/backend/jvm/DottyBackendInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
def isVarargsMethod: Boolean = sym is Flags.JavaVarargs
def isDeprecated: Boolean = false
def isMutable: Boolean = sym is Flags.Mutable
def hasAbstractFlag: Boolean = (sym is Flags.Abstract) || (sym is Flags.JavaInterface)
def hasAbstractFlag: Boolean =
(sym is Flags.Abstract) || (sym is Flags.JavaInterface) || (sym is Flags.Trait)
def hasModuleFlag: Boolean = sym is Flags.Module
def isSynchronized: Boolean = sym is Flags.Synchronized
def isNonBottomSubClass(other: Symbol): Boolean = sym.derivesFrom(other)
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class Compiler {
List(new LambdaLift,
new Flatten,
new RestoreScopes),
List(/*new PrivateToStatic,*/ new CollectEntryPoints, new LabelDefs, new ElimWildcardIdents),
List(/*new PrivateToStatic,*/ new CollectEntryPoints, new LabelDefs, new ElimWildcardIdents, new TraitConstructors),
List(new GenBCode)
)

Expand Down
6 changes: 3 additions & 3 deletions src/dotty/tools/dotc/transform/InterceptedMethods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
// this should be removed if we have guarantee that ## will get Apply node
override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (tree.symbol.isTerm && poundPoundMethods.contains(tree.symbol.asTerm)) {
val rewrite = PoundPoundValue(tree.qualifier)
val rewrite = poundPoundValue(tree.qualifier)
ctx.log(s"$phaseName rewrote $tree to $rewrite")
rewrite
}
else tree
}

private def PoundPoundValue(tree: Tree)(implicit ctx: Context) = {
private def poundPoundValue(tree: Tree)(implicit ctx: Context) = {
val s = tree.tpe.widen.typeSymbol
if (s == defn.NullClass) Literal(Constant(0))
else {
Expand Down Expand Up @@ -108,7 +108,7 @@ class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
val rewrite: Tree = tree.fun match {
case Select(qual, name) =>
if (poundPoundMethods contains tree.fun.symbol.asTerm) {
PoundPoundValue(qual)
poundPoundValue(qual)
} else if (Any_comparisons contains tree.fun.symbol.asTerm) {
if (tree.fun.symbol eq defn.Any_==) {
qual.select(defn.Any_equals).appliedToArgs(tree.args)
Expand Down
37 changes: 37 additions & 0 deletions src/dotty/tools/dotc/transform/TraitConstructors.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dotty.tools.dotc.transform

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.DenotTransformers.{SymTransformer, DenotTransformer}
import dotty.tools.dotc.core.Denotations.SingleDenotation
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.core.StdNames._
import dotty.tools.dotc.core.SymDenotations.SymDenotation
import dotty.tools.dotc.core._
import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}

/***
* Renames constructors in traits so that backend will call them with invokeInterface
* Also makes sure that renamed constructor bodies conforms to type of method
*/
class TraitConstructors extends MiniPhaseTransform with SymTransformer {
import dotty.tools.dotc.ast.tpd._
def phaseName: String = "traitConstructors"


override def treeTransformPhase: Phase = this.phase

def transformSym(sym: SymDenotation)(implicit ctx: Context): SymDenotation = {
if(sym.isPrimaryConstructor && (sym.owner is Flags.Trait))
sym.copySymDenotation(name = nme.INITIALIZER_PREFIX ++ sym.owner.fullName)
else sym
}

override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
val sym = tree.symbol
if (sym.isPrimaryConstructor && (sym.owner is Flags.Trait))
cpy.DefDef(tree)(rhs = Block(List(tree.rhs), This(tree.symbol.enclosingClass.asClass)))
else tree
}

}
24 changes: 12 additions & 12 deletions tests/pos/approximateUnion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ object approximateUnion {
trait B extends C[B] with D

val coin = true
val x = if (coin) new A else new B
val y = Some(if (coin) new A else new B)
val x = if (coin) new A{} else new B{}
val y = Some(if (coin) new A{} else new B{} )

val xtest: C[A | B] & D = x
val ytest: Some[C[A | B] & D] = y
Expand All @@ -22,8 +22,8 @@ object approximateUnion {
trait B extends C[X[B]] with D with E

val coin = true
val x = if (coin) new A else new B
val y = Some(if (coin) new A else new B)
val x = if (coin) new A{} else new B{}
val y = Some(if (coin) new A{} else new B{})

val xtest: C[X[A & B]] & D = x
val ytest: Some[C[X[A & B]] & D] = y
Expand All @@ -42,8 +42,8 @@ object approximateUnion2 {
trait B extends C[B] with D

val coin = true
val x = if (coin) new A else new B
val y = Some(if (coin) new A else new B)
val x = if (coin) new A{} else new B{}
val y = Some(if (coin) new A{} else new B{})

val xtest: C[_ >: A & B <: A | B] & D = x
val ytest: Some[C[_ >: A & B <: A | B] & D] = y
Expand All @@ -54,8 +54,8 @@ object approximateUnion2 {
trait B extends C[X[B]] with D with E

val coin = true
val x = if (coin) new A else new B
val y = Some(if (coin) new A else new B)
val x = if (coin) new A{} else new B{}
val y = Some(if (coin) new A{} else new B{})

val xtest: C[_ >: X[A | B] <: X[A & B]] & D = x
val ytest: Some[C[_ >: X[A | B] <: X[A & B]]] = y
Expand All @@ -74,8 +74,8 @@ object approximateUnion3 {
trait B extends C[B] with D

val coin = true
val x = if (coin) new A else new B
val y = Some(if (coin) new A else new B)
val x = if (coin) new A{} else new B{}
val y = Some(if (coin) new A{} else new B{})

val xtest: C[A & B] & D = x
val ytest: Some[C[A & B] & D] = y
Expand All @@ -86,8 +86,8 @@ object approximateUnion3 {
trait B extends C[X[B]] with D with E

val coin = true
val x = if (coin) new A else new B
val y = Some(if (coin) new A else new B)
val x = if (coin) new A{} else new B{}
val y = Some(if (coin) new A{} else new B{})

val xtest: C[X[A | B]] & D = x
val ytest2: Some[C[X[A | B]] & D] = y
Expand Down