diff options
author | Dmitry Petrashko <dark@d-d.me> | 2014-11-24 13:51:44 +0100 |
---|---|---|
committer | Dmitry Petrashko <dark@d-d.me> | 2014-11-24 13:51:44 +0100 |
commit | 779afd2f65f967ec5af1ac5ec7464ad5851852ad (patch) | |
tree | af6d2ff5b81ee10e7a427ec7b36a2ac5639981a3 /src/dotty/tools/dotc/transform | |
parent | 33feb9dea9db0695f510654348455133707e0740 (diff) | |
parent | 859a7fe21d4e2b9a2f336bc38815b21367a2993b (diff) | |
download | dotty-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.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/FirstTransform.scala | 21 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/GettersSetters.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Memoize.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 38 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeTransform.scala | 24 |
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 |