From 8a61ff432543a29234193cd1f7c14abd3f3d31a0 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 2 Nov 2016 11:08:28 +0100 Subject: Move compiler and compiler tests to compiler dir --- .../dotty/tools/dotc/parsing/DeSugarTest.scala | 96 ++++ .../dotty/tools/dotc/parsing/DocstringTest.scala | 34 ++ .../dotty/tools/dotc/parsing/DocstringTests.scala | 491 +++++++++++++++++++++ .../tools/dotc/parsing/ModifiersParsingTest.scala | 164 +++++++ .../test/dotty/tools/dotc/parsing/ParserTest.scala | 44 ++ .../dotty/tools/dotc/parsing/ScannerTest.scala | 65 +++ .../dotty/tools/dotc/parsing/desugarPackage.scala | 28 ++ .../test/dotty/tools/dotc/parsing/parseFile.scala | 13 + .../dotty/tools/dotc/parsing/parsePackage.scala | 83 ++++ .../test/dotty/tools/dotc/parsing/showTree.scala | 26 ++ 10 files changed, 1044 insertions(+) create mode 100644 compiler/test/dotty/tools/dotc/parsing/DeSugarTest.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/DocstringTest.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/DocstringTests.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/ParserTest.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/desugarPackage.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/parseFile.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/parsePackage.scala create mode 100644 compiler/test/dotty/tools/dotc/parsing/showTree.scala (limited to 'compiler/test/dotty/tools/dotc/parsing') diff --git a/compiler/test/dotty/tools/dotc/parsing/DeSugarTest.scala b/compiler/test/dotty/tools/dotc/parsing/DeSugarTest.scala new file mode 100644 index 000000000..1f79c2cf6 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/DeSugarTest.scala @@ -0,0 +1,96 @@ +package dotty.tools +package dotc +package parsing + +import Tokens._, Parsers._ +import scala.reflect.io._ +import util._ +import core._ +import ast.Trees._ +import ast.desugar +import ast.desugar._ +import core.Mode +import Contexts.Context + +import scala.collection.mutable.ListBuffer + +class DeSugarTest extends ParserTest { + + import dotty.tools.dotc.ast.untpd._ + + import Mode._ + + val Expr = Mode(0) + + object DeSugar extends UntypedTreeMap { + var curMode: Mode = Expr + def withMode[T](mode: Mode)(op: => T) = { + val saved = curMode + curMode = mode + try op + finally curMode = saved + } + + def transform(tree: Tree, mode: Mode)(implicit ctx: Context): Tree = withMode(mode) { transform(tree) } + def transform(trees: List[Tree], mode: Mode)(implicit ctx: Context): List[Tree] = withMode(mode) { transform(trees) } + + override def transform(tree: Tree)(implicit ctx: Context): Tree = { + val tree1 = desugar(tree)(ctx.withModeBits(curMode)) + tree1 match { + case TypedSplice(t) => + tree1 + case PostfixOp(od, op) => + PostfixOp(transform(od), op) + case Select(qual, name) => + cpy.Select(tree1)(transform(qual, Expr), name) + case Apply(fn, args) => + cpy.Apply(tree1)(transform(fn, Expr), transform(args)) + case TypeApply(fn, args) => + cpy.TypeApply(tree1)(transform(fn, Expr), transform(args, Type)) + case New(tpt) => + cpy.New(tree1)(transform(tpt, Type)) + case Typed(expr, tpt) => + cpy.Typed(tree1)(transform(expr), transform(tpt, Type)) + case CaseDef(pat, guard, body) => + cpy.CaseDef(tree1)(transform(pat, Pattern), transform(guard), transform(body)) + case SeqLiteral(elems, elemtpt) => + cpy.SeqLiteral(tree1)(transform(elems), transform(elemtpt)) + case UnApply(fun, implicits, patterns) => + cpy.UnApply(tree1)(transform(fun, Expr), transform(implicits), transform(patterns)) + case tree1 @ ValDef(name, tpt, _) => + cpy.ValDef(tree1)(name, transform(tpt, Type), transform(tree1.rhs)) + case tree1 @ DefDef(name, tparams, vparamss, tpt, _) => + cpy.DefDef(tree1)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt, Type), transform(tree1.rhs)) + case tree1 @ TypeDef(name, rhs) => + cpy.TypeDef(tree1)(name, transform(rhs, Type)) + case impl @ Template(constr, parents, self, _) => + cpy.Template(tree1)(transformSub(constr), transform(parents), transformSub(self), transform(impl.body, Expr)) + case Thicket(trees) => + Thicket(flatten(trees mapConserve super.transform)) + case tree1 => + super.transform(tree1) + } + } + } + + def firstClass(stats: List[Tree]): String = stats match { + case Nil => "" + case TypeDef(name, _) :: _ => name.toString + case ModuleDef(name, _) :: _ => name.toString + case (pdef: PackageDef) :: _ => firstClass(pdef) + case stat :: stats => firstClass(stats) + } + + def firstClass(tree: Tree): String = tree match { + case PackageDef(pid, stats) => + pid.show + "." + firstClass(stats) + case _ => "??? " + tree.getClass + } + + def desugarTree(tree: Tree): Tree = { + //println("***** desugaring " + firstClass(tree)) + DeSugar.transform(tree) + } + + def desugarAll() = parsedTrees foreach (desugarTree(_).show) +} diff --git a/compiler/test/dotty/tools/dotc/parsing/DocstringTest.scala b/compiler/test/dotty/tools/dotc/parsing/DocstringTest.scala new file mode 100644 index 000000000..30e885f70 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/DocstringTest.scala @@ -0,0 +1,34 @@ +package dotty.tools +package dotc +package parsing + +import ast.Trees._ +import core.Contexts.Context + +trait DocstringTest extends DottyTest { + ctx = ctx.fresh.setSetting(ctx.settings.YkeepComments, true) + + def checkDocString(actual: Option[String], expected: String): Unit = actual match { + case Some(str) => + assert(str == expected, s"""Docstring: "$str" didn't match expected "$expected"""") + case None => + assert(false, s"""No docstring found, expected: "$expected"""") + } + + def expectNoDocString(doc: Option[String]): Unit = + doc.fold(()) { d => assert(false, s"""Expected not to find a docstring, but found: "$d"""") } + + def defaultAssertion: PartialFunction[Any, Unit] = { + case t: Tree[Untyped] => + assert(false, s"Couldn't match resulting AST to expected AST in: ${t.show}") + case x => + assert(false, s"Couldn't match resulting AST to expected AST in: $x") + } + + def checkFrontend(source: String)(docAssert: PartialFunction[Tree[Untyped], Unit]) = { + checkCompile("frontend", source) { (_, ctx) => + implicit val c = ctx + (docAssert orElse defaultAssertion)(ctx.compilationUnit.untpdTree) + } + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/DocstringTests.scala b/compiler/test/dotty/tools/dotc/parsing/DocstringTests.scala new file mode 100644 index 000000000..930ec117a --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/DocstringTests.scala @@ -0,0 +1,491 @@ +package dotty.tools +package dotc +package parsing + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.ast.Trees._ + +import org.junit.Assert._ +import org.junit.Test + +class DocstringTests extends DocstringTest { + + @Test def noComment = { + import dotty.tools.dotc.ast.untpd._ + val source = "class Class" + + checkFrontend(source) { + case PackageDef(_, Seq(c: TypeDef)) => + assert(c.rawComment.map(_.raw) == None, "Should not have a comment, mainly used for exhaustive tests") + } + } + + @Test def singleClassInPackage = { + val source = + """ + |package a + | + |/** Hello world! */ + |class Class(val x: String) + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" => + checkDocString(t.rawComment.map(_.raw), "/** Hello world! */") + } + } + + @Test def multipleOpenedOnSingleClassInPackage = { + val source = + """ + |package a + | + |/** Hello /* multiple open */ world! */ + |class Class(val x: String) + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(t @ TypeDef(name, _))) if name.toString == "Class" => + checkDocString(t.rawComment.map(_.raw), "/** Hello /* multiple open */ world! */") + } + } + @Test def multipleClassesInPackage = { + val source = + """ + |package a + | + |/** Class1 docstring */ + |class Class1(val x: String) + | + |/** Class2 docstring */ + |class Class2(val x: String) + """.stripMargin + + checkCompile("frontend", source) { (_, ctx) => + ctx.compilationUnit.untpdTree match { + case PackageDef(_, Seq(c1 @ TypeDef(_,_), c2 @ TypeDef(_,_))) => { + checkDocString(c1.rawComment.map(_.raw), "/** Class1 docstring */") + checkDocString(c2.rawComment.map(_.raw), "/** Class2 docstring */") + } + } + } + } + + @Test def singleCaseClassWithoutPackage = { + val source = + """ + |/** Class without package */ + |case class Class(val x: Int) + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment.map(_.raw), "/** Class without package */") + } + } + + @Test def SingleTraitWihoutPackage = { + val source = "/** Trait docstring */\ntrait Trait" + + checkFrontend(source) { + case PackageDef(_, Seq(t @ TypeDef(_,_))) => checkDocString(t.rawComment.map(_.raw), "/** Trait docstring */") + } + } + + @Test def multipleTraitsWithoutPackage = { + val source = + """ + |/** Trait1 docstring */ + |trait Trait1 + | + |/** Trait2 docstring */ + |trait Trait2 + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(t1 @ TypeDef(_,_), t2 @ TypeDef(_,_))) => { + checkDocString(t1.rawComment.map(_.raw), "/** Trait1 docstring */") + checkDocString(t2.rawComment.map(_.raw), "/** Trait2 docstring */") + } + } + } + + @Test def multipleMixedEntitiesWithPackage = { + val source = + """ + |/** Trait1 docstring */ + |trait Trait1 + | + |/** Class2 docstring */ + |class Class2(val x: Int) + | + |/** CaseClass3 docstring */ + |case class CaseClass3() + | + |case class NoComment() + | + |/** AbstractClass4 docstring */ + |abstract class AbstractClass4(val x: Int) + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(t1 @ TypeDef(_,_), c2 @ TypeDef(_,_), cc3 @ TypeDef(_,_), _, ac4 @ TypeDef(_,_))) => { + checkDocString(t1.rawComment.map(_.raw), "/** Trait1 docstring */") + checkDocString(c2.rawComment.map(_.raw), "/** Class2 docstring */") + checkDocString(cc3.rawComment.map(_.raw), "/** CaseClass3 docstring */") + checkDocString(ac4.rawComment.map(_.raw), "/** AbstractClass4 docstring */") + } + } + } + + @Test def nestedClass = { + val source = + """ + |/** Outer docstring */ + |class Outer { + | /** Inner docstring */ + | class Inner(val x: Int) + |} + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(outer @ TypeDef(_, tpl @ Template(_,_,_,_)))) => { + checkDocString(outer.rawComment.map(_.raw), "/** Outer docstring */") + tpl.body match { + case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.raw), "/** Inner docstring */") + case _ => assert(false, "Couldn't find inner class") + } + } + } + } + + @Test def nestedClassThenOuter = { + val source = + """ + |/** Outer1 docstring */ + |class Outer1 { + | /** Inner docstring */ + | class Inner(val x: Int) + |} + | + |/** Outer2 docstring */ + |class Outer2 + """.stripMargin + + checkFrontend(source) { + case PackageDef(_, Seq(o1 @ TypeDef(_, tpl @ Template(_,_,_,_)), o2 @ TypeDef(_,_))) => { + checkDocString(o1.rawComment.map(_.raw), "/** Outer1 docstring */") + checkDocString(o2.rawComment.map(_.raw), "/** Outer2 docstring */") + tpl.body match { + case (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.raw), "/** Inner docstring */") + case _ => assert(false, "Couldn't find inner class") + } + } + } + } + + @Test def objects = { + val source = + """ + |package p + | + |/** Object1 docstring */ + |object Object1 + | + |/** Object2 docstring */ + |object Object2 + """.stripMargin + + checkFrontend(source) { + case p @ PackageDef(_, Seq(o1: MemberDef[Untyped], o2: MemberDef[Untyped])) => { + assertEquals(o1.name.toString, "Object1") + checkDocString(o1.rawComment.map(_.raw), "/** Object1 docstring */") + assertEquals(o2.name.toString, "Object2") + checkDocString(o2.rawComment.map(_.raw), "/** Object2 docstring */") + } + } + } + + @Test def objectsNestedClass = { + val source = + """ + |package p + | + |/** Object1 docstring */ + |object Object1 + | + |/** Object2 docstring */ + |object Object2 { + | class A1 + | /** Inner docstring */ + | class Inner + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case p @ PackageDef(_, Seq(o1: ModuleDef, o2: ModuleDef)) => { + assert(o1.name.toString == "Object1") + checkDocString(o1.rawComment.map(_.raw), "/** Object1 docstring */") + assert(o2.name.toString == "Object2") + checkDocString(o2.rawComment.map(_.raw), "/** Object2 docstring */") + + o2.impl.body match { + case _ :: (inner @ TypeDef(_,_)) :: _ => checkDocString(inner.rawComment.map(_.raw), "/** Inner docstring */") + case _ => assert(false, "Couldn't find inner class") + } + } + } + } + + @Test def packageObject = { + val source = + """ + |/** Package object docstring */ + |package object foo { + | /** Boo docstring */ + | case class Boo() + | + | /** Trait docstring */ + | trait Trait + | + | /** InnerObject docstring */ + | object InnerObject { + | /** InnerClass docstring */ + | class InnerClass + | } + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(p: ModuleDef)) => { + checkDocString(p.rawComment.map(_.raw), "/** Package object docstring */") + + p.impl.body match { + case (b: TypeDef) :: (t: TypeDef) :: (o: ModuleDef) :: Nil => { + checkDocString(b.rawComment.map(_.raw), "/** Boo docstring */") + checkDocString(t.rawComment.map(_.raw), "/** Trait docstring */") + checkDocString(o.rawComment.map(_.raw), "/** InnerObject docstring */") + checkDocString(o.impl.body.head.asInstanceOf[TypeDef].rawComment.map(_.raw), "/** InnerClass docstring */") + } + case _ => assert(false, "Incorrect structure inside package object") + } + } + } + } + + @Test def multipleDocStringsBeforeEntity = { + val source = + """ + |/** First comment */ + |/** Second comment */ + |/** Real comment */ + |class Class + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(c: TypeDef)) => + checkDocString(c.rawComment.map(_.raw), "/** Real comment */") + } + } + + @Test def multipleDocStringsBeforeAndAfter = { + val source = + """ + |/** First comment */ + |/** Second comment */ + |/** Real comment */ + |class Class + |/** Following comment 1 */ + |/** Following comment 2 */ + |/** Following comment 3 */ + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(c: TypeDef)) => + checkDocString(c.rawComment.map(_.raw), "/** Real comment */") + } + } + + @Test def valuesWithDocString = { + val source = + """ + |object Object { + | /** val1 */ + | val val1 = 1 + | + | /** val2 */ + | val val2: Int = 2 + | /** bogus docstring */ + | + | /** bogus docstring */ + | /** val3 */ + | val val3: List[Int] = 1 :: 2 :: 3 :: Nil + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(o: ModuleDef)) => { + o.impl.body match { + case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { + checkDocString(v1.rawComment.map(_.raw), "/** val1 */") + checkDocString(v2.rawComment.map(_.raw), "/** val2 */") + checkDocString(v3.rawComment.map(_.raw), "/** val3 */") + } + case _ => assert(false, "Incorrect structure inside object") + } + } + } + } + + @Test def varsWithDocString = { + val source = + """ + |object Object { + | /** var1 */ + | var var1 = 1 + | + | /** var2 */ + | var var2: Int = 2 + | /** bogus docstring */ + | + | /** bogus docstring */ + | /** var3 */ + | var var3: List[Int] = 1 :: 2 :: 3 :: Nil + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(o: ModuleDef)) => { + o.impl.body match { + case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { + checkDocString(v1.rawComment.map(_.raw), "/** var1 */") + checkDocString(v2.rawComment.map(_.raw), "/** var2 */") + checkDocString(v3.rawComment.map(_.raw), "/** var3 */") + } + case _ => assert(false, "Incorrect structure inside object") + } + } + } + } + + @Test def defsWithDocString = { + val source = + """ + |object Object { + | /** def1 */ + | def def1 = 1 + | + | /** def2 */ + | def def2: Int = 2 + | /** bogus docstring */ + | + | /** bogus docstring */ + | /** def3 */ + | def def3: List[Int] = 1 :: 2 :: 3 :: Nil + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(o: ModuleDef)) => { + o.impl.body match { + case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { + checkDocString(v1.rawComment.map(_.raw), "/** def1 */") + checkDocString(v2.rawComment.map(_.raw), "/** def2 */") + checkDocString(v3.rawComment.map(_.raw), "/** def3 */") + } + case _ => assert(false, "Incorrect structure inside object") + } + } + } + } + + @Test def typesWithDocString = { + val source = + """ + |object Object { + | /** type1 */ + | type T1 = Int + | + | /** type2 */ + | type T2 = String + | /** bogus docstring */ + | + | /** bogus docstring */ + | /** type3 */ + | type T3 = T2 + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(o: ModuleDef)) => { + o.impl.body match { + case (v1: MemberDef) :: (v2: MemberDef) :: (v3: MemberDef) :: Nil => { + checkDocString(v1.rawComment.map(_.raw), "/** type1 */") + checkDocString(v2.rawComment.map(_.raw), "/** type2 */") + checkDocString(v3.rawComment.map(_.raw), "/** type3 */") + } + case _ => assert(false, "Incorrect structure inside object") + } + } + } + } + + @Test def defInnerClass = { + val source = + """ + |object Foo { + | def foo() = { + | /** Innermost */ + | class Innermost + | } + |} + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case PackageDef(_, Seq(o: ModuleDef)) => + o.impl.body match { + case (foo: MemberDef) :: Nil => + expectNoDocString(foo.rawComment.map(_.raw)) + case _ => assert(false, "Incorrect structure inside object") + } + } + } + + @Test def withExtends = { + val source = + """ + |trait Trait1 + |/** Class1 */ + |class Class1 extends Trait1 + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case p @ PackageDef(_, Seq(_, c: TypeDef)) => + checkDocString(c.rawComment.map(_.raw), "/** Class1 */") + } + } + + @Test def withAnnotation = { + val source = + """ + |/** Class1 */ + |@SerialVersionUID(1) + |class Class1 + """.stripMargin + + import dotty.tools.dotc.ast.untpd._ + checkFrontend(source) { + case p @ PackageDef(_, Seq(c: TypeDef)) => + checkDocString(c.rawComment.map(_.raw), "/** Class1 */") + } + } +} /* End class */ diff --git a/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala b/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala new file mode 100644 index 000000000..e31ef2160 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/ModifiersParsingTest.scala @@ -0,0 +1,164 @@ +package dotty.tools +package dotc +package parsing + +import org.junit.Test +import org.junit.Assert._ + +import ast.untpd.modsDeco +import ast.untpd._ +import ast.{ Trees => d } +import Parsers.Parser +import util.SourceFile +import core.Contexts.ContextBase +import core.Flags + +object ModifiersParsingTest { + implicit val ctx = (new ContextBase).initialCtx + + implicit def parse(code: String): Tree = { + val (_, stats) = new Parser(new SourceFile("", code.toCharArray)).templateStatSeq() + stats match { case List(stat) => stat; case stats => Thicket(stats) } + } + + implicit class TreeDeco(val code: Tree) extends AnyVal { + def firstConstrValDef: ValDef = code match { + case d.TypeDef(_, d.Template(constr, _, _, _)) => + constr.vparamss.head.head + } + + def firstTypeParam: TypeDef = code match { + case d.TypeDef(_, d.Template(constr, _, _, _)) => + constr.tparams.head + } + + def defParam(i: Int): ValDef = code match { + case d.DefDef(_, _, vparamss, _, _) => + vparamss.head.toArray.apply(i) + } + + def defParam(i: Int, j: Int): ValDef = code match { + case d.DefDef(_, _, vparamss, _, _) => + vparamss.toArray.apply(i).toArray.apply(j) + } + + def funParam(i: Int): Tree = code match { + case Function(params, _) => + params.toArray.apply(i) + } + + def field(i: Int): Tree = code match { + case d.TypeDef(_, t: Template) => + t.body.toArray.apply(i) + } + + def field(name: String): Tree = code match { + case d.TypeDef(_, t: Template) => + t.body.find({ + case m: MemberDef => m.name.show == name + case _ => false + }).get + } + + def stat(i: Int): Tree = code match { + case d.Block(stats, expr) => + if (i < stats.length) stats.toArray.apply(i) + else expr + } + + def modifiers: List[Mod] = code match { + case t: MemberDef => t.mods.mods + } + } +} + + +class ModifiersParsingTest { + import ModifiersParsingTest._ + + + @Test def valDef = { + var source: Tree = "class A(var a: Int)" + assert(source.firstConstrValDef.modifiers == List(Mod.Var())) + + source = "class A(val a: Int)" + assert(source.firstConstrValDef.modifiers == List(Mod.Val())) + + source = "class A(private val a: Int)" + assert(source.firstConstrValDef.modifiers == List(Mod.Private(), Mod.Val())) + + source = "class A(protected var a: Int)" + assert(source.firstConstrValDef.modifiers == List(Mod.Protected(), Mod.Var())) + + source = "class A(protected implicit val a: Int)" + assert(source.firstConstrValDef.modifiers == List(Mod.Protected(), Mod.Implicit(), Mod.Val())) + + source = "class A[T]" + assert(source.firstTypeParam.modifiers == List()) + + source = "class A[type T]" + assert(source.firstTypeParam.modifiers == List(Mod.Type())) + } + + @Test def typeDef = { + var source: Tree = "class A" + assert(source.modifiers == List()) + + source = "sealed class A" + assert(source.modifiers == List(Mod.Sealed())) + + source = "implicit class A" + assert(source.modifiers == List(Mod.Implicit())) + + source = "abstract sealed class A" + assert(source.modifiers == List(Mod.Abstract(), Mod.Sealed())) + } + + @Test def fieldDef = { + val source: Tree = + """ + | class A { + | lazy var a = ??? + | lazy private val b = ??? + | final val c = ??? + | + | abstract override def f: Boolean + | inline def g(n: Int) = ??? + | } + """.stripMargin + + assert(source.field("a").modifiers == List(Mod.Lazy(), Mod.Var())) + assert(source.field("b").modifiers == List(Mod.Lazy(), Mod.Private(), Mod.Val())) + assert(source.field("c").modifiers == List(Mod.Final(), Mod.Val())) + assert(source.field("f").modifiers == List(Mod.Abstract(), Mod.Override())) + assert(source.field("g").modifiers == List(Mod.Inline())) + } + + @Test def paramDef = { + var source: Tree = "def f(inline a: Int) = ???" + assert(source.defParam(0).modifiers == List(Mod.Inline())) + + source = "def f(implicit a: Int, b: Int) = ???" + println(source.defParam(0).modifiers) + assert(source.defParam(0).modifiers == List(Mod.Implicit(Flags.Implicit))) + assert(source.defParam(1).modifiers == List(Mod.Implicit(Flags.Implicit))) + + source = "def f(x: Int, y: Int)(implicit a: Int, b: Int) = ???" + assert(source.defParam(0, 0).modifiers == List()) + assert(source.defParam(1, 0).modifiers == List(Mod.Implicit(Flags.Implicit))) + } + + @Test def blockDef = { + var source: Tree = "implicit val x : A = ???" + assert(source.modifiers == List(Mod.Implicit(), Mod.Val())) + + source = "implicit var x : A = ???" + assert(source.modifiers == List(Mod.Implicit(), Mod.Var())) + + source = "{ implicit var x : A = ??? }" + assert(source.stat(0).modifiers == List(Mod.Implicit(), Mod.Var())) + + source = "{ implicit x => x * x }" + assert(source.stat(0).funParam(0).modifiers == List(Mod.Implicit())) + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala b/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala new file mode 100644 index 000000000..a89b34512 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/ParserTest.scala @@ -0,0 +1,44 @@ +package dotty.tools +package dotc +package parsing + +import scala.reflect.io._ +import util._ +import core._ +import scala.io.Codec +import Tokens._, Parsers._ +import ast.untpd._ +import org.junit.Test +import scala.collection.mutable.ListBuffer + +class ParserTest extends DottyTest { + + def parse(name: String): Tree = parse(new PlainFile(name)) + + var parsed = 0 + val parsedTrees = new ListBuffer[Tree] + + def reset() = { + parsed = 0 + parsedTrees.clear() + } + + def parse(file: PlainFile): Tree = { + //println("***** parsing " + file) + val source = new SourceFile(file, Codec.UTF8) + val parser = new Parser(source) + val tree = parser.parse() + parsed += 1 + parsedTrees += tree + tree + } + + def parseDir(path: String): Unit = parseDir(Directory(path)) + + def parseDir(dir: Directory): Unit = { + for (f <- dir.files) + if (f.name.endsWith(".scala")) parse(new PlainFile(f)) + for (d <- dir.dirs) + parseDir(d.path) + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala b/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala new file mode 100644 index 000000000..b024a63db --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/ScannerTest.scala @@ -0,0 +1,65 @@ +package dotty.tools +package dotc +package parsing + +import scala.reflect.io._ +import scala.io.Codec +import util._ +import Tokens._, Scanners._ +import org.junit.Test + +class ScannerTest extends DottyTest { + + val blackList = List( + "/scaladoc/scala/tools/nsc/doc/html/page/Index.scala", + "/scaladoc/scala/tools/nsc/doc/html/page/Template.scala" + ) + + def scan(name: String): Unit = scan(new PlainFile(name)) + + def scan(file: PlainFile): Unit = { + //println("***** scanning " + file) + val source = new SourceFile(file, Codec.UTF8) + val scanner = new Scanner(source) + var i = 0 + while (scanner.token != EOF) { +// print("[" + scanner.token.show +"]") + scanner.nextToken +// i += 1 +// if (i % 10 == 0) println() + } + } + + def scanDir(path: String): Unit = scanDir(Directory(path)) + + def scanDir(dir: Directory): Unit = { + if (blackList exists (dir.jfile.toString endsWith _)) + println(s"blacklisted package: ${dir.jfile.getAbsolutePath}") + else + for (f <- dir.files) + if (f.name.endsWith(".scala")) + if (blackList exists (f.jfile.toString endsWith _)) + println(s"blacklisted file: ${f.jfile.getAbsolutePath}") + else + scan(new PlainFile(f)) + for (d <- dir.dirs) + scanDir(d.path) + } + + @Test + def scanList() = { + println(System.getProperty("user.dir")) + scan("./src/dotty/tools/dotc/core/Symbols.scala") + scan("./src/dotty/tools/dotc/core/Symbols.scala") + } + + @Test + def scanDotty() = { + scanDir("src") + } + + @Test + def scanScala() = { + scanDir("../scala-scala/src") + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/desugarPackage.scala b/compiler/test/dotty/tools/dotc/parsing/desugarPackage.scala new file mode 100644 index 000000000..84bf7a2d1 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/desugarPackage.scala @@ -0,0 +1,28 @@ +package dotty.tools +package dotc +package parsing + +import core._, ast._ +import Trees._ + +object desugarPackage extends DeSugarTest { + + def test() = { + reset() + val start = System.nanoTime() + val startNodes = Trees.ntrees + parseDir("./src") + parseDir("./scala-scala/src") + val ms1 = (System.nanoTime() - start)/1000000 + val nodes = Trees.ntrees + val buf = parsedTrees map desugarTree + val ms2 = (System.nanoTime() - start)/1000000 + println(s"$parsed files parsed in ${ms1}ms, ${nodes - startNodes} nodes desugared in ${ms2-ms1}ms, total trees created = ${Trees.ntrees - startNodes}") + ctx.reporter.printSummary(ctx) + } + + def main(args: Array[String]): Unit = { +// parse("/Users/odersky/workspace/scala/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala") + for (i <- 0 until 10) test() + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/parseFile.scala b/compiler/test/dotty/tools/dotc/parsing/parseFile.scala new file mode 100644 index 000000000..c41a286cb --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/parseFile.scala @@ -0,0 +1,13 @@ +package dotty.tools.dotc.parsing + +object parseFile extends ParserTest { + + def main(args: Array[String]): Unit = { + if (args.isEmpty) println("usage: scala test.parseFile file1.scala ... fileN.scala") + for (arg <- args) { + val tree = parse(arg) + println("parsed: " + arg) + println(tree.show) + } + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/parsePackage.scala b/compiler/test/dotty/tools/dotc/parsing/parsePackage.scala new file mode 100644 index 000000000..df5368ffe --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/parsePackage.scala @@ -0,0 +1,83 @@ +package dotty.tools +package dotc +package parsing + +import dotty.tools.dotc._ +import core._, ast._ +import Trees._ +import Contexts.Context + +object parsePackage extends ParserTest { + + import ast.untpd._ + + var nodes = 0 + + val transformer = new UntypedTreeMap { + override def transform(tree: Tree)(implicit ctx: Context): Tree = { + nodes += 1 + tree match { + case Ident(name) => + Ident(name) + case This(name) => + This(name) + case TypedSplice(t) => + TypedSplice(t) + case SymbolLit(str) => + tree + case InterpolatedString(id, segments) => + InterpolatedString(id, segments map transform) + case mdef @ ModuleDef(name, impl) => + ModuleDef(name, transformSub(impl)).withMods(mdef.mods) + case Function(params, body) => + Function(params map transform, body) + case InfixOp(l, o, r) => + InfixOp(transform(l), o, transform(r)) + case PostfixOp(l, o) => + PostfixOp(transform(l), o) + case PrefixOp(o, t) => + PrefixOp(o, transform(t)) + case Parens(t) => + Parens(transform(t)) + case Tuple(ts) => + Tuple(ts map transform) + case WhileDo(cond, body) => + WhileDo(transform(cond), transform(body)) + case DoWhile(body, cond) => + DoWhile(transform(body), transform(cond)) + case ForYield(enums, expr) => + ForYield(enums map transform, transform(expr)) + case ForDo(enums, expr) => + ForDo(enums map transform, transform(expr)) + case GenFrom(pat, expr) => + GenFrom(transform(pat), transform(expr)) + case GenAlias(pat, expr) => + GenAlias(transform(pat), transform(expr)) + case PatDef(mods, pats, tpt, expr) => + PatDef(mods, pats map transform, transform(tpt), transform(expr)) + case ContextBounds(bounds, cxBounds) => + ContextBounds(transformSub(bounds), cxBounds map transform) + case _ => + super.transform(tree) + } + } + } + + def test() = { + reset() + nodes = 0 + val start = System.nanoTime() + parseDir("./src") + parseDir("./scala-scala/src") + val ms1 = (System.nanoTime() - start)/1000000 + val buf = parsedTrees map transformer.transform + val ms2 = (System.nanoTime() - start)/1000000 + println(s"$parsed files parsed in ${ms1}ms, $nodes nodes transformed in ${ms2-ms1}ms, total trees created = ${Trees.ntrees}") + ctx.reporter.printSummary(ctx) + } + + def main(args: Array[String]): Unit = { +// parse("/Users/odersky/workspace/scala/src/compiler/scala/tools/nsc/doc/model/ModelFactoryTypeSupport.scala") + for (i <- 0 until 10) test() + } +} diff --git a/compiler/test/dotty/tools/dotc/parsing/showTree.scala b/compiler/test/dotty/tools/dotc/parsing/showTree.scala new file mode 100644 index 000000000..18b2203d5 --- /dev/null +++ b/compiler/test/dotty/tools/dotc/parsing/showTree.scala @@ -0,0 +1,26 @@ +package dotty.tools +package dotc +package parsing + +import ast.Trees._ +import ast.desugar +import ast.desugar._ +import core.Mode + +object showTree extends DeSugarTest { + + import dotty.tools.dotc.ast.untpd._ + + import Mode._ + + def test(arg: String) = { + val tree: Tree = parse(arg) + println("result = " + tree.show) + println("desugared = " + DeSugar.transform(tree).show) + } + + def main(args: Array[String]): Unit = { + test("src/dotty/tools/dotc/core/Types.scala") + for (arg <- args) test(arg) + } +} -- cgit v1.2.3