aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2014-11-24 13:51:44 +0100
committerDmitry Petrashko <dark@d-d.me>2014-11-24 13:51:44 +0100
commit779afd2f65f967ec5af1ac5ec7464ad5851852ad (patch)
treeaf6d2ff5b81ee10e7a427ec7b36a2ac5639981a3 /src/dotty/tools/dotc/transform
parent33feb9dea9db0695f510654348455133707e0740 (diff)
parent859a7fe21d4e2b9a2f336bc38815b21367a2993b (diff)
downloaddotty-779afd2f65f967ec5af1ac5ec7464ad5851852ad.tar.gz
dotty-779afd2f65f967ec5af1ac5ec7464ad5851852ad.tar.bz2
dotty-779afd2f65f967ec5af1ac5ec7464ad5851852ad.zip
Merge pull request #213 from dotty-staging/javaparser
Javaparser & ElimRepeated fixes & Annotation-fixes
Diffstat (limited to 'src/dotty/tools/dotc/transform')
-rw-r--r--src/dotty/tools/dotc/transform/ElimRepeated.scala20
-rw-r--r--src/dotty/tools/dotc/transform/FirstTransform.scala21
-rw-r--r--src/dotty/tools/dotc/transform/GettersSetters.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Memoize.scala2
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala38
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala24
6 files changed, 84 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala
index 03fd28a26..ff56ae872 100644
--- a/src/dotty/tools/dotc/transform/ElimRepeated.scala
+++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala
@@ -4,13 +4,15 @@ package transform
import core._
import Names._
import Types._
-import TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
+import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
import ast.Trees.flatten
import Flags._
import Contexts.Context
import Symbols._
import Denotations._, SymDenotations._
import Decorators.StringInterpolators
+import dotty.tools.dotc.ast.tpd
+import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
import scala.collection.mutable
import DenotTransformers._
import Names.Name
@@ -20,7 +22,7 @@ import TypeUtils._
/** A transformer that removes repeated parameters (T*) from all types, replacing
* them with Seq types.
*/
-class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
+class ElimRepeated extends MiniPhaseTransform with InfoTransformer with AnnotationTransformer { thisTransformer =>
import ast.tpd._
override def phaseName = "elimRepeated"
@@ -34,9 +36,10 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
case tp @ MethodType(paramNames, paramTypes) =>
val resultType1 = elimRepeated(tp.resultType)
val paramTypes1 =
- if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam)
- paramTypes.init :+ paramTypes.last.underlyingIfRepeated(tp.isJava)
- else paramTypes
+ if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam) {
+ val last = paramTypes.last.underlyingIfRepeated(tp.isJava)
+ paramTypes.init :+ last
+ } else paramTypes
tp.derivedMethodType(paramNames, paramTypes1, resultType1)
case tp: PolyType =>
tp.derivedPolyType(tp.paramNames, tp.paramBounds, elimRepeated(tp.resultType))
@@ -54,19 +57,20 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
transformTypeOfTree(tree)
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
- transformTypeOfTree(tree)
+ transformTypeOfTree(tree) // should also transform the tree if argument needs adaptation
override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
transformTypeOfTree(tree)
/** If method overrides a Java varargs method, add a varargs bridge.
+ * Also transform trees inside method annotation
*/
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
+ addVarArgsBridge(tree)(ctx.withPhase(thisTransformer.next))
+ else
tree
}
diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala
index 7687be457..29cef09fe 100644
--- a/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -3,7 +3,7 @@ package transform
import core._
import Names._
-import TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
+import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
import ast.Trees._
import Flags._
import Types._
@@ -12,6 +12,8 @@ import Contexts.Context
import Symbols._
import SymDenotations._
import Decorators._
+import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
+import dotty.tools.dotc.core.Denotations.SingleDenotation
import scala.collection.mutable
import DenotTransformers._
import typer.Checking
@@ -26,12 +28,16 @@ import NameOps._
* - inserts `.package` for selections of package object members
* - checks the bounds of AppliedTypeTrees
* - stubs out native methods
+ * - removes java-defined ASTs
*/
-class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer { thisTransformer =>
+class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer with AnnotationTransformer { thisTransformer =>
import ast.tpd._
override def phaseName = "firstTransform"
+
+ def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = tp
+
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match {
case Select(qual, _) if tree.symbol.exists =>
assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe}")
@@ -79,16 +85,21 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer {
Thicket(stat :: newCompanion(stat.name.toTermName).trees)
case stat => stat
}
- addMissingCompanions(reorder(stats))
+
+ def skipJava(stats: List[Tree]): List[Tree] = // packages get a JavaDefined flag. Dont skip them
+ stats.filter(t => !(t.symbol is(Flags.JavaDefined, Flags.Package)))
+
+ addMissingCompanions(reorder(skipJava(stats)))
}
- override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) {
ddef.symbol.resetFlag(Deferred)
DefDef(ddef.symbol.asTerm,
_ => ref(defn.Sys_error).withPos(ddef.pos)
.appliedTo(Literal(Constant("native method stub"))))
} else ddef
+ }
override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] =
ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisTransformer.next)))
@@ -107,6 +118,8 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer {
case _ => normalizeType(tree)
}
+
+
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
normalizeType {
val qual = tree.qualifier
diff --git a/src/dotty/tools/dotc/transform/GettersSetters.scala b/src/dotty/tools/dotc/transform/GettersSetters.scala
index e1b4b59a0..bbe5740ff 100644
--- a/src/dotty/tools/dotc/transform/GettersSetters.scala
+++ b/src/dotty/tools/dotc/transform/GettersSetters.scala
@@ -102,7 +102,7 @@ import Decorators._
}
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree =
- if (tree.symbol.isSetter && !tree.symbol.is(Deferred | ParamAccessor)) {
+ if (tree.symbol.isSetter && !tree.symbol.is(Deferred | ParamAccessor | JavaDefined)) {
val Literal(Constant(())) = tree.rhs
assert(tree.symbol.field.exists, i"no field for ${tree.symbol.showLocated}")
val initializer = Assign(ref(tree.symbol.field), ref(tree.vparamss.head.head.symbol))
diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala
index ef70b9ecf..f4b00d6a5 100644
--- a/src/dotty/tools/dotc/transform/Memoize.scala
+++ b/src/dotty/tools/dotc/transform/Memoize.scala
@@ -82,5 +82,5 @@ import Decorators._
// neither getters nor setters
else tree
}
- private val NoFieldNeeded = Lazy | Deferred | ParamAccessor
+ private val NoFieldNeeded = Lazy | Deferred | ParamAccessor | JavaDefined
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index dd84cd53a..5c45f4fc5 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -67,19 +67,39 @@ class TreeChecker {
class Checker(phasesToCheck: Seq[Phase]) extends ReTyper {
- val definedSyms = new mutable.HashSet[Symbol]
+ val nowDefinedSyms = new mutable.HashSet[Symbol]
+ val everDefinedSyms = new mutable.HashMap[Symbol, Tree]
+
+ def withDefinedSym[T](tree: untpd.Tree)(op: => T)(implicit ctx: Context): T = tree match {
+ case tree: DefTree =>
+ val sym = tree.symbol
+ everDefinedSyms.get(sym) match {
+ case Some(t) =>
+ if(t ne tree)
+ ctx.warning(i"symbol ${sym.fullName} is defined at least twice in different parts of AST")
+ // should become an error
+ case None =>
+ everDefinedSyms(sym) = tree
+ }
+ assert(!nowDefinedSyms.contains(sym), i"doubly defined symbol: ${sym.fullName} in $tree")
+
+ if(ctx.settings.YcheckMods.value) {
+ tree match {
+ case t: MemberDef =>
+ if (t.name ne sym.name) ctx.warning(s"symbol ${sym.fullName} name doesn't correspond to AST: ${t}")
+ if (sym.flags != t.mods.flags) ctx.warning(s"symbol ${sym.fullName} flags ${sym.flags} doesn't match AST definition flags ${t.mods.flags}")
+ // todo: compare trees inside annotations
+ case _ =>
+ }
+ }
- def withDefinedSym[T](tree: untpd.Tree)(op: => T)(implicit ctx: Context): T = {
- if (tree.isDef) {
- assert(!definedSyms.contains(tree.symbol), i"doubly defined symbol: ${tree.symbol}in $tree")
- definedSyms += tree.symbol
+ nowDefinedSyms += tree.symbol
//println(i"defined: ${tree.symbol}")
val res = op
- definedSyms -= tree.symbol
+ nowDefinedSyms -= tree.symbol
//println(i"undefined: ${tree.symbol}")
res
- }
- else op
+ case _ => op
}
def withDefinedSyms[T](trees: List[untpd.Tree])(op: => T)(implicit ctx: Context) =
@@ -90,7 +110,7 @@ class TreeChecker {
def assertDefined(tree: untpd.Tree)(implicit ctx: Context) =
if (tree.symbol.maybeOwner.isTerm)
- assert(definedSyms contains tree.symbol, i"undefined symbol ${tree.symbol}")
+ assert(nowDefinedSyms contains tree.symbol, i"undefined symbol ${tree.symbol}")
override def typedUnadapted(tree: untpd.Tree, pt: Type)(implicit ctx: Context): tpd.Tree = {
val res = tree match {
diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala
index d3d8a183b..3869adf6c 100644
--- a/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -2,8 +2,12 @@ package dotty.tools.dotc
package transform
import dotty.tools.dotc.ast.tpd
+import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
import dotty.tools.dotc.core.Contexts.Context
+import dotty.tools.dotc.core.DenotTransformers.{InfoTransformer, DenotTransformer}
+import dotty.tools.dotc.core.Denotations.SingleDenotation
import dotty.tools.dotc.core.Phases.Phase
+import dotty.tools.dotc.core.SymDenotations.SymDenotation
import dotty.tools.dotc.core.Symbols.Symbol
import dotty.tools.dotc.core.Flags.PackageVal
import dotty.tools.dotc.typer.Mode
@@ -169,6 +173,26 @@ object TreeTransforms {
def phase = this
}
+ /** A helper trait to transform annotations on MemberDefs */
+ trait AnnotationTransformer extends MiniPhaseTransform with InfoTransformer {
+
+ val annotationTransformer = mkTreeTransformer
+
+ override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = {
+ val info1 = transformInfo(ref.info, ref.symbol)
+
+ ref match {
+ case ref: SymDenotation =>
+ val annotTrees = ref.annotations.map(_.tree)
+ val annotTrees1 = annotTrees.mapConserve(annotationTransformer.macroTransform)
+ val annots1 = if(annotTrees eq annotTrees1) ref.annotations else annotTrees1.map(new ConcreteAnnotation(_))
+ if ((info1 eq ref.info) && (annots1 eq ref.annotations)) ref
+ else ref.copySymDenotation(info = info1, annotations = annots1)
+ case _ => if (info1 eq ref.info) ref else ref.derivedSingleDenotation(ref.symbol, info1)
+ }
+ }
+ }
+
val NoTransform = new TreeTransform {
def phase = unsupported("phase")
idx = -1