aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-02 11:08:28 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:07 +0100
commit8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch)
treea8147561d307af862c295cfc8100d271063bb0dd /compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled
parent6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff)
downloaddotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled258
1 files changed, 258 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled b/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled
new file mode 100644
index 000000000..255619f35
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/ast/CheckTrees.scala.disabled
@@ -0,0 +1,258 @@
+package dotty.tools
+package dotc
+package ast
+
+import core._
+import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
+import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
+
+// TODO: revise, integrate in a checking phase.
+object CheckTrees {
+
+ import tpd._
+
+ def check(p: Boolean, msg: => String = "")(implicit ctx: Context): Unit = assert(p, msg)
+
+ def checkTypeArg(arg: Tree, bounds: TypeBounds)(implicit ctx: Context): Unit = {
+ check(arg.isValueType)
+ check(bounds contains arg.tpe)
+ }
+
+ def escapingRefs(block: Block)(implicit ctx: Context): collection.Set[NamedType] = {
+ var hoisted: Set[Symbol] = Set()
+ lazy val locals = ctx.typeAssigner.localSyms(block.stats).toSet
+ def isLocal(sym: Symbol): Boolean =
+ (locals contains sym) && !isHoistableClass(sym)
+ def isHoistableClass(sym: Symbol) =
+ sym.isClass && {
+ (hoisted contains sym) || {
+ hoisted += sym
+ !classLeaks(sym.asClass)
+ }
+ }
+ def leakingTypes(tp: Type): collection.Set[NamedType] =
+ tp namedPartsWith (tp => isLocal(tp.symbol))
+ def typeLeaks(tp: Type): Boolean = leakingTypes(tp).nonEmpty
+ def classLeaks(sym: ClassSymbol): Boolean =
+ (ctx.owner is Method) || // can't hoist classes out of method bodies
+ (sym.info.parents exists typeLeaks) ||
+ (sym.decls.toList exists (t => typeLeaks(t.info)))
+ leakingTypes(block.tpe)
+ }
+
+ def checkType(tree: 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: Tree, name: Name, formal: Type): Unit = {
+ arg match {
+ case NamedArg(argName, _) =>
+ check(argName == name)
+ 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.translateParameterized(defn.RepeatedParamClass, defn.SeqClass))
+ }
+ 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 tree @ Block(stats, expr) =>
+ check(expr.isValue)
+ check(escapingRefs(tree).isEmpty)
+ case If(cond, thenp, elsep) =>
+ check(cond.isValue); check(thenp.isValue); check(elsep.isValue)
+ check(cond.tpe isRef defn.BooleanClass)
+ case Closure(env, meth, target) =>
+ meth.tpe.widen match {
+ case mt @ MethodType(_, paramTypes) =>
+ if (target.isEmpty) {
+ check(env.length < paramTypes.length)
+ for ((arg, formal) <- env zip paramTypes)
+ check(arg.tpe <:< formal)
+ }
+ else
+ // env is stored in class, not method
+ target.tpe match {
+ case SAMType(targetMeth) =>
+ check(mt <:< targetMeth.info)
+ }
+ }
+ 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.isRealMethod)
+ case Try(block, handler, finalizer) =>
+ check(block.isTerm)
+ check(finalizer.isTerm)
+ check(handler.isTerm)
+ check(handler.tpe derivesFrom defn.FunctionClass(1))
+ check(handler.tpe.baseArgInfos(defn.FunctionClass(1)).head <:< defn.ThrowableType)
+ case Throw(expr) =>
+ check(expr.isValue)
+ check(expr.tpe.derivesFrom(defn.ThrowableClass))
+ case SeqLiteral(elems) =>
+ val elemtp = tree.tpe.elemType
+ for (elem <- elems) {
+ check(elem.isValue)
+ check(elem.tpe <:< elemtp)
+ }
+ 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[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(ctx.typeAssigner.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, implicits, args) => // todo: review
+ 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.isInstanceOf[SeqLiteral])
+ case nme.unapply =>
+ val rtp = funtpe.resultType
+ if (rtp isRef defn.BooleanClass)
+ check(args.isEmpty)
+ else {
+ check(rtp isRef defn.OptionClass)
+ val normArgs = rtp.argTypesHi match {
+ case optionArg :: Nil =>
+ optionArg.argTypesHi match {
+ case Nil =>
+ optionArg :: Nil
+ case tupleArgs if defn.isTupleType(optionArg) =>
+ 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.isInstanceOf[Template] || tpt.tpe.isInstanceOf[TypeBounds])
+ case Template(constr, parents, selfType, body) =>
+ 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 EmptyTree =>
+ }
+}
+