aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-05-22 18:02:24 +0200
committerMartin Odersky <odersky@gmail.com>2013-05-22 18:30:23 +0200
commitfd079d2f3335db7b54b0f78a4d884d9948a7beea (patch)
treecee19b71a9a077880e8d7ab1738891f55ce5bd85 /src/dotty/tools
parent0ebdcc7ed2d2024d93ba7d24b88187d4c502eb4b (diff)
downloaddotty-fd079d2f3335db7b54b0f78a4d884d9948a7beea.tar.gz
dotty-fd079d2f3335db7b54b0f78a4d884d9948a7beea.tar.bz2
dotty-fd079d2f3335db7b54b0f78a4d884d9948a7beea.zip
More tree refactorings.
1) Getting rid of ugen in favor of untpd. 2) Eliminating some unused methods 3) Splitting out CheckTrees from TypedTrees. 4) Moving trees and related classes into separate package dotc.ast
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/ast/CheckTrees.scala243
-rw-r--r--src/dotty/tools/dotc/ast/PluggableTransformers.scala (renamed from src/dotty/tools/dotc/core/PluggableTransformers.scala)2
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala (renamed from src/dotty/tools/dotc/core/TreeInfo.scala)3
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala (renamed from src/dotty/tools/dotc/core/Trees.scala)3
-rw-r--r--src/dotty/tools/dotc/ast/TypedTrees.scala (renamed from src/dotty/tools/dotc/core/TypedTrees.scala)243
-rw-r--r--src/dotty/tools/dotc/ast/UntypedTrees.scala487
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala2
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala8
-rw-r--r--src/dotty/tools/dotc/core/TypeComparers.scala3
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
-rw-r--r--src/dotty/tools/dotc/core/UntypedTrees.scala501
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala2
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala3
-rw-r--r--src/dotty/tools/dotc/parsing/MarkupParsers.scala5
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala31
-rw-r--r--src/dotty/tools/dotc/parsing/ScriptParsers.scala5
-rw-r--r--src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala2
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala4
-rw-r--r--src/dotty/tools/dotc/printing/Printer.scala2
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala5
21 files changed, 781 insertions, 779 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala
new file mode 100644
index 000000000..f62eb1921
--- /dev/null
+++ b/src/dotty/tools/dotc/ast/CheckTrees.scala
@@ -0,0 +1,243 @@
+package dotty.tools
+package dotc
+package ast
+
+import core._
+import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
+import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
+import TypedTrees.{tpd, TreeOps, localSyms}
+
+object CheckTrees {
+
+ def check(p: Boolean, msg: => String = "")(implicit ctx: Context): Unit = assert(p, msg)
+
+ def checkTypeArg(arg: tpd.Tree, bounds: TypeBounds)(implicit ctx: Context): Unit = {
+ check(arg.isValueType)
+ check(bounds contains arg.tpe)
+ }
+
+ def checkType(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match {
+ case Ident(name) =>
+ case Select(qualifier, name) =>
+ check(qualifier.isValue)
+ check(qualifier.tpe =:= tree.tpe.normalizedPrefix)
+ val denot = qualifier.tpe.member(name)
+ check(denot.exists)
+ check(denot.hasAltWith(_.symbol == tree.symbol))
+ case This(cls) =>
+ case Super(qual, mixin) =>
+ check(qual.isValue)
+ val cls = qual.tpe.typeSymbol
+ check(cls.isClass)
+ case Apply(fn, args) =>
+ def checkArg(arg: tpd.Tree, name: Name, formal: Type): Unit = {
+ arg match {
+ case NamedArg(argName, _) =>
+ check(argName == name)
+ case SeqLiteral(_, _) =>
+ check(defn.RepeatedParamClasses contains formal.typeSymbol)
+ case _ =>
+ check(arg.isValue)
+ }
+ check(arg.tpe <:< formal)
+ }
+ val MethodType(paramNames, paramTypes) = fn.tpe.widen // checked already at construction
+ (args, paramNames, paramTypes).zipped foreach checkArg
+ case TypeApply(fn, args) =>
+ val pt @ PolyType(_) = fn.tpe.widen // checked already at construction
+ (args, pt.instantiateBounds(args map (_.tpe))).zipped foreach checkTypeArg
+ case Literal(const: Constant) =>
+ case New(tpt) =>
+ check(tpt.isValueType)
+ val cls = tpt.tpe.typeSymbol
+ check(cls.isClass)
+ check(!(cls is AbstractOrTrait))
+ case Pair(left, right) =>
+ check(left.isValue)
+ check(right.isValue)
+ case Typed(expr, tpt) =>
+ check(tpt.isValueType)
+ expr.tpe.widen match {
+ case tp: MethodType =>
+ val cls = tpt.tpe.typeSymbol
+ check(cls.isClass)
+ check((cls is Trait) ||
+ cls.primaryConstructor.info.paramTypess.flatten.isEmpty)
+ val absMembers = tpt.tpe.abstractTermMembers
+ check(absMembers.size == 1)
+ check(tp <:< absMembers.head.info)
+ case _ =>
+ check(expr.isValueOrPattern)
+ check(expr.tpe <:< tpt.tpe)
+ }
+ case NamedArg(name, arg) =>
+ case Assign(lhs, rhs) =>
+ check(lhs.isValue); check(rhs.isValue)
+ lhs.tpe match {
+ case ltpe: TermRef =>
+ check(ltpe.symbol is Mutable)
+ case _ =>
+ check(false)
+ }
+ check(rhs.tpe <:< lhs.tpe.widen)
+ case Block(stats, expr) =>
+ var hoisted: Set[Symbol] = Set()
+ lazy val locals = localSyms(stats).toSet
+ check(expr.isValue)
+ def isNonLocal(sym: Symbol): Boolean =
+ !(locals contains sym) || isHoistableClass(sym)
+ def isHoistableClass(sym: Symbol) =
+ sym.isClass && {
+ (hoisted contains sym) || {
+ hoisted += sym
+ noLeaksInClass(sym.asClass)
+ }
+ }
+ def noLeaksIn(tp: Type): Boolean = tp forallParts {
+ case tp: NamedType => isNonLocal(tp.symbol)
+ case _ => true
+ }
+ def noLeaksInClass(sym: ClassSymbol): Boolean =
+ (sym.info.parents forall noLeaksIn) &&
+ (sym.decls.toList forall (t => noLeaksIn(t.info)))
+ check(noLeaksIn(tree.tpe))
+ case If(cond, thenp, elsep) =>
+ check(cond.isValue); check(thenp.isValue); check(elsep.isValue)
+ check(cond.tpe.derivesFrom(defn.BooleanClass))
+ case Match(selector, cases) =>
+ check(selector.isValue)
+ // are any checks that relate selector and patterns desirable?
+ case CaseDef(pat, guard, body) =>
+ check(pat.isValueOrPattern); check(guard.isValue); check(body.isValue)
+ check(guard.tpe.derivesFrom(defn.BooleanClass))
+ case Return(expr, from) =>
+ check(expr.isValue); check(from.isTerm)
+ check(from.tpe.termSymbol.isSourceMethod)
+ case Try(block, handler, finalizer) =>
+ check(block.isTerm)
+ check(finalizer.isTerm)
+ check(handler.isTerm)
+ check(handler.tpe derivesFrom defn.FunctionClass(1))
+ check(handler.tpe.baseType(defn.FunctionClass(1)).typeArgs.head <:< defn.ThrowableType)
+ case Throw(expr) =>
+ check(expr.isValue)
+ check(expr.tpe.derivesFrom(defn.ThrowableClass))
+ case SeqLiteral(elemtpt, elems) =>
+ check(elemtpt.isValueType);
+ for (elem <- elems) {
+ check(elem.isValue)
+ check(elem.tpe <:< elemtpt.tpe)
+ }
+ case TypeTree(original) =>
+ if (!original.isEmpty) {
+ check(original.isValueType)
+ check(original.tpe == tree.tpe)
+ }
+ case SingletonTypeTree(ref) =>
+ check(ref.isValue)
+ check(ref.symbol.isStable)
+ case SelectFromTypeTree(qualifier, name) =>
+ check(qualifier.isValueType)
+ check(qualifier.tpe =:= tree.tpe.normalizedPrefix)
+ val denot = qualifier.tpe.member(name)
+ check(denot.exists)
+ check(denot.symbol == tree.symbol)
+ case AndTypeTree(left, right) =>
+ check(left.isValueType); check(right.isValueType)
+ case OrTypeTree(left, right) =>
+ check(left.isValueType); check(right.isValueType)
+ case RefinedTypeTree(tpt, refinements) =>
+ check(tpt.isValueType)
+ def checkRefinements(forbidden: Set[Symbol], rs: List[tpd.Tree]): Unit = rs match {
+ case r :: rs1 =>
+ val rsym = r.symbol
+ check(rsym.isTerm || rsym.isAbstractOrAliasType)
+ if (rsym.isAbstractType) check(tpt.tpe.member(rsym.name).exists)
+ check(rsym.info forallParts {
+ case nt: NamedType => !(forbidden contains nt.symbol)
+ case _ => true
+ })
+ checkRefinements(forbidden - rsym, rs1)
+ case nil =>
+ }
+ checkRefinements(localSyms(refinements).toSet, refinements)
+ case AppliedTypeTree(tpt, args) =>
+ check(tpt.isValueType)
+ val tparams = tpt.tpe.typeParams
+ check(sameLength(tparams, args))
+ (args, tparams map (_.info.bounds)).zipped foreach checkTypeArg
+ case TypeBoundsTree(lo, hi) =>
+ check(lo.isValueType); check(hi.isValueType)
+ check(lo.tpe <:< hi.tpe)
+ case Bind(sym, body) =>
+ check(body.isValueOrPattern)
+ check(!(tree.symbol is Method))
+ body match {
+ case Ident(nme.WILDCARD) =>
+ case _ => check(body.tpe.widen =:= tree.symbol.info)
+ }
+ case Alternative(alts) =>
+ for (alt <- alts) check(alt.isValueOrPattern)
+ case UnApply(fun, args) =>
+ check(fun.isTerm)
+ for (arg <- args) check(arg.isValueOrPattern)
+ val funtpe @ MethodType(_, _) = fun.tpe.widen
+ fun.symbol.name match { // check arg arity
+ case nme.unapplySeq =>
+ // args need to be wrapped in (...: _*)
+ check(args.length == 1)
+ check(args.head.tpe.typeSymbol == defn.RepeatedParamClass)
+ case nme.unapply =>
+ val rtp = funtpe.resultType
+ val rsym = rtp.dealias.typeSymbol
+ if (rsym == defn.BooleanClass)
+ check(args.isEmpty)
+ else {
+ check(rsym == defn.OptionClass)
+ val normArgs = rtp.typeArgs match {
+ case optionArg :: Nil =>
+ optionArg.typeArgs match {
+ case Nil =>
+ optionArg :: Nil
+ case tupleArgs if defn.TupleClasses contains optionArg.dealias.typeSymbol =>
+ tupleArgs
+ }
+ case _ =>
+ check(false)
+ Nil
+ }
+ check(sameLength(normArgs, args))
+ }
+ }
+ case ValDef(mods, name, tpt, rhs) =>
+ check(!(tree.symbol is Method))
+ if (!rhs.isEmpty) {
+ check(rhs.isValue)
+ check(rhs.tpe <:< tpt.tpe)
+ }
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ check(tree.symbol is Method)
+ if (!rhs.isEmpty) {
+ check(rhs.isValue)
+ check(rhs.tpe <:< tpt.tpe)
+ }
+ case TypeDef(mods, name, _, tpt) =>
+ check(tpt.tpe.isInstanceOf[TypeBounds])
+ case Template(constr, parents, selfType, body) =>
+ case ClassDef(mods, name, tparams, impl) =>
+ case Import(expr, selectors) =>
+ check(expr.isValue)
+ check(expr.tpe.termSymbol.isStable)
+ case PackageDef(pid, stats) =>
+ check(pid.isTerm)
+ check(pid.symbol is Package)
+ case Annotated(annot, arg) =>
+ check(annot.isInstantiation)
+ check(annot.symbol.owner.isSubClass(defn.AnnotationClass))
+ check(arg.isValueType || arg.isValue)
+ case tpd.EmptyTree =>
+ case SharedTree(shared) =>
+ check(shared.isType || shared.isTerm)
+ }
+}
+
diff --git a/src/dotty/tools/dotc/core/PluggableTransformers.scala b/src/dotty/tools/dotc/ast/PluggableTransformers.scala
index caeb1c9e6..8c64feb21 100644
--- a/src/dotty/tools/dotc/core/PluggableTransformers.scala
+++ b/src/dotty/tools/dotc/ast/PluggableTransformers.scala
@@ -1,5 +1,5 @@
package dotty.tools.dotc
-package core
+package ast
object PluggableTransformers {
diff --git a/src/dotty/tools/dotc/core/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 79e35170a..eeab6ceb0 100644
--- a/src/dotty/tools/dotc/core/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -1,7 +1,8 @@
package dotty.tools
package dotc
-package core
+package ast
+import core._
import Flags._, Trees._, UntypedTrees._, TypedTrees._, Types._, Contexts._
import Names._, StdNames._, NameOps._, Decorators._, Symbols._
import util.HashSet
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 4cb65cf3b..9f8c2ca93 100644
--- a/src/dotty/tools/dotc/core/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -1,6 +1,7 @@
package dotty.tools.dotc
-package core
+package ast
+import core._
import Types._, Names._, Flags._, util.Positions._, Contexts._, Constants._, SymDenotations._, Symbols._
import Denotations._, StdNames._
import annotation.tailrec
diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala
index 2ded92920..b6583baf0 100644
--- a/src/dotty/tools/dotc/core/TypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/TypedTrees.scala
@@ -1,8 +1,11 @@
-package dotty.tools.dotc
-package core
+package dotty.tools
+package dotc
+package ast
+import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
-import SymDenotations._, Symbols._, StdNames._, Annotations._
+import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
+import CheckTrees._
object TypedTrees {
@@ -320,239 +323,6 @@ object TypedTrees {
}
}
- import Trees._
-
- def check(p: Boolean, msg: => String = "")(implicit ctx: Context): Unit = assert(p, msg)
-
- def checkTypeArg(arg: tpd.Tree, bounds: TypeBounds)(implicit ctx: Context): Unit = {
- check(arg.isValueType)
- check(bounds contains arg.tpe)
- }
-
- def checkType(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match {
- case Ident(name) =>
- case Select(qualifier, name) =>
- check(qualifier.isValue)
- check(qualifier.tpe =:= tree.tpe.normalizedPrefix)
- val denot = qualifier.tpe.member(name)
- check(denot.exists)
- check(denot.hasAltWith(_.symbol == tree.symbol))
- case This(cls) =>
- case Super(qual, mixin) =>
- check(qual.isValue)
- val cls = qual.tpe.typeSymbol
- check(cls.isClass)
- case Apply(fn, args) =>
- def checkArg(arg: tpd.Tree, name: Name, formal: Type): Unit = {
- arg match {
- case NamedArg(argName, _) =>
- check(argName == name)
- case SeqLiteral(_, _) =>
- check(defn.RepeatedParamClasses contains formal.typeSymbol)
- case _ =>
- check(arg.isValue)
- }
- check(arg.tpe <:< formal)
- }
- val MethodType(paramNames, paramTypes) = fn.tpe.widen // checked already at construction
- (args, paramNames, paramTypes).zipped foreach checkArg
- case TypeApply(fn, args) =>
- val pt @ PolyType(_) = fn.tpe.widen // checked already at construction
- (args, pt.instantiateBounds(args map (_.tpe))).zipped foreach checkTypeArg
- case Literal(const: Constant) =>
- case New(tpt) =>
- check(tpt.isValueType)
- val cls = tpt.tpe.typeSymbol
- check(cls.isClass)
- check(!(cls is AbstractOrTrait))
- case Pair(left, right) =>
- check(left.isValue)
- check(right.isValue)
- case Typed(expr, tpt) =>
- check(tpt.isValueType)
- expr.tpe.widen match {
- case tp: MethodType =>
- val cls = tpt.tpe.typeSymbol
- check(cls.isClass)
- check((cls is Trait) ||
- cls.primaryConstructor.info.paramTypess.flatten.isEmpty)
- val absMembers = tpt.tpe.abstractTermMembers
- check(absMembers.size == 1)
- check(tp <:< absMembers.head.info)
- case _ =>
- check(expr.isValueOrPattern)
- check(expr.tpe <:< tpt.tpe)
- }
- case NamedArg(name, arg) =>
- case Assign(lhs, rhs) =>
- check(lhs.isValue); check(rhs.isValue)
- lhs.tpe match {
- case ltpe: TermRef =>
- check(ltpe.symbol is Mutable)
- case _ =>
- check(false)
- }
- check(rhs.tpe <:< lhs.tpe.widen)
- case Block(stats, expr) =>
- var hoisted: Set[Symbol] = Set()
- lazy val locals = localSyms(stats).toSet
- check(expr.isValue)
- def isNonLocal(sym: Symbol): Boolean =
- !(locals contains sym) || isHoistableClass(sym)
- def isHoistableClass(sym: Symbol) =
- sym.isClass && {
- (hoisted contains sym) || {
- hoisted += sym
- noLeaksInClass(sym.asClass)
- }
- }
- def noLeaksIn(tp: Type): Boolean = tp forallParts {
- case tp: NamedType => isNonLocal(tp.symbol)
- case _ => true
- }
- def noLeaksInClass(sym: ClassSymbol): Boolean =
- (sym.info.parents forall noLeaksIn) &&
- (sym.decls.toList forall (t => noLeaksIn(t.info)))
- check(noLeaksIn(tree.tpe))
- case If(cond, thenp, elsep) =>
- check(cond.isValue); check(thenp.isValue); check(elsep.isValue)
- check(cond.tpe.derivesFrom(defn.BooleanClass))
- case Match(selector, cases) =>
- check(selector.isValue)
- // are any checks that relate selector and patterns desirable?
- case CaseDef(pat, guard, body) =>
- check(pat.isValueOrPattern); check(guard.isValue); check(body.isValue)
- check(guard.tpe.derivesFrom(defn.BooleanClass))
- case Return(expr, from) =>
- check(expr.isValue); check(from.isTerm)
- check(from.tpe.termSymbol.isSourceMethod)
- case Try(block, handler, finalizer) =>
- check(block.isTerm)
- check(finalizer.isTerm)
- check(handler.isTerm)
- check(handler.tpe derivesFrom defn.FunctionClass(1))
- check(handler.tpe.baseType(defn.FunctionClass(1)).typeArgs.head <:< defn.ThrowableType)
- case Throw(expr) =>
- check(expr.isValue)
- check(expr.tpe.derivesFrom(defn.ThrowableClass))
- case SeqLiteral(elemtpt, elems) =>
- check(elemtpt.isValueType);
- for (elem <- elems) {
- check(elem.isValue)
- check(elem.tpe <:< elemtpt.tpe)
- }
- case TypeTree(original) =>
- if (!original.isEmpty) {
- check(original.isValueType)
- check(original.tpe == tree.tpe)
- }
- case SingletonTypeTree(ref) =>
- check(ref.isValue)
- check(ref.symbol.isStable)
- case SelectFromTypeTree(qualifier, name) =>
- check(qualifier.isValueType)
- check(qualifier.tpe =:= tree.tpe.normalizedPrefix)
- val denot = qualifier.tpe.member(name)
- check(denot.exists)
- check(denot.symbol == tree.symbol)
- case AndTypeTree(left, right) =>
- check(left.isValueType); check(right.isValueType)
- case OrTypeTree(left, right) =>
- check(left.isValueType); check(right.isValueType)
- case RefinedTypeTree(tpt, refinements) =>
- check(tpt.isValueType)
- def checkRefinements(forbidden: Set[Symbol], rs: List[tpd.Tree]): Unit = rs match {
- case r :: rs1 =>
- val rsym = r.symbol
- check(rsym.isTerm || rsym.isAbstractOrAliasType)
- if (rsym.isAbstractType) check(tpt.tpe.member(rsym.name).exists)
- check(rsym.info forallParts {
- case nt: NamedType => !(forbidden contains nt.symbol)
- case _ => true
- })
- checkRefinements(forbidden - rsym, rs1)
- case nil =>
- }
- checkRefinements(localSyms(refinements).toSet, refinements)
- case AppliedTypeTree(tpt, args) =>
- check(tpt.isValueType)
- val tparams = tpt.tpe.typeParams
- check(sameLength(tparams, args))
- (args, tparams map (_.info.bounds)).zipped foreach checkTypeArg
- case TypeBoundsTree(lo, hi) =>
- check(lo.isValueType); check(hi.isValueType)
- check(lo.tpe <:< hi.tpe)
- case Bind(sym, body) =>
- check(body.isValueOrPattern)
- check(!(tree.symbol is Method))
- body match {
- case Ident(nme.WILDCARD) =>
- case _ => check(body.tpe.widen =:= tree.symbol.info)
- }
- case Alternative(alts) =>
- for (alt <- alts) check(alt.isValueOrPattern)
- case UnApply(fun, args) =>
- check(fun.isTerm)
- for (arg <- args) check(arg.isValueOrPattern)
- val funtpe @ MethodType(_, _) = fun.tpe.widen
- fun.symbol.name match { // check arg arity
- case nme.unapplySeq =>
- // args need to be wrapped in (...: _*)
- check(args.length == 1)
- check(args.head.tpe.typeSymbol == defn.RepeatedParamClass)
- case nme.unapply =>
- val rtp = funtpe.resultType
- val rsym = rtp.dealias.typeSymbol
- if (rsym == defn.BooleanClass)
- check(args.isEmpty)
- else {
- check(rsym == defn.OptionClass)
- val normArgs = rtp.typeArgs match {
- case optionArg :: Nil =>
- optionArg.typeArgs match {
- case Nil =>
- optionArg :: Nil
- case tupleArgs if defn.TupleClasses contains optionArg.dealias.typeSymbol =>
- tupleArgs
- }
- case _ =>
- check(false)
- Nil
- }
- check(sameLength(normArgs, args))
- }
- }
- case ValDef(mods, name, tpt, rhs) =>
- check(!(tree.symbol is Method))
- if (!rhs.isEmpty) {
- check(rhs.isValue)
- check(rhs.tpe <:< tpt.tpe)
- }
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- check(tree.symbol is Method)
- if (!rhs.isEmpty) {
- check(rhs.isValue)
- check(rhs.tpe <:< tpt.tpe)
- }
- case TypeDef(mods, name, _, tpt) =>
- check(tpt.tpe.isInstanceOf[TypeBounds])
- case Template(constr, parents, selfType, body) =>
- case ClassDef(mods, name, tparams, impl) =>
- case Import(expr, selectors) =>
- check(expr.isValue)
- check(expr.tpe.termSymbol.isStable)
- case PackageDef(pid, stats) =>
- check(pid.isTerm)
- check(pid.symbol is Package)
- case Annotated(annot, arg) =>
- check(annot.isInstantiation)
- check(annot.symbol.owner.isSubClass(defn.AnnotationClass))
- check(arg.isValueType || arg.isValue)
- case tpd.EmptyTree =>
- case SharedTree(shared) =>
- check(shared.isType || shared.isTerm)
- }
-
implicit class TreeOps[ThisTree <: tpd.Tree](val tree: ThisTree) extends AnyVal {
def isValue(implicit ctx: Context): Boolean =
@@ -633,4 +403,3 @@ object TypedTrees {
def localSyms(stats: List[tpd.Tree])(implicit ctx: Context): List[Symbol] =
for (stat <- stats if (stat.isDef)) yield stat.symbol
}
-
diff --git a/src/dotty/tools/dotc/ast/UntypedTrees.scala b/src/dotty/tools/dotc/ast/UntypedTrees.scala
new file mode 100644
index 000000000..c7f468134
--- /dev/null
+++ b/src/dotty/tools/dotc/ast/UntypedTrees.scala
@@ -0,0 +1,487 @@
+package dotty.tools
+package dotc
+package ast
+
+import core._
+import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
+import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, TypedTrees._
+import TreeInfo._
+import Decorators._
+import language.higherKinds
+import collection.mutable.ListBuffer
+
+object UntypedTrees {
+
+ object untpd extends Trees.Instance[Untyped] {
+
+ // ----- Tree cases that exist in untyped form only ------------------
+
+ /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */
+ case class TypedSplice(tree: TypedTree) extends UntypedTree
+
+ /** mods object name impl */
+ case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
+ extends NameTree with ModDefTree {
+ type ThisTree[T >: Untyped] <: Trees.NameTree[T] with Trees.ModDefTree[T] with ModuleDef
+ }
+
+ /** (vparams) => body */
+ case class SymbolLit(str: String) extends Tree
+ case class InterpolatedString(id: TermName, strings: List[Literal], elems: List[Tree]) extends Tree
+ case class Function(args: List[Tree], body: Tree) extends Tree
+ case class InfixOp(left: Tree, op: Name, right: Tree) extends Tree
+ case class PostfixOp(tree: Tree, op: Name) extends Tree
+ case class PrefixOp(op: Name, tree: Tree) extends Tree
+ case class Parens(tree: Tree) extends Tree {
+ def derivedParens(tree: Tree) = if (this.tree eq tree) this else Parens(tree).copyAttr(this)
+ }
+ case class Tuple(trees: List[Tree]) extends Tree {
+ def derivedTuple(trees: List[Tree]) = if (this.trees eq trees) this else Tuple(trees).copyAttr(this)
+ }
+ case class WhileDo(cond: Tree, body: Tree) extends TermTree
+ case class DoWhile(body: Tree, cond: Tree) extends TermTree
+ case class ForYield(enums: List[Tree], expr: Tree) extends TermTree
+ case class ForDo(enums: List[Tree], body: Tree) extends TermTree
+ case class GenFrom(pat: Tree, expr: Tree) extends Tree
+ case class GenAlias(pat: Tree, expr: Tree) extends Tree
+ case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
+ case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends Tree
+
+ val unitLiteral = Literal(Constant())
+
+ private type VarInfo = (NameTree, Tree)
+
+ def ref(tp: NamedType)(implicit ctx: Context): Tree =
+ TypedSplice(tpd.ref(tp))
+
+ def scalaUnit(implicit ctx: Context) = ref(defn.UnitClass.typeConstructor)
+
+ def makeConstructor(mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree = EmptyTree())(implicit ctx: Context): DefDef =
+ DefDef(mods, nme.CONSTRUCTOR, Nil, vparamss, TypeTree(), rhs)
+
+ def makeSelfDef(name: TermName, tpt: Tree)(implicit ctx: Context) =
+ ValDef(Modifiers(Private), name, tpt, EmptyTree())
+
+ def makeTupleOrParens(ts: List[Tree])(implicit ctx: Context) = ts match {
+ case t :: Nil => Parens(t)
+ case _ => Tuple(ts)
+ }
+
+ def makeTuple(ts: List[Tree])(implicit ctx: Context) = ts match {
+ case t :: Nil => t
+ case _ => Tuple(ts)
+ }
+
+ /** new C(args) */
+ def makeNew(tpt: Tree, args: List[Tree])(implicit ctx: Context): Apply =
+ Apply(Select(Trees.New(tpt), nme.CONSTRUCTOR), args)
+
+ def makeSyntheticParameter(pname: TermName)(implicit ctx: Context): ValDef =
+ ValDef(Modifiers(SyntheticTermParam), pname, TypeTree(), EmptyTree())
+
+ def desugar(tree: Tree, mode: Mode.Value)(implicit ctx: Context): Tree = {
+
+ def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
+ val ldef = DefDef(Modifiers(Label), lname, Nil, ListOfNil, TypeTree(), rhs)
+ Block(ldef, call)
+ }
+
+ def derivedValDef(mods: Modifiers, named: NameTree, tpt: Tree, rhs: Tree) =
+ ValDef(mods, named.name.asTermName, tpt, rhs).withPos(named.pos)
+
+ /** Translate infix operation expression left op right
+ */
+ def makeBinop(left: Tree, op: Name, right: Tree): Tree = {
+ def assignToNamedArg(arg: Tree) = arg match {
+ case Assign(Ident(name), rhs) => arg.derivedNamedArg(name, rhs)
+ case _ => arg
+ }
+ if (isLeftAssoc(op)) {
+ val args: List[Tree] = right match {
+ case Parens(arg) => assignToNamedArg(arg) :: Nil
+ case Tuple(args) => args mapConserve assignToNamedArg
+ case _ => right :: Nil
+ }
+ Apply(Select(left, op.encode), args)
+ } else {
+ val x = ctx.freshName().toTermName
+ Block(
+ ValDef(Modifiers(Synthetic), x, TypeTree(), left),
+ Apply(Select(right, op.encode), Ident(x)))
+ }
+ }
+
+ /** Create tree for for-comprehension <for (enums) do body> or
+ * <for (enums) yield body> where mapName and flatMapName are chosen
+ * corresponding to whether this is a for-do or a for-yield.
+ * The creation performs the following rewrite rules:
+ *
+ * 1.
+ *
+ * for (P <- G) E ==> G.foreach (P => E)
+ *
+ * Here and in the following (P => E) is interpreted as the function (P => E)
+ * if P is a variable pattern and as the partial function { case P => E } otherwise.
+ *
+ * 2.
+ *
+ * for (P <- G) yield E ==> G.map (P => E)
+ *
+ * 3.
+ *
+ * for (P_1 <- G_1; P_2 <- G_2; ...) ...
+ * ==>
+ * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
+ *
+ * 4.
+ *
+ * for (P <- G; E; ...) ...
+ * =>
+ * for (P <- G.filter (P => E); ...) ...
+ *
+ * 5. For any N:
+ *
+ * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...)
+ * ==>
+ * for (TupleN(P_1, P_2, ... P_N) <-
+ * for (x_1 @ P_1 <- G) yield {
+ * val x_2 @ P_2 = E_2
+ * ...
+ * val x_N & P_N = E_N
+ * TupleN(x_1, ..., x_N)
+ * } ...)
+ *
+ * If any of the P_i are variable patterns, the corresponding `x_i @ P_i' is not generated
+ * and the variable constituting P_i is used instead of x_i
+ *
+ * @param mapName The name to be used for maps (either map or foreach)
+ * @param flatMapName The name to be used for flatMaps (either flatMap or foreach)
+ * @param enums The enumerators in the for expression
+ * @param body The body of the for expression
+ */
+ def makeFor(mapName: TermName, flatMapName: TermName, enums: List[Tree], body: Tree): Tree = {
+
+ /** Make a function value pat => body.
+ * If pat is a var pattern id: T then this gives (id: T) => body
+ * Otherwise this gives { case pat => body }
+ */
+ def makeLambda(pat: Tree, body: Tree): Tree = pat match {
+ case VarPattern(named, tpt) =>
+ Function(derivedValDef(Modifiers(Param), named, tpt, EmptyTree()) :: Nil, body)
+ case _ =>
+ Match(EmptyTree(), CaseDef(pat, EmptyTree(), body) :: Nil)
+ }
+
+ /** If `pat` is not yet a `Bind` wrap it in one with a fresh name
+ */
+ def makeBind(pat: Tree): Tree = pat match {
+ case Bind(_, _) => pat
+ case _ => Bind(ctx.freshName().toTermName, pat)
+ }
+
+ /** Is pattern `pat` irrefutable when matched against `rhs`?
+ * We only can do a simple syntactic check here; a more refined check
+ * is done later prompted by the presence of a "withFilterIfRefutable" call.
+ */
+ def isIrrefutable(pat: Tree, rhs: Tree): Boolean = {
+ def matchesTuple(pats: List[Tree], rhs: Tree): Boolean = rhs match {
+ case Tuple(trees) => (pats corresponds trees)(isIrrefutable)
+ case Parens(rhs1) => matchesTuple(pats, rhs1)
+ case Block(_, rhs1) => matchesTuple(pats, rhs1)
+ case If(_, thenp, elsep) => matchesTuple(pats, thenp) && matchesTuple(pats, elsep)
+ case Match(_, cases) => cases forall (matchesTuple(pats, _))
+ case CaseDef(_, _, rhs1) => matchesTuple(pats, rhs)
+ case Throw(_) => true
+ case _ => false
+ }
+ pat match {
+ case Bind(_, pat1) => isIrrefutable(pat1, rhs)
+ case Parens(pat1) => isIrrefutable(pat1, rhs)
+ case Tuple(pats) => matchesTuple(pats, rhs)
+ case _ => isVarPattern(pat)
+ }
+ }
+
+ /** Make a pattern filter:
+ * rhs.withFilterIfRefutable { case pat => true case _ => false }
+ */
+ def makePatFilter(rhs: Tree, pat: Tree): Tree = {
+ val cases = List(
+ CaseDef(pat, EmptyTree(), Literal(Constant(true))),
+ CaseDef(Ident(nme.WILDCARD), EmptyTree(), Literal(Constant(false))))
+ Apply(Select(rhs, nme.withFilterIfRefutable), Match(EmptyTree(), cases))
+ }
+
+ /** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
+ * matched against `rhs`.
+ */
+ def rhsSelect(rhs: Tree, name: TermName, pat: Tree) = {
+ val rhs1 = if (isIrrefutable(pat, rhs)) rhs else makePatFilter(rhs, pat)
+ Select(rhs1, name)
+ }
+
+ enums match {
+ case (enum @ GenFrom(pat, rhs)) :: Nil =>
+ Apply(rhsSelect(rhs, mapName, pat), makeLambda(pat, body))
+ case GenFrom(pat, rhs) :: (rest @ (GenFrom(_, _) :: _)) =>
+ val cont = makeFor(mapName, flatMapName, rest, body)
+ Apply(rhsSelect(rhs, flatMapName, pat), makeLambda(pat, cont))
+ case (enum @ GenFrom(pat, rhs)) :: (rest @ GenAlias(_, _) :: _) =>
+ val (valeqs, rest1) = rest.span(_.isInstanceOf[GenAlias])
+ val pats = valeqs map { case GenAlias(pat, _) => pat }
+ val rhss = valeqs map { case GenAlias(_, rhs) => rhs }
+ val defpat1 = makeBind(pat)
+ val defpats = pats map makeBind
+ val pdefs = (defpats, rhss).zipped map (makePatDef(Modifiers(), _, _))
+ val ids = (defpat1 :: defpats) map { case Bind(name, _) => Ident(name) }
+ val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids)))
+ val allpats = pat :: pats
+ val vfrom1 = GenFrom(makeTuple(allpats), rhs1)
+ makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
+ case (enum @ GenFrom(pat, rhs)) :: test :: rest =>
+ val filtered = Apply(rhsSelect(rhs, nme.withFilter, pat), makeLambda(pat, test))
+ makeFor(mapName, flatMapName, GenFrom(pat, filtered) :: rest, body)
+ case _ =>
+ EmptyTree() //may happen for erroneous input
+ }
+ }
+
+ def makeAnnotated(cls: Symbol, tree: Tree) =
+ Annotated(TypedSplice(tpd.New(cls.typeConstructor)), tree)
+
+ /** Returns list of all pattern variables, possibly with their types,
+ * without duplicates
+ */
+ def getVariables(tree: Tree): List[VarInfo] =
+ getVars(new ListBuffer[VarInfo], tree).toList
+
+ /** In case there is exactly one variable x_1 in pattern
+ * val/var p = e ==> val/var x_1 = (e: @unchecked) match (case p => (x_1))
+ *
+ * in case there are zero or more than one variables in pattern
+ * val/var p = e ==> private synthetic val t$ = (e: @unchecked) match (case p => (x_1, ..., x_N))
+ * val/var x_1 = t$._1
+ * ...
+ * val/var x_N = t$._N
+ * If the original pattern variable carries a type annotation, so does the corresponding
+ * ValDef.
+ */
+ def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree): Tree = pat match {
+ case VarPattern(named, tpt) =>
+ derivedValDef(mods, named, tpt, rhs)
+ case _ =>
+ val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
+ val vars = getVariables(pat)
+ val ids = for ((named, _) <- vars) yield Ident(named.name)
+ val caseDef = CaseDef(pat, EmptyTree(), makeTuple(ids))
+ val matchExpr = Match(rhsUnchecked, caseDef :: Nil)
+ vars match {
+ case (named, tpt) :: Nil =>
+ derivedValDef(mods, named, tpt, matchExpr)
+ case _ =>
+ val tmpName = ctx.freshName().toTermName
+ val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy))
+ val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr)
+ def selector(n: Int) = Select(Ident(tmpName), ("_" + n).toTermName)
+ val restDefs =
+ for (((named, tpt), n) <- vars.zipWithIndex)
+ yield derivedValDef(mods, named, tpt, selector(n))
+ TempTrees(firstDef :: restDefs)
+ }
+ }
+
+ def isPatternVar(id: Ident) =
+ mode == Mode.Pattern && isVarPattern(id) && id.name != nme.WILDCARD
+
+ // begin desugar
+ tree match { // todo: move general tree desugaring to typer, and keep only untyped trees here?
+ case id @ Ident(_) if isPatternVar(id) =>
+ Bind(id.name, Ident(nme.WILDCARD))
+ case Typed(id @ Ident(_), tpt) if isPatternVar(id) =>
+ Bind(id.name, Typed(Ident(nme.WILDCARD), tpt)).withPos(id.pos)
+ case New(templ: Template) =>
+ desugarAnonClass(templ)
+ case Assign(Apply(fn, args), rhs) =>
+ Apply(Select(fn, nme.update), args :+ rhs)
+ case If(cond, thenp, EmptyTree()) =>
+ If(cond, thenp, unitLiteral)
+ case _: DefDef | _: ClassDef =>
+ desugarContextBounds(tree)
+ case ModuleDef(mods, name, tmpl @ Template(constr, parents, self, body)) =>
+ // <module> val name: name$ = New(name$)
+ // <module> final class name$ extends parents { self: name.type => body }
+ val clsName = name.moduleClassName
+ val clsRef = Ident(clsName)
+ val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, clsRef)
+ val clsSelf = self.derivedValDef(self.mods, self.name, SingletonTypeTree(Ident(name)), self.rhs)
+ val clsTmpl = tmpl.derivedTemplate(constr, parents, clsSelf, body)
+ val cls = ClassDef(mods & AccessFlags | ModuleClassCreationFlags, clsName, Nil, clsTmpl)
+ TempTrees(List(modul, cls))
+ case SymbolLit(str) =>
+ makeNew(ref(defn.SymbolClass.typeConstructor), Literal(Constant(str)) :: Nil)
+ case InterpolatedString(id, strs, elems) =>
+ Apply(Select(Apply(Ident(nme.StringContext), strs), id), elems)
+ case Function(args, body) =>
+ if (mode == Mode.Type) // FunctionN[args: _*, body]
+ AppliedTypeTree(
+ ref(defn.FunctionClass(args.length).typeConstructor),
+ args :+ body)
+ else { // { def $anonfun(args) = body; $anonfun }
+ val params = args.asInstanceOf[List[ValDef]]
+ Block(
+ DefDef(Modifiers(Synthetic), nme.ANON_FUN, Nil, params :: Nil, EmptyTree(), body),
+ Ident(nme.ANON_FUN))
+ }
+ case InfixOp(l, op, r) =>
+ mode match {
+ case Mode.Expr => // l.op'(r), or val x = r; l.op;(x), plus handle named args specially
+ makeBinop(l, op, r)
+ case Mode.Pattern => // op'(l, r)
+ Apply(Ident(op.encode), l :: r :: Nil)
+ case Mode.Type => // op'[l, r]
+ AppliedTypeTree(Ident(op.encode), l :: r :: Nil)
+ }
+ case PostfixOp(t, op) =>
+ if (mode == Mode.Type && op == nme.raw.STAR)
+ AppliedTypeTree(ref(defn.RepeatedParamType), t)
+ else {
+ assert(mode == Mode.Expr)
+ if (op == nme.WILDCARD) tree // desugar later by eta expansion
+ else Select(t, op.encode)
+ }
+ case PrefixOp(op, t) =>
+ if (mode == Mode.Type && op == nme.ARROWkw)
+ AppliedTypeTree(ref(defn.ByNameParamClass.typeConstructor), t)
+ else
+ Select(t, nme.UNARY_PREFIX ++ op.encode)
+ case Parens(t) =>
+ t
+ case Tuple(ts) =>
+ def PairTypeTree(l: Tree, r: Tree) =
+ AppliedTypeTree(ref(defn.PairClass.typeConstructor), l :: r :: Nil)
+ if (mode == Mode.Type) ts.reduceRight(PairTypeTree)
+ else if (ts.isEmpty) unitLiteral
+ else ts.reduceRight(Pair(_, _))
+ case WhileDo(cond, body) =>
+ // { <label> def while$(): Unit = if (cond) { body; while$() } ; while$() }
+ val call = Apply(Ident(nme.WHILE_PREFIX), Nil)
+ val rhs = If(cond, Block(body, call), unitLiteral)
+ labelDefAndCall(nme.WHILE_PREFIX, rhs, call)
+ case DoWhile(body, cond) =>
+ // { label def doWhile$(): Unit = { body; if (cond) doWhile$() } ; doWhile$() }
+ val call = Apply(Ident(nme.DO_WHILE_PREFIX), Nil)
+ val rhs = Block(body, If(cond, call, unitLiteral))
+ labelDefAndCall(nme.DO_WHILE_PREFIX, rhs, call)
+ case ForDo(enums, body) =>
+ makeFor(nme.foreach, nme.foreach, enums, body) orElse tree
+ case ForYield(enums, body) =>
+ makeFor(nme.map, nme.flatMap, enums, body) orElse tree
+ case PatDef(mods, pats, tpt, rhs) =>
+ val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
+ combine(pats1 map (makePatDef(mods, _, rhs)))
+ case _ =>
+ tree
+ }
+ }.withPos(tree.pos)
+
+ def desugarContextBounds(tparams: List[TypeDef], vparamss: List[List[ValDef]], ofClass: Boolean): (List[TypeDef], List[List[ValDef]]) = {
+ val epbuf = new ListBuffer[ValDef]
+ def makeEvidenceParam(cxBound: Tree): ValDef = ???
+ val tparams1 = tparams map {
+ case tparam @ TypeDef(mods, name, ttparams, ContextBounds(tbounds, cxbounds)) =>
+ for (cxbound <- cxbounds) {
+ val accessMods = if (ofClass) PrivateOrLocal else EmptyFlags
+ val epname = (nme.EVIDENCE_PARAM_PREFIX.toString + epbuf.length).toTermName
+ epbuf +=
+ ValDef(Modifiers(Implicit | Param | accessMods), epname, cxbound, EmptyTree())
+ }
+ tparam.derivedTypeDef(mods, name, ttparams, tbounds)
+ case tparam =>
+ tparam
+ }
+ val evidenceParams = epbuf.toList
+ val vparamss1 = vparamss.reverse match {
+ case (vparams @ (vparam :: _)) :: rvparamss if vparam.mods is Implicit =>
+ ((vparams ++ evidenceParams) :: rvparamss).reverse
+ case _ =>
+ vparamss :+ evidenceParams
+ }
+ (tparams1, vparamss1)
+ }
+
+ def desugarContextBounds(tree: Tree): Tree = tree match {
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ val (tparams1, vparamss1) =
+ desugarContextBounds(tparams, vparamss, ofClass = false)
+ tree.derivedDefDef(mods, name, tparams1, vparamss, tpt, rhs)
+ case ClassDef(
+ mods, name, tparams, templ @ Template(constr, parents, self, body)) =>
+ val (tparams1, vparamss1) =
+ desugarContextBounds(tparams, constr.vparamss, ofClass = true)
+ val constr1 = constr.derivedDefDef(
+ constr.mods, constr.name, constr.tparams, vparamss1, constr.tpt, constr.rhs)
+ val templ1 = templ.derivedTemplate(constr1, parents, self, body)
+ tree.derivedClassDef(mods, name, tparams1, templ1)
+ case _ => tree
+ }
+
+ def desugarAnonClass(templ: Template): Tree = {
+ val x = tpnme.ANON_CLASS
+ val clsDef = ClassDef(Modifiers(Final), x, Nil, templ)
+ Block(clsDef, New(Ident(x), Nil))
+ }
+
+ object Mode extends Enumeration {
+ val Type, Expr, Pattern = Value
+ }
+
+ /** If tree is a variable pattern, return its name and type, otherwise return None.
+ */
+ private object VarPattern {
+ def unapply(tree: Tree): Option[VarInfo] = tree match {
+ case id: Ident => Some(id, TypeTree())
+ case Typed(id: Ident, tpt) => Some((id, tpt))
+ case _ => None
+ }
+ }
+
+ /** Traverse pattern and collect all variable names with their types in buffer.
+ * Works for expanded as well as unexpanded patterns
+ *
+ */
+ private object getVars extends TreeAccumulator[ListBuffer[VarInfo]] {
+ override def apply(buf: ListBuffer[VarInfo], tree: Tree): ListBuffer[VarInfo] = {
+ def seenName(name: Name) = buf exists (_._1.name == name)
+ def add(named: NameTree, t: Tree): ListBuffer[VarInfo] =
+ if (seenName(named.name)) buf else buf += ((named, t))
+ tree match {
+ case Bind(nme.WILDCARD, _) =>
+ foldOver(buf, tree)
+ case tree @ Bind(_, Typed(tree1, tpt)) if !mayBeTypePat(tpt) =>
+ apply(add(tree, tpt), tree1)
+ case tree @ Bind(_, tree1) =>
+ apply(add(tree, TypeTree()), tree1)
+ case Typed(id: Ident, t) if isVarPattern(id) =>
+ add(id, t)
+ case id: Ident if isVarPattern(id) =>
+ add(id, TypeTree())
+ case _ =>
+ foldOver(buf, tree)
+ }
+ }
+ }
+
+ implicit class UntypedTreeDecorator(val self: Tree) extends AnyVal {
+ def locateEnclosing(base: List[Tree], pos: Position): List[Tree] = {
+ def encloses(elem: Any) = elem match {
+ case t: Tree => t.envelope contains pos
+ case _ => false
+ }
+ base.productIterator find encloses match {
+ case Some(tree: Tree) => locateEnclosing(tree :: base, pos)
+ case none => base
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 9086047cd..07ed37f06 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package core
-import Symbols._, Types._, util.Positions._, Contexts._, Constants._, TypedTrees.tpd._
+import Symbols._, Types._, util.Positions._, Contexts._, Constants._, ast.TypedTrees.tpd._
object Annotations {
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index d29f8834d..8fcdc2cbd 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -9,7 +9,7 @@ import Phases._
import Types._
import Symbols._
import TypeComparers._, NameOps._, SymDenotations._, util.Positions._
-import TypedTrees.tpd._, util.FreshNameCreator
+import ast.TypedTrees.tpd._, util.FreshNameCreator
import config.Settings._
import config.ScalaSettings
import reporting._
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index b6efdcd36..8c5474740 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -12,7 +12,9 @@ import Symbols._
import Contexts._
import SymDenotations._, printing.Texts._
import printing.Printer
-import Types._, Annotations._, util.Positions._, StdNames._, Trees._, NameOps._
+import Types._, Annotations._, util.Positions._, StdNames._, NameOps._
+import ast.TypedTrees.TreeMapper
+import ast.TypedTrees.tpd.SharedTree
import Denotations.{ Denotation, SingleDenotation, MultiDenotation }
import collection.mutable
import io.AbstractFile
@@ -200,7 +202,7 @@ trait Symbols { this: Context =>
newSymbol(cls, nme.localDummyName(cls), EmptyFlags, NoType)
/** Create an import symbol pointing back to given qualifier `expr`. */
- def newImportSymbol(expr: SharedTree[Type], coord: Coord = NoCoord) =
+ def newImportSymbol(expr: SharedTree, coord: Coord = NoCoord) =
newSymbol(NoSymbol, nme.IMPORT, EmptyFlags, ImportType(expr), coord = coord)
/** Create a class constructor symbol for given class `cls`. */
@@ -251,7 +253,7 @@ trait Symbols { this: Context =>
else {
val copies: List[Symbol] = for (original <- originals) yield
newNakedSymbol[original.ThisName](original.coord)
- val treeMap = new TypedTrees.TreeMapper(typeMap, ownerMap)
+ val treeMap = new TreeMapper(typeMap, ownerMap)
.withSubstitution(originals, copies)
(originals, copies).zipped foreach {(original, copy) =>
val odenot = original.denot
diff --git a/src/dotty/tools/dotc/core/TypeComparers.scala b/src/dotty/tools/dotc/core/TypeComparers.scala
index 9d109b724..7dd874325 100644
--- a/src/dotty/tools/dotc/core/TypeComparers.scala
+++ b/src/dotty/tools/dotc/core/TypeComparers.scala
@@ -1,4 +1,5 @@
-package dotty.tools.dotc.core
+package dotty.tools
+package dotc.core
import Types._, Contexts._, Symbols._, Flags._
import collection.mutable
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 395584a49..135437671 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -15,7 +15,7 @@ import SymDenotations._
import Decorators._
import Denotations._
import Periods._
-import TypedTrees.tpd._, TypedTrees.TreeMapper, printing.Texts._
+import ast.TypedTrees.tpd._, ast.TypedTrees.TreeMapper, printing.Texts._
import transform.Erasure
import printing.Printer
import scala.util.hashing.{ MurmurHash3 => hashing }
@@ -936,7 +936,7 @@ object Types {
lastDenotation
}
- private[core] final def withDenot(denot: Denotation): this.type = {
+ private[dotc] final def withDenot(denot: Denotation): this.type = {
lastDenotation = denot
this
}
diff --git a/src/dotty/tools/dotc/core/UntypedTrees.scala b/src/dotty/tools/dotc/core/UntypedTrees.scala
deleted file mode 100644
index f5ed04f11..000000000
--- a/src/dotty/tools/dotc/core/UntypedTrees.scala
+++ /dev/null
@@ -1,501 +0,0 @@
-package dotty.tools
-package dotc
-package core
-
-import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
-import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, TypedTrees._
-import TreeInfo._
-import Decorators._
-import language.higherKinds
-import collection.mutable.ListBuffer
-
-object UntypedTrees {
-
- object untpd extends Trees.Instance[Untyped] {
-
- // ----- Tree cases that exist in untyped form only ------------------
-
- /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice */
- case class TypedSplice(tree: TypedTree) extends UntypedTree
-
- /** mods object name impl */
- case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
- extends NameTree with ModDefTree {
- type ThisTree[T >: Untyped] <: Trees.NameTree[T] with Trees.ModDefTree[T] with ModuleDef
- }
-
- /** (vparams) => body */
- case class SymbolLit(str: String) extends Tree
- case class InterpolatedString(id: TermName, strings: List[Literal], elems: List[Tree]) extends Tree
- case class Function(args: List[Tree], body: Tree) extends Tree
- case class InfixOp(left: Tree, op: Name, right: Tree) extends Tree
- case class PostfixOp(tree: Tree, op: Name) extends Tree
- case class PrefixOp(op: Name, tree: Tree) extends Tree
- case class Parens(tree: Tree) extends Tree {
- def derivedParens(tree: Tree) = if (this.tree eq tree) this else Parens(tree).copyAttr(this)
- }
- case class Tuple(trees: List[Tree]) extends Tree {
- def derivedTuple(trees: List[Tree]) = if (this.trees eq trees) this else Tuple(trees).copyAttr(this)
- }
- case class WhileDo(cond: Tree, body: Tree) extends TermTree
- case class DoWhile(body: Tree, cond: Tree) extends TermTree
- case class ForYield(enums: List[Tree], expr: Tree) extends TermTree
- case class ForDo(enums: List[Tree], body: Tree) extends TermTree
- case class GenFrom(pat: Tree, expr: Tree) extends Tree
- case class GenAlias(pat: Tree, expr: Tree) extends Tree
- case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
- case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends Tree
-
- val unitLiteral = Literal(Constant())
- }
-
- import untpd._
-
- object Mode extends Enumeration {
- val Type, Expr, Pattern = Value
- }
-
- private type VarInfo = (NameTree, Tree)
-
- class UGen(implicit val ctx: Context) extends AnyVal {
-
- def scalaDot(name: Name): Select =
- Select(new TypedSplice(tpd.Ident(defn.ScalaPackageVal.termRef)), name)
-
- def scalaAnyRefConstr = scalaDot(tpnme.AnyRef)
- def scalaAnyValConstr = scalaDot(tpnme.AnyVal)
- def scalaAnyConstr = scalaDot(tpnme.Any)
- def scalaUnitConstr = scalaDot(tpnme.Unit)
- def productConstr = scalaDot(tpnme.Product)
- def productConstrN(n: Int) = scalaDot(("Product" + n).toTypeName)
- def serializableConstr = scalaDot(tpnme.Serializable)
-
- def constructor(mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree = EmptyTree()): DefDef =
- DefDef(mods, nme.CONSTRUCTOR, Nil, vparamss, TypeTree(), rhs)
-
- def selfDef(name: TermName, tpt: Tree) =
- ValDef(Modifiers(Private), name, tpt, EmptyTree())
-
- def makeTupleOrParens(ts: List[Tree]) = ts match {
- case t :: Nil => Parens(t)
- case _ => Tuple(ts)
- }
-
- def makeTuple(ts: List[Tree]) = ts match {
- case t :: Nil => t
- case _ => Tuple(ts)
- }
-
- def ref(tp: NamedType)(implicit ctx: Context): Tree =
- TypedSplice(tpd.ref(tp))
-
- /** new C(args) */
- def New(tpt: Tree, args: List[Tree]): Apply =
- Apply(Select(Trees.New(tpt), nme.CONSTRUCTOR), args)
-
- def syntheticParameter(pname: TermName): ValDef =
- ValDef(Modifiers(SyntheticTermParam), pname, TypeTree(), EmptyTree())
-
- private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
- val ldef = DefDef(Modifiers(Label), lname, Nil, ListOfNil, TypeTree(), rhs)
- Block(ldef, call)
- }
-
- private def derivedValDef(mods: Modifiers, named: NameTree, tpt: Tree, rhs: Tree) =
- ValDef(mods, named.name.asTermName, tpt , rhs).withPos(named.pos)
-
- /** Translate infix operation expression left op right
- */
- private def makeBinop(left: Tree, op: Name, right: Tree): Tree = {
- def assignToNamedArg(arg: Tree) = arg match {
- case Assign(Ident(name), rhs) => arg.derivedNamedArg(name, rhs)
- case _ => arg
- }
- if (isLeftAssoc(op)) {
- val args: List[Tree] = right match {
- case Parens(arg) => assignToNamedArg(arg) :: Nil
- case Tuple(args) => args mapConserve assignToNamedArg
- case _ => right :: Nil
- }
- Apply(Select(left, op.encode), args)
- } else {
- val x = ctx.freshName().toTermName
- Block(
- ValDef(Modifiers(Synthetic), x, TypeTree(), left),
- Apply(Select(right, op.encode), Ident(x)))
- }
- }
-
- /** Create tree for for-comprehension <for (enums) do body> or
- * <for (enums) yield body> where mapName and flatMapName are chosen
- * corresponding to whether this is a for-do or a for-yield.
- * The creation performs the following rewrite rules:
- *
- * 1.
- *
- * for (P <- G) E ==> G.foreach (P => E)
- *
- * Here and in the following (P => E) is interpreted as the function (P => E)
- * if P is a variable pattern and as the partial function { case P => E } otherwise.
- *
- * 2.
- *
- * for (P <- G) yield E ==> G.map (P => E)
- *
- * 3.
- *
- * for (P_1 <- G_1; P_2 <- G_2; ...) ...
- * ==>
- * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
- *
- * 4.
- *
- * for (P <- G; E; ...) ...
- * =>
- * for (P <- G.filter (P => E); ...) ...
- *
- * 5. For any N:
- *
- * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...)
- * ==>
- * for (TupleN(P_1, P_2, ... P_N) <-
- * for (x_1 @ P_1 <- G) yield {
- * val x_2 @ P_2 = E_2
- * ...
- * val x_N & P_N = E_N
- * TupleN(x_1, ..., x_N)
- * } ...)
- *
- * If any of the P_i are variable patterns, the corresponding `x_i @ P_i' is not generated
- * and the variable constituting P_i is used instead of x_i
- *
- * @param mapName The name to be used for maps (either map or foreach)
- * @param flatMapName The name to be used for flatMaps (either flatMap or foreach)
- * @param enums The enumerators in the for expression
- * @param body The body of the for expression
- */
- private def makeFor(mapName: TermName, flatMapName: TermName, enums: List[Tree], body: Tree): Tree = {
-
- /** Make a function value pat => body.
- * If pat is a var pattern id: T then this gives (id: T) => body
- * Otherwise this gives { case pat => body }
- */
- def makeLambda(pat: Tree, body: Tree): Tree = pat match {
- case VarPattern(named, tpt) =>
- Function(derivedValDef(Modifiers(Param), named, tpt, EmptyTree()) :: Nil, body)
- case _ =>
- Match(EmptyTree(), CaseDef(pat, EmptyTree(), body) :: Nil)
- }
-
- /** If `pat` is not yet a `Bind` wrap it in one with a fresh name
- */
- def makeBind(pat: Tree): Tree = pat match {
- case Bind(_, _) => pat
- case _ => Bind(ctx.freshName().toTermName, pat)
- }
-
- /** Is pattern `pat` irrefutable when matched against `rhs`?
- * We only can do a simple syntactic check here; a more refined check
- * is done later prompted by the presence of a "withFilterIfRefutable" call.
- */
- def isIrrefutable(pat: Tree, rhs: Tree): Boolean = {
- def matchesTuple(pats: List[Tree], rhs: Tree): Boolean = rhs match {
- case Tuple(trees) => (pats corresponds trees)(isIrrefutable)
- case Parens(rhs1) => matchesTuple(pats, rhs1)
- case Block(_, rhs1) => matchesTuple(pats, rhs1)
- case If(_, thenp, elsep) => matchesTuple(pats, thenp) && matchesTuple(pats, elsep)
- case Match(_, cases) => cases forall (matchesTuple(pats, _))
- case CaseDef(_, _, rhs1) => matchesTuple(pats, rhs)
- case Throw(_) => true
- case _ => false
- }
- pat match {
- case Bind(_, pat1) => isIrrefutable(pat1, rhs)
- case Parens(pat1) => isIrrefutable(pat1, rhs)
- case Tuple(pats) => matchesTuple(pats, rhs)
- case _ => isVarPattern(pat)
- }
- }
-
- /** Make a pattern filter:
- * rhs.withFilterIfRefutable { case pat => true case _ => false }
- */
- def makePatFilter(rhs: Tree, pat: Tree): Tree = {
- val cases = List(
- CaseDef(pat, EmptyTree(), Literal(Constant(true))),
- CaseDef(Ident(nme.WILDCARD), EmptyTree(), Literal(Constant(false)))
- )
- Apply(Select(rhs, nme.withFilterIfRefutable), Match(EmptyTree(), cases))
- }
-
- /** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
- * matched against `rhs`.
- */
- def rhsSelect(rhs: Tree, name: TermName, pat: Tree) = {
- val rhs1 = if (isIrrefutable(pat, rhs)) rhs else makePatFilter(rhs, pat)
- Select(rhs1, name)
- }
-
- enums match {
- case (enum @ GenFrom(pat, rhs)) :: Nil =>
- Apply(rhsSelect(rhs, mapName, pat), makeLambda(pat, body))
- case GenFrom(pat, rhs) :: (rest @ (GenFrom(_, _) :: _)) =>
- val cont = makeFor(mapName, flatMapName, rest, body)
- Apply(rhsSelect(rhs, flatMapName, pat), makeLambda(pat, cont))
- case (enum @ GenFrom(pat, rhs)) :: (rest @ GenAlias(_, _) :: _) =>
- val (valeqs, rest1) = rest.span(_.isInstanceOf[GenAlias])
- val pats = valeqs map { case GenAlias(pat, _) => pat }
- val rhss = valeqs map { case GenAlias(_, rhs) => rhs }
- val defpat1 = makeBind(pat)
- val defpats = pats map makeBind
- val pdefs = (defpats, rhss).zipped map (makePatDef(Modifiers(), _, _))
- val ids = (defpat1 :: defpats) map { case Bind(name, _) => Ident(name) }
- val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids)))
- val allpats = pat :: pats
- val vfrom1 = GenFrom(makeTuple(allpats), rhs1)
- makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
- case (enum @ GenFrom(pat, rhs)) :: test :: rest =>
- val filtered = Apply(rhsSelect(rhs, nme.withFilter, pat), makeLambda(pat, test))
- makeFor(mapName, flatMapName, GenFrom(pat, filtered) :: rest, body)
- case _ =>
- EmptyTree() //may happen for erroneous input
- }
- }
-
- private def makeAnnotated(cls: Symbol, tree: Tree) =
- Annotated(TypedSplice(tpd.New(cls.typeConstructor)), tree)
-
- /** Returns list of all pattern variables, possibly with their types,
- * without duplicates
- */
- private def getVariables(tree: Tree): List[VarInfo] =
- getVars(new ListBuffer[VarInfo], tree).toList
-
- /** In case there is exactly one variable x_1 in pattern
- * val/var p = e ==> val/var x_1 = (e: @unchecked) match (case p => (x_1))
- *
- * in case there are zero or more than one variables in pattern
- * val/var p = e ==> private synthetic val t$ = (e: @unchecked) match (case p => (x_1, ..., x_N))
- * val/var x_1 = t$._1
- * ...
- * val/var x_N = t$._N
- * If the original pattern variable carries a type annotation, so does the corresponding
- * ValDef.
- */
- private def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree): Tree = pat match {
- case VarPattern(named, tpt) =>
- derivedValDef(mods, named, tpt, rhs)
- case _ =>
- val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
- val vars = getVariables(pat)
- val ids = for ((named, _) <- vars) yield Ident(named.name)
- val caseDef = CaseDef(pat, EmptyTree(), makeTuple(ids))
- val matchExpr = Match(rhsUnchecked, caseDef :: Nil)
- vars match {
- case (named, tpt) :: Nil =>
- derivedValDef(mods, named, tpt, matchExpr)
- case _ =>
- val tmpName = ctx.freshName().toTermName
- val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy))
- val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr)
- def selector(n: Int) = Select(Ident(tmpName), ("_" + n).toTermName)
- val restDefs =
- for (((named, tpt), n) <- vars.zipWithIndex)
- yield derivedValDef(mods, named, tpt, selector(n))
- TempTrees(firstDef :: restDefs)
- }
- }
-
- def desugarContextBounds(tparams: List[TypeDef], vparamss: List[List[ValDef]], ofClass: Boolean): (List[TypeDef], List[List[ValDef]]) = {
- val epbuf = new ListBuffer[ValDef]
- def makeEvidenceParam(cxBound: Tree): ValDef = ???
- val tparams1 = tparams map {
- case tparam @ TypeDef(mods, name, ttparams, ContextBounds(tbounds, cxbounds)) =>
- for (cxbound <- cxbounds) {
- val accessMods = if (ofClass) PrivateOrLocal else EmptyFlags
- val epname = (nme.EVIDENCE_PARAM_PREFIX.toString + epbuf.length).toTermName
- epbuf +=
- ValDef(Modifiers(Implicit | Param | accessMods), epname, cxbound, EmptyTree())
- }
- tparam.derivedTypeDef(mods, name, ttparams, tbounds)
- case tparam =>
- tparam
- }
- val evidenceParams = epbuf.toList
- val vparamss1 = vparamss.reverse match {
- case (vparams @ (vparam :: _)) :: rvparamss if vparam.mods is Implicit =>
- ((vparams ++ evidenceParams) :: rvparamss).reverse
- case _ =>
- vparamss :+ evidenceParams
- }
- (tparams1, vparamss1)
- }
-
- def desugarContextBounds(tree: Tree): Tree = tree match {
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- val (tparams1, vparamss1) =
- desugarContextBounds(tparams, vparamss, ofClass = false)
- tree.derivedDefDef(mods, name, tparams1, vparamss, tpt, rhs)
- case ClassDef(
- mods, name, tparams, templ @ Template(constr, parents, self, body)) =>
- val (tparams1, vparamss1) =
- desugarContextBounds(tparams, constr.vparamss, ofClass = true)
- val constr1 = constr.derivedDefDef(
- constr.mods, constr.name, constr.tparams, vparamss1, constr.tpt, constr.rhs)
- val templ1 = templ.derivedTemplate(constr1, parents, self, body)
- tree.derivedClassDef(mods, name, tparams1, templ1)
- case _ => tree
- }
-
- def desugarAnonClass(templ: Template): Tree = {
- val x = tpnme.ANON_CLASS
- val clsDef = ClassDef(Modifiers(Final), x, Nil, templ)
- Block(clsDef, New(Ident(x), Nil))
- }
-
- def desugar(tree: Tree, mode: Mode.Value): Tree = {
- def isPatternVar(id: Ident) =
- mode == Mode.Pattern && isVarPattern(id) && id.name != nme.WILDCARD
- tree match { // todo: move general tree desugaring to typer, and keep only untyped trees here?
- case id @ Ident(_) if isPatternVar(id) =>
- Bind(id.name, Ident(nme.WILDCARD))
- case Typed(id @ Ident(_), tpt) if isPatternVar(id) =>
- Bind(id.name, Typed(Ident(nme.WILDCARD), tpt)).withPos(id.pos)
- case New(templ: Template) =>
- desugarAnonClass(templ)
- case Assign(Apply(fn, args), rhs) =>
- Apply(Select(fn, nme.update), args :+ rhs)
- case If(cond, thenp, EmptyTree()) =>
- If(cond, thenp, unitLiteral)
- case _: DefDef| _: ClassDef =>
- desugarContextBounds(tree)
- case ModuleDef(mods, name, tmpl @ Template(constr, parents, self, body)) =>
- // <module> val name: name$ = New(name$)
- // <module> final class name$ extends parents { self: name.type => body }
- val clsName = name.moduleClassName
- val clsRef = Ident(clsName)
- val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, clsRef)
- val clsSelf = self.derivedValDef(self.mods, self.name, SingletonTypeTree(Ident(name)), self.rhs)
- val clsTmpl = tmpl.derivedTemplate(constr, parents, clsSelf, body)
- val cls = ClassDef(mods & AccessFlags | ModuleClassCreationFlags, clsName, Nil, clsTmpl)
- TempTrees(List(modul, cls))
- case SymbolLit(str) =>
- New(ref(defn.SymbolClass.typeConstructor), Literal(Constant(str)) :: Nil)
- case InterpolatedString(id, strs, elems) =>
- Apply(Select(Apply(Ident(nme.StringContext), strs), id), elems)
- case Function(args, body) =>
- if (mode == Mode.Type) // FunctionN[args: _*, body]
- AppliedTypeTree(
- ref(defn.FunctionClass(args.length).typeConstructor),
- args :+ body)
- else { // { def $anonfun(args) = body; $anonfun }
- val params = args.asInstanceOf[List[ValDef]]
- Block(
- DefDef(Modifiers(Synthetic), nme.ANON_FUN, Nil, params :: Nil, EmptyTree(), body),
- Ident(nme.ANON_FUN)
- )
- }
- case InfixOp(l, op, r) =>
- mode match {
- case Mode.Expr => // l.op'(r), or val x = r; l.op;(x), plus handle named args specially
- makeBinop(l, op, r)
- case Mode.Pattern => // op'(l, r)
- Apply(Ident(op.encode), l :: r :: Nil)
- case Mode.Type => // op'[l, r]
- AppliedTypeTree(Ident(op.encode), l :: r :: Nil)
- }
- case PostfixOp(t, op) =>
- if (mode == Mode.Type && op == nme.raw.STAR)
- AppliedTypeTree(ref(defn.RepeatedParamType), t)
- else {
- assert(mode == Mode.Expr)
- if (op == nme.WILDCARD) tree // desugar later by eta expansion
- else Select(t, op.encode)
- }
- case PrefixOp(op, t) =>
- if (mode == Mode.Type && op == nme.ARROWkw)
- AppliedTypeTree(ref(defn.ByNameParamClass.typeConstructor), t)
- else
- Select(t, nme.UNARY_PREFIX ++ op.encode)
- case Parens(t) =>
- t
- case Tuple(ts) =>
- def PairTypeTree(l: Tree, r: Tree) =
- AppliedTypeTree(ref(defn.PairClass.typeConstructor), l :: r :: Nil)
- if (mode == Mode.Type) ts.reduceRight(PairTypeTree)
- else if (ts.isEmpty) unitLiteral
- else ts.reduceRight(Pair(_, _))
- case WhileDo(cond, body) =>
- // { <label> def while$(): Unit = if (cond) { body; while$() } ; while$() }
- val call = Apply(Ident(nme.WHILE_PREFIX), Nil)
- val rhs = If(cond, Block(body, call), unitLiteral)
- labelDefAndCall(nme.WHILE_PREFIX, rhs, call)
- case DoWhile(body, cond) =>
- // { label def doWhile$(): Unit = { body; if (cond) doWhile$() } ; doWhile$() }
- val call = Apply(Ident(nme.DO_WHILE_PREFIX), Nil)
- val rhs = Block(body, If(cond, call, unitLiteral))
- labelDefAndCall(nme.DO_WHILE_PREFIX, rhs, call)
- case ForDo(enums, body) =>
- makeFor(nme.foreach, nme.foreach, enums, body) orElse tree
- case ForYield(enums, body) =>
- makeFor(nme.map, nme.flatMap, enums, body) orElse tree
- case PatDef(mods, pats, tpt, rhs) =>
- val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
- combine(pats1 map (makePatDef(mods, _, rhs)))
- case _ =>
- tree
- }
- }.withPos(tree.pos)
- }
-
- def ugen(implicit ctx: Context) = new UGen
-
- /** If tree is a variable pattern, return its name and type, otherwise return None.
- */
- private object VarPattern {
- def unapply(tree: Tree): Option[VarInfo] = tree match {
- case id: Ident => Some(id, TypeTree())
- case Typed(id: Ident, tpt) => Some((id, tpt))
- case _ => None
- }
- }
-
- /** Traverse pattern and collect all variable names with their types in buffer.
- * Works for expanded as well as unexpanded patterns
- *
- */
- private object getVars extends TreeAccumulator[ListBuffer[VarInfo]] {
- override def apply(buf: ListBuffer[VarInfo], tree: Tree): ListBuffer[VarInfo] = {
- def seenName(name: Name) = buf exists (_._1.name == name)
- def add(named: NameTree, t: Tree): ListBuffer[VarInfo] =
- if (seenName(named.name)) buf else buf += ((named, t))
- tree match {
- case Bind(nme.WILDCARD, _) =>
- foldOver(buf, tree)
- case tree @ Bind(_, Typed(tree1, tpt)) if !mayBeTypePat(tpt) =>
- apply(add(tree, tpt), tree1)
- case tree @ Bind(_, tree1) =>
- apply(add(tree, TypeTree()), tree1)
- case Typed(id: Ident, t) if isVarPattern(id) =>
- add(id, t)
- case id: Ident if isVarPattern(id) =>
- add(id, TypeTree())
- case _ =>
- foldOver(buf, tree)
- }
- }
- }
-
- implicit class UntypedTreeDecorator(val self: Tree) extends AnyVal {
- def locateEnclosing(base: List[Tree], pos: Position): List[Tree] = {
- def encloses(elem: Any) = elem match {
- case t: Tree => t.envelope contains pos
- case _ => false
- }
- base.productIterator find encloses match {
- case Some(tree: Tree) => locateEnclosing(tree :: base, pos)
- case none => base
- }
- }
- }
-} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 02ee9d9cc..9586b9436 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -5,7 +5,7 @@ package pickling
import Contexts._, Symbols._, Types._, Names._, StdNames._, NameOps._, Scopes._, Decorators._
import SymDenotations._, UnPickler._, Constants._, Annotations._, util.Positions._
-import TypedTrees.tpd._
+import ast.TypedTrees.tpd._
import java.io.{ File, IOException }
import java.lang.Integer.toHexString
import scala.collection.{ mutable, immutable }
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 5083ccf52..42899ef44 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -9,7 +9,8 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
-import util.Positions._, TypedTrees.tpd._, TypedTrees.TreeOps
+import util.Positions._
+import ast.Trees, ast.TypedTrees.tpd._, ast.TypedTrees.TreeOps
import printing.Texts._
import printing.Printer
import io.AbstractFile
diff --git a/src/dotty/tools/dotc/parsing/MarkupParsers.scala b/src/dotty/tools/dotc/parsing/MarkupParsers.scala
index 1422c83b3..04694a61c 100644
--- a/src/dotty/tools/dotc/parsing/MarkupParsers.scala
+++ b/src/dotty/tools/dotc/parsing/MarkupParsers.scala
@@ -13,7 +13,7 @@ import scala.reflect.internal.Chars.{ SU, LF }
import Parsers._
import util.Positions._
import core._
-import Trees._
+import ast.Trees._
import Constants._
@@ -35,8 +35,7 @@ import Constants._
*/
object MarkupParsers {
- import UntypedTrees.{untpd, ugen}
- import untpd._
+ import ast.UntypedTrees.untpd._
case object MissingEndTagControl extends ControlThrowable {
override def getMessage = "start tag was here: "
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 91fd009f2..f31a93c24 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -12,7 +12,7 @@ import core._
import Flags._
import Contexts._
import Names._
-import Trees._
+import ast.Trees._, ast.TreeInfo
import Decorators._
import StdNames._
import util.Positions._
@@ -25,8 +25,7 @@ import annotation.switch
object Parsers {
- import UntypedTrees.{untpd, ugen}
- import untpd._
+ import ast.UntypedTrees.untpd._
case class OpInfo(operand: Tree, operator: Name, offset: Offset)
@@ -266,10 +265,10 @@ object Parsers {
def convertToParam(tree: Tree, mods: Modifiers = Modifiers(), expected: String = "formal parameter"): ValDef = tree match {
case Ident(name) =>
Parameter(name.asTermName, TypeTree(), mods) withPos tree.pos
- case Typed(Ident(name), tpt) if tpt.isType =>
+ case Typed(Ident(name), tpt) =>
Parameter(name.asTermName, tpt, mods) withPos tree.pos
case _ =>
- syntaxError(s"not a legal $expected", tree.pos)
+ syntaxError(s"not a legal $expected (${tree.getClass})", tree.pos)
Parameter(nme.ERROR, tree, mods)
}
@@ -286,7 +285,7 @@ object Parsers {
}
def emptyConstructor() = atPos(in.offset) {
- ugen.constructor(Modifiers(), Nil)
+ makeConstructor(Modifiers(), Nil)
}
/* -------------- XML ---------------------------------------------------- */
@@ -623,7 +622,7 @@ object Parsers {
for (t <- ts)
if (TreeInfo.isByNameParamType(t))
syntaxError("no by-name parameter type allowed here", t.pos)
- val tuple = atPos(start) { ugen.makeTupleOrParens(ts) }
+ val tuple = atPos(start) { makeTupleOrParens(ts) }
infixTypeRest(refinedTypeRest(withTypeRest(simpleTypeRest(tuple))))
}
}
@@ -679,7 +678,7 @@ object Parsers {
*/
def simpleType(): Tree = simpleTypeRest {
if (in.token == LPAREN)
- atPos(in.offset) { ugen.makeTupleOrParens(inParens(argTypes())) }
+ atPos(in.offset) { makeTupleOrParens(inParens(argTypes())) }
else if (in.token == LBRACE)
atPos(in.offset) { RefinedTypeTree(EmptyTree(), refinement()) }
else path(thisOK = false, handleSingletonType) match {
@@ -993,7 +992,7 @@ object Parsers {
case USCORE =>
wildcardIdent()
case LPAREN =>
- atPos(in.offset) { ugen.makeTupleOrParens(inParens(exprsInParensOpt())) }
+ atPos(in.offset) { makeTupleOrParens(inParens(exprsInParensOpt())) }
case LBRACE =>
canApply = false
blockExpr()
@@ -1134,7 +1133,7 @@ object Parsers {
wrappedEnums = false
accept(RPAREN)
openParens.change(LPAREN, -1)
- atPos(lparenOffset) { ugen.makeTupleOrParens(pats) } // note: alternatives `|' need to be weeded out by typer.
+ atPos(lparenOffset) { makeTupleOrParens(pats) } // note: alternatives `|' need to be weeded out by typer.
}
else pats.head
val res = generatorRest(pat) :: enumeratorsRest()
@@ -1230,7 +1229,7 @@ object Parsers {
case USCORE =>
wildcardIdent()
case LPAREN =>
- atPos(in.offset) { ugen.makeTupleOrParens(inParens(patternsOpt())) }
+ atPos(in.offset) { makeTupleOrParens(inParens(patternsOpt())) }
case LBRACE =>
dotSelectors(blockExpr())
case XMLSTART =>
@@ -1639,7 +1638,7 @@ object Parsers {
accept(EQUALS)
atPos(in.offset) { constrExpr() }
}
- ugen.constructor(mods, vparamss, rhs)
+ makeConstructor(mods, vparamss, rhs)
} else {
val name = ident()
val tparams = typeParamClauseOpt(ParamOwner.Def)
@@ -1649,7 +1648,7 @@ object Parsers {
val rhs =
if (isStatSep || in.token == RBRACE) EmptyTree()
else if (restype.isEmpty && in.token == LBRACE) {
- restype = atPos(in.offset) { ugen.scalaUnitConstr }
+ restype = atPos(in.offset) { scalaUnit }
blockExpr()
} else {
equalsExpr()
@@ -1734,7 +1733,7 @@ object Parsers {
val constr = atPos(in.offset) {
val cmods = constrModsOpt()
val vparamss = paramClauses(name, mods is Case)
- ugen.constructor(cmods, vparamss)
+ makeConstructor(cmods, vparamss)
}
val templ = templateOpt(constr)
ClassDef(mods, name, tparams, templ)
@@ -1871,10 +1870,10 @@ object Parsers {
if (in.token == ARROW) {
first match {
case Typed(tree @ This(tpnme.EMPTY), tpt) =>
- self = ugen.selfDef(nme.WILDCARD, tpt).withPos(first.pos)
+ self = makeSelfDef(nme.WILDCARD, tpt).withPos(first.pos)
case _ =>
val ValDef(_, name, tpt, _) = convertToParam(first, expected = "self type clause")
- self = ugen.selfDef(name, tpt).withPos(first.pos)
+ self = makeSelfDef(name, tpt).withPos(first.pos)
}
in.nextToken()
} else {
diff --git a/src/dotty/tools/dotc/parsing/ScriptParsers.scala b/src/dotty/tools/dotc/parsing/ScriptParsers.scala
index daf8dc9e2..2aab98eaa 100644
--- a/src/dotty/tools/dotc/parsing/ScriptParsers.scala
+++ b/src/dotty/tools/dotc/parsing/ScriptParsers.scala
@@ -7,7 +7,7 @@ import core._
import Flags._
import Contexts._
import Names._
-import Trees._
+import ast.Trees._
import Decorators._
import StdNames._
import util.Chars.isScalaLetter
@@ -57,8 +57,7 @@ import Parsers._
*/
object ScriptParsers {
- import UntypedTrees.{untpd, ugen}
- import untpd._
+ import ast.UntypedTrees.untpd._
class ScriptParser(source: SourceFile)(implicit ctx: Context) extends Parser(source) {
diff --git a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
index e59e7975f..a712a437c 100644
--- a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
+++ b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
@@ -7,7 +7,7 @@ import scala.xml.{ EntityRef, Text }
import scala.xml.XML.{ xmlns }
import core._
import Flags.Mutable
-import Names._, NameOps._, StdNames._, Decorators._, Trees._, TypedTrees._, UntypedTrees._, Constants._
+import Names._, NameOps._, StdNames._, Decorators._, ast.Trees._, ast.TypedTrees._, ast.UntypedTrees._, Constants._
import Symbols._, Contexts._
import util.Positions._
import Parsers.Parser
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 274f78bee..a133d25da 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -2,10 +2,10 @@ package dotty.tools.dotc
package printing
import core._
-import Texts._, Trees._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._
+import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation
import StdNames.nme
-import UntypedTrees.untpd
+import ast.Trees._, ast.UntypedTrees.untpd
import java.lang.Integer.toOctalString
import scala.annotation.switch
diff --git a/src/dotty/tools/dotc/printing/Printer.scala b/src/dotty/tools/dotc/printing/Printer.scala
index 9ba3141f8..6944c4ae2 100644
--- a/src/dotty/tools/dotc/printing/Printer.scala
+++ b/src/dotty/tools/dotc/printing/Printer.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package printing
import core._
-import Texts._, Trees._
+import Texts._, ast.Trees._
import Types.Type, Symbols.Symbol, Contexts.Context, Scopes.Scope, Constants.Constant,
Names.Name, Denotations.Denotation, Annotations.Annotation
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 32f5f2d2f..c24d3a800 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -2,10 +2,11 @@ package dotty.tools.dotc
package printing
import core._
-import Texts._, Trees._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._
+import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation
import StdNames.nme
-import UntypedTrees.untpd
+import ast.Trees._
+import ast.UntypedTrees.untpd
import scala.annotation.switch
class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {