diff options
author | VladimirNik <vladimir.nikolaev9@gmail.com> | 2014-02-07 02:41:54 +0400 |
---|---|---|
committer | VladimirNik <vladimir.nikolaev9@gmail.com> | 2014-02-20 01:23:25 +0400 |
commit | 931edcc94ebd73b420b2359d989442bf700588eb (patch) | |
tree | 40d1c09c1d6b32ad54d704550028eaea8873c477 | |
parent | 3973f29cec9f06724941b68577908f546341c45e (diff) | |
download | scala-931edcc94ebd73b420b2359d989442bf700588eb.tar.gz scala-931edcc94ebd73b420b2359d989442bf700588eb.tar.bz2 scala-931edcc94ebd73b420b2359d989442bf700588eb.zip |
Attributed val/var processing for syntactics (SI-8180)
TypedTreesPrinter added
changes based on pull request comments:
print root packages flag; tests for syntactics; SyntacticEmptyTypeTree added to Printers
-rw-r--r-- | src/reflect/scala/reflect/api/Printers.scala | 14 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Printers.scala | 162 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/ReificationSupport.scala | 58 | ||||
-rw-r--r-- | test/files/scalacheck/quasiquotes/TypecheckedProps.scala | 29 | ||||
-rw-r--r-- | test/junit/scala/reflect/internal/PrintersTest.scala | 1954 |
5 files changed, 1363 insertions, 854 deletions
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala index b262fdce68..3591712708 100644 --- a/src/reflect/scala/reflect/api/Printers.scala +++ b/src/reflect/scala/reflect/api/Printers.scala @@ -209,21 +209,23 @@ trait Printers { self: Universe => * Renders the code of the passed tree, so that: * 1) it can be later compiled by scalac retaining the same meaning, * 2) it looks pretty. - * At the moment we have handled #1 for unattributed trees and - * later on plan to account for typical idiosyncrasies of the typechecker. + * #1 is available for unattributed trees and attributed trees * #2 is more or less okay indentation-wise, but at the moment there's a lot of desugaring - * left in place, and that's what we also plan to improve in the future. + * left in place, and that's what we plan to improve in the future. + * printTypes, printIds, printPositions options have the same meaning as for TreePrinter + * printRootPkg option is available only for attributed trees. * * @group Printers */ - def showCode(tree: Tree) = render(tree, newCodePrinter) + def showCode(tree: Tree, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printPositions: BooleanFlag = None, printRootPkg: Boolean = false) = + render(tree, newCodePrinter(_, tree, printRootPkg), printTypes, printIds, None, None, printPositions) /** * Hook to define what `showCode(...)` means. * @group Printers */ - protected def newCodePrinter(out: PrintWriter): TreePrinter - + protected def newCodePrinter(out: PrintWriter, tree: Tree, printRootPkg: Boolean): TreePrinter + /** Renders internal structure of a reflection artifact as the * visualization of a Scala syntax tree. * diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala index b1d76b6056..cb4abd8bd8 100644 --- a/src/reflect/scala/reflect/internal/Printers.scala +++ b/src/reflect/scala/reflect/internal/Printers.scala @@ -74,6 +74,10 @@ trait Printers extends api.Printers { self: SymbolTable => def undent() = indentMargin -= indentStep def printPosition(tree: Tree) = if (printPositions) print(tree.pos.show) + + protected def printTypesInfo(tree: Tree) = + if (printTypes && tree.isTerm && tree.canHaveAttrs) + print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}") def println() = { out.println() @@ -279,9 +283,9 @@ trait Printers extends api.Printers { self: SymbolTable => if (printOwners && tree.symbol != null) print("@" + tree.symbol.owner.id) } - protected def printSuper(tree: Super, resultName: => String) = { + protected def printSuper(tree: Super, resultName: => String, checkSymbol: Boolean = true) = { val Super(This(qual), mix) = tree - if (qual.nonEmpty || tree.symbol != NoSymbol) print(resultName + ".") + if (qual.nonEmpty || (checkSymbol && tree.symbol != NoSymbol)) print(resultName + ".") print("super") if (mix.nonEmpty) print(s"[$mix]") } @@ -498,9 +502,7 @@ trait Printers extends api.Printers { self: SymbolTable => case tree => xprintTree(this, tree) } - if (printTypes && tree.isTerm && tree.canHaveAttrs) { - print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}") - } + printTypesInfo(tree) } def print(args: Any*): Unit = args foreach { @@ -516,19 +518,6 @@ trait Printers extends api.Printers { self: SymbolTable => // it's the printer for trees after parser and before typer phases class ParsedTreePrinter(out: PrintWriter) extends TreePrinter(out) { - override def withTypes = this - override def withIds = this - override def withKinds = this - override def withMirrors = this - override def withPositions = this - - // TODO: add print parameters to typed trees printer - printTypes = false - printIds = false - printKinds = false - printMirrors = false - printPositions = false - protected val parentsStack = scala.collection.mutable.Stack[Tree]() protected def currentTree = if (parentsStack.nonEmpty) Some(parentsStack.top) else None @@ -582,7 +571,7 @@ trait Printers extends api.Printers { self: SymbolTable => case Select(qual, name) if name.isTermName => s"${resolveSelect(qual)}.${printedName(name)}" case Select(qual, name) if name.isTypeName => s"${resolveSelect(qual)}#${blankForOperatorName(name)}%${printedName(name)}" case Ident(name) => printedName(name) - case _ => showCode(t) + case _ => render(t, new ParsedTreePrinter(_)) } } @@ -635,6 +624,7 @@ trait Printers extends api.Printers { self: SymbolTable => def printParam(tree: Tree, primaryCtorParam: Boolean): Unit = tree match { case vd @ ValDef(mods, name, tp, rhs) => + printPosition(tree) printAnnotations(vd) val mutableOrOverride = mods.isOverride || mods.isMutable val hideCtorMods = mods.isParamAccessor && mods.isPrivateLocal && !mutableOrOverride @@ -648,6 +638,7 @@ trait Printers extends api.Printers { self: SymbolTable => printOpt(": ", tp); printOpt(" = ", rhs) case TypeDef(_, name, tparams, rhs) => + printPosition(tree) print(printedName(name)) printTypeParams(tparams); print(rhs) @@ -682,6 +673,13 @@ trait Printers extends api.Printers { self: SymbolTable => override def printTree(tree: Tree): Unit = { parentsStack.push(tree) + try { + processTreePrinting(tree); + printTypesInfo(tree) + } finally parentsStack.pop() + } + + def processTreePrinting(tree: Tree): Unit = { tree match { case cl @ ClassDef(mods, name, tparams, impl) => if (mods.isJavaDefined) super.printTree(cl) @@ -733,12 +731,11 @@ trait Printers extends api.Printers { self: SymbolTable => printSeq(stats) { print(_) } { - print(";"); + println() println() }; case _ => - val separator = scala.util.Properties.lineSeparator - printPackageDef(pd, separator) + printPackageDef(pd, scala.util.Properties.lineSeparator) } case md @ ModuleDef(mods, name, impl) => @@ -786,7 +783,8 @@ trait Printers extends api.Printers { self: SymbolTable => case imp @ Import(expr, _) => printImport(imp, resolveSelect(expr)) - case Template(parents, self, body) => + case t @ Template(parents, self, tbody) => + val body = build.unattributedTemplBody(t) val printedParents = currentParent map { case _: CompoundTypeTree => parents @@ -840,7 +838,7 @@ trait Printers extends api.Printers { self: SymbolTable => case dd: DefDef => dd.name != nme.CONSTRUCTOR case _ => true } - val modBody = left ::: right.drop(1) + val modBody = (left ::: right.drop(1)) val showBody = !(modBody.isEmpty && (self == noSelfType || self.isEmpty)) if (showBody) { if (self.name != nme.WILDCARD) { @@ -996,15 +994,127 @@ trait Printers extends api.Printers { self: SymbolTable => case tree => super.printTree(tree) } - parentsStack.pop() } } + // it's the printer for trees after typer phases + class TypedTreePrinter(out: PrintWriter, printRootPkg: Boolean) extends ParsedTreePrinter(out) { + override def printOpt(prefix: String, tree: Tree) = + if (!emptyTree(tree)) super.printOpt(prefix, tree) + + def syntheticToRemove(tree: Tree) = + tree match { + case _: ValDef | _: TypeDef => false // don't remove ValDef and TypeDef + case md: MemberDef if md.mods.isSynthetic => true + case _ => false + } + + override def printColumn(ts: List[Tree], start: String, sep: String, end: String) = { + super.printColumn(ts.filter(!syntheticToRemove(_)), start, sep, end) + } + + protected def emptyTree(tree: Tree) = tree match { + case EmptyTree | build.SyntacticEmptyTypeTree() => true + case _ => false + } + + def originalTypeTrees(trees: List[Tree]) = + trees.filter(!emptyTree(_)) map { + case tt: TypeTree => tt.original + case tree => tree + } + + override protected def removeDefaultClassesFromList(trees: List[Tree], classesToRemove: List[Name] = defaultClasses) = + super.removeDefaultClassesFromList(originalTypeTrees(trees), classesToRemove) + + override def resolveSelect(t: Tree): String = { + t match { + case _: Select | _: Ident => super.resolveSelect(t) + case _ => render(t, new TypedTreePrinter(_, printRootPkg)) + } + } + + override def processTreePrinting(tree: Tree): Unit = { + tree match { + // don't remove synthetic ValDef/TypeDef + case _ if syntheticToRemove(tree) => + + case tt: TypeTree => + if (printPositions) { + if (tt.original != null) + print("<type: ", tt.original.toString(), ">") + else print("<type ?>") + } else if (!emptyTree(tt)) print(tt.original) + + // print only fun when targs are TypeTrees with empty original + case TypeApply(fun, targs) => + if (targs.exists(emptyTree(_))) { + print(fun) + } else super.processTreePrinting(tree) + + case UnApply(fun, args) => + fun match { + case treeInfo.Unapplied(body) => + body match { + case Select(qual, name) if name == nme.unapply => print(qual) + case TypeApply(Select(qual, name), args) if name == nme.unapply || name == nme.unapplySeq => + print(TypeApply(qual, args)) + case _ => print(body) + } + case _ => print(fun) + } + printRow(args, "(", ", ", ")") + + // remove this.this from constructor invocation + case Select(This(_), name @ nme.CONSTRUCTOR) => print(printedName(name)) + + case Select(qual, name) => + def checkRootPackage(tr: Tree): Boolean = + (currentParent match { //check that Select is not for package def name + case Some(_: PackageDef) => false + case _ => true + }) && (tr match { // check that Select contains package + case Select(q, _) => checkRootPackage(q) + case _: Ident | _: This => val sym = tr.symbol + tr.hasExistingSymbol && sym.isPackage && !sym.isRootPackage + case _ => false + }) + + if (printRootPkg && checkRootPackage(tree)) print(s"${printedName(nme.ROOTPKG)}.") + super.processTreePrinting(tree) + + case Typed(expr, tp) => + def printTp = print("(", tp, ")") + + tp match { + case EmptyTree | build.SyntacticEmptyTypeTree() | _: Annotated => printTp + case tt: TypeTree if tt.original.isInstanceOf[Annotated] => printTp + case _ => super.processTreePrinting(tree) + } + + case This(qual) => + if (tree.symbol.isPackage) print(tree.symbol.fullName) + else super.processTreePrinting(tree) + + case st @ Super(th @ This(qual), mix) => + printSuper(st, printedName(qual), checkSymbol = false) + + case tree => super.processTreePrinting(tree) + } + } + } + /** Hook for extensions */ def xprintTree(treePrinter: TreePrinter, tree: Tree) = treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")")) - def newCodePrinter(writer: PrintWriter): TreePrinter = new ParsedTreePrinter(writer) + def newCodePrinter(writer: PrintWriter, tree: Tree, printRootPkg: Boolean): TreePrinter = { + if (build.detectAttributedTree(tree)) + new TypedTreePrinter(writer, printRootPkg) + else + new ParsedTreePrinter(writer) + } + def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer) def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream)) def newTreePrinter(): TreePrinter = newTreePrinter(new PrintWriter(ConsoleWriter)) diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala index 087d4186be..44cda24242 100644 --- a/src/reflect/scala/reflect/internal/ReificationSupport.scala +++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala @@ -234,10 +234,66 @@ trait ReificationSupport { self: SymbolTable => } } + private[internal] def detectAttributedTree(tree: Tree) = + tree.hasExistingSymbol || tree.exists { + case dd: DefDef => dd.mods.hasAccessorFlag || dd.mods.isSynthetic // for untypechecked trees + case md: MemberDef => md.hasExistingSymbol + case _ => false + } + + // recover template body to parsed state + private[internal] def unattributedTemplBody(templ: Template) = { + val tbody = templ.body + + def filterBody(body: List[Tree]) = body filter { + case _: ValDef | _: TypeDef => true + // keep valdef or getter for val/var + case dd: DefDef if dd.mods.hasAccessorFlag => !nme.isSetterName(dd.name) && !tbody.exists{ + case vd: ValDef => dd.name == vd.name.dropLocal + case _ => false + } + case md: MemberDef => !md.mods.isSynthetic + case tree => true + } + + def lazyValDefRhs(body: Tree) = + body match { + case Block(List(Assign(_, rhs)), _) => rhs + case _ => body + } + + def recoverBody(body: List[Tree]) = body map { + case vd @ ValDef(vmods, vname, _, vrhs) if nme.isLocalName(vname) => + tbody find { + case dd: DefDef => dd.name == vname.dropLocal + case _ => false + } map { dd => + val DefDef(dmods, dname, _, _, _, drhs) = dd + // get access flags from DefDef + val vdMods = (vmods &~ Flags.AccessFlags) | (dmods & Flags.AccessFlags).flags + // for most cases lazy body should be taken from accessor DefDef + val vdRhs = if (vmods.isLazy) lazyValDefRhs(drhs) else vrhs + copyValDef(vd)(mods = vdMods, name = dname, rhs = vdRhs) + } getOrElse (vd) + // for abstract and some lazy val/vars + case dd @ DefDef(mods, name, _, _, tpt, rhs) if mods.hasAccessorFlag => + // transform getter mods to field + val vdMods = (if (!mods.hasStableFlag) mods | Flags.MUTABLE else mods &~ Flags.STABLE) &~ Flags.ACCESSOR + ValDef(vdMods, name, tpt, rhs) + case tree => tree + } + + if (detectAttributedTree(templ)) { + recoverBody(filterBody(tbody)) + } else tbody + } + // undo gen.mkTemplate protected object UnMkTemplate { def unapply(templ: Template): Option[(List[Tree], ValDef, Modifiers, List[List[ValDef]], List[Tree], List[Tree])] = { - val Template(parents, selfType, tbody) = templ + val Template(parents, selfType, _) = templ + val tbody = unattributedTemplBody(templ) + def result(ctorMods: Modifiers, vparamss: List[List[ValDef]], edefs: List[Tree], body: List[Tree]) = Some((parents, selfType, ctorMods, vparamss, edefs, body)) def indexOfCtor(trees: List[Tree]) = diff --git a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala index 8b1cb6cc49..14669764d3 100644 --- a/test/files/scalacheck/quasiquotes/TypecheckedProps.scala +++ b/test/files/scalacheck/quasiquotes/TypecheckedProps.scala @@ -65,7 +65,7 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") { } property("extract UnApply (2)") = test { - val q"object $_ { $_; $_; $m }" = typecheck(q""" + val q"object $_ { $_; $m }" = typecheck(q""" object Test { case class Cell(val x: Int) new Cell(0) match { case Cell(v) => v } @@ -82,4 +82,31 @@ object TypecheckedProps extends QuasiquoteProperties("typechecked") { val q"val x: ${tq""} = 42" = typechecked val q"val x: ${t: Type} = 42" = typechecked } + + property("class with param (1)") = test { + val paramName = TermName("x") + val q"class $_($param)" = typecheck(q"class Test(val $paramName: Int)") + + assert(param.name == paramName) + } + + property("class with param (2)") = test { + val paramName = TermName("y") + val q"{ class $_($param); $_}" = typecheck(q"{ class Test(val $paramName: Int = 3) }") + + assert(param.name == paramName) + assert(param.rhs ≈ q"3") + } + + property("class with params") = test { + val pName1 = TermName("x1") + val pName2 = TermName("x2") + val q"{ class $_($param1)(..$params2); $_}" = typecheck(q"{ class Test(val x0: Float)(val $pName1: Int = 3, $pName2: String) }") + + val List(p1, p2, _*) = params2 + + assert(p1.name == pName1) + assert(p2.name == pName2) + assert(params2.size == 2) + } } diff --git a/test/junit/scala/reflect/internal/PrintersTest.scala b/test/junit/scala/reflect/internal/PrintersTest.scala index 9fec112c99..534cd5b95f 100644 --- a/test/junit/scala/reflect/internal/PrintersTest.scala +++ b/test/junit/scala/reflect/internal/PrintersTest.scala @@ -2,823 +2,1137 @@ // therefore certain scala-reflect tests give me AMEs after the SI-8063 overhaul // TODO: fix this in build.xml -// package scala.reflect.internal - -// import org.junit.Test -// import org.junit.Assert._ -// import scala.tools.reflect._ -// import scala.reflect.runtime.universe._ -// import scala.reflect.runtime.{currentMirror=>cm} -// import org.junit.runner.RunWith -// import org.junit.runners.JUnit4 - -// @RunWith(classOf[JUnit4]) -// class PrintersTest extends BasePrintTests -// with ClassPrintTests -// with TraitPrintTests -// with ValAndDefPrintTests -// with QuasiTreesPrintTests -// with PackagePrintTests - -// object PrinterHelper { -// val toolbox = cm.mkToolBox() -// def assertPrintedCode(code: String, tree: Tree = EmptyTree) = { -// def processEOL(resultCode: String) = { -// import scala.reflect.internal.Chars._ -// resultCode.replaceAll(s"$CR$LF", s"$LF").replace(CR, LF) -// } - -// val toolboxTree = -// try{ -// toolbox.parse(code) -// } catch { -// case e:scala.tools.reflect.ToolBoxError => throw new Exception(e.getMessage + ": " + code) -// } -// if (tree ne EmptyTree) assertEquals("using quasiquote or given tree"+"\n", code.trim, processEOL(showCode(tree))) -// else assertEquals("using toolbox parser", code.trim, processEOL(showCode(toolboxTree))) -// } - -// implicit class StrContextStripMarginOps(val stringContext: StringContext) extends util.StripMarginInterpolator -// } - -// import PrinterHelper._ - -// trait BasePrintTests { -// @Test def testIdent = assertPrintedCode("*", Ident("*")) - -// @Test def testConstant1 = assertPrintedCode("\"*\"", Literal(Constant("*"))) - -// @Test def testConstant2 = assertPrintedCode("42", Literal(Constant(42))) - -// @Test def testConstantFloat = assertPrintedCode("42.0F", Literal(Constant(42f))) - -// @Test def testConstantDouble = assertPrintedCode("42.0", Literal(Constant(42d))) - -// @Test def testConstantLong = assertPrintedCode("42L", Literal(Constant(42l))) - -// @Test def testOpExpr = assertPrintedCode("(5).+(4)") - -// @Test def testName1 = assertPrintedCode("class test") - -// @Test def testName2 = assertPrintedCode("class *") - -// @Test def testName4 = assertPrintedCode("class `a*`") - -// @Test def testName5 = assertPrintedCode("val :::: = 1") - -// @Test def testName6 = assertPrintedCode("val `::::t` = 1") - -// @Test def testName7 = assertPrintedCode("""class \/""") - -// @Test def testName8 = assertPrintedCode("""class \\\\""") - -// @Test def testName9 = assertPrintedCode("""class test_\/""") - -// @Test def testName10 = assertPrintedCode("""class `*_*`""") - -// @Test def testName11 = assertPrintedCode("""class `a_*`""") - -// @Test def testName12 = assertPrintedCode("""class `*_a`""") - -// @Test def testName13 = assertPrintedCode("""class a_a""") - -// @Test def testName14 = assertPrintedCode("val x$11 = 5") - -// @Test def testName15 = assertPrintedCode("class `[]`") - -// @Test def testName16 = assertPrintedCode("class `()`") - -// @Test def testName17 = assertPrintedCode("class `{}`") - -// @Test def testName18 = assertPrintedCode("class <>") - -// @Test def testName19 = assertPrintedCode("""class `class`""") - -// @Test def testName20 = assertPrintedCode("""class `test name`""") - -// @Test def testIfExpr1 = assertPrintedCode(sm""" -// |if (a) -// | ((expr1): Int) -// |else -// | ((expr2): Int)""") - -// @Test def testIfExpr2 = assertPrintedCode(sm""" -// |(if (a) -// | { -// | expr1; -// | () -// | } -// |else -// | { -// | expr2; -// | () -// | }).toString""") - -// @Test def testIfExpr3 = assertPrintedCode(sm""" -// |(if (a) -// | { -// | expr1; -// | () -// | } -// |else -// | { -// | expr2; -// | () -// | }).method1().method2()""") - -// //val x = true && true && false.! -// @Test def testBooleanExpr1 = assertPrintedCode("val x = true.&&(true).&&(false.!)") - -// //val x = true && !(true && false) -// @Test def testBooleanExpr2 = assertPrintedCode("val x = true.&&(true.&&(false).`unary_!`)") - -// @Test def testNewExpr1 = assertPrintedCode("new foo()") - -// //new foo { test } -// @Test def testNewExpr2 = assertPrintedCode(sm""" -// |{ -// | final class $$anon extends foo { -// | test -// | }; -// | new $$anon() -// |}""") - -// @Test def testNewExpr3 = assertPrintedCode("new foo[t]()") - -// @Test def testNewExpr4 = assertPrintedCode("new foo(x)") - -// @Test def testNewExpr5 = assertPrintedCode("new foo[t](x)") - -// //new foo[t](x) { () } -// @Test def testNewExpr6 = assertPrintedCode(sm""" -// |{ -// | final class $$anon extends foo[t](x) { -// | () -// | }; -// | new $$anon() -// |}""") - -// //new foo with bar -// @Test def testNewExpr7 = assertPrintedCode(sm""" -// |{ -// | final class $$anon extends foo with bar; -// | new $$anon() -// |}""") - -// //new { anonymous } -// @Test def testNewExpr8 = assertPrintedCode(sm""" -// |{ -// | final class $$anon { -// | anonymous -// | }; -// | new $$anon() -// |}""") - -// //new { val early = 1 } with Parent[Int] { body } -// @Test def testNewExpr9 = assertPrintedCode(sm""" -// |{ -// | final class $$anon extends { -// | val early = 1 -// | } with Parent[Int] { -// | body -// | }; -// | new $$anon() -// |}""") - -// //new Foo { self => } -// @Test def testNewExpr10 = assertPrintedCode(sm""" -// |{ -// | final class $$anon extends Foo { self => -// | -// | }; -// | new $$anon() -// |}""") - -// @Test def testReturn = assertPrintedCode("def test: Int = return 42") - -// @Test def testFunc1 = assertPrintedCode("List(1, 2, 3).map(((i: Int) => i.-(1)))") - -// //val sum: Seq[Int] => Int = _ reduceLeft (_+_) -// @Test def testFunc2 = assertPrintedCode("val sum: _root_.scala.Function1[Seq[Int], Int] = ((x$1) => x$1.reduceLeft(((x$2, x$3) => x$2.+(x$3))))") - -// //List(1, 2, 3) map (_ - 1) -// @Test def testFunc3 = assertPrintedCode("List(1, 2, 3).map(((x$1) => x$1.-(1)))") - -// @Test def testImport1 = assertPrintedCode("import scala.collection.mutable") - -// @Test def testImport2 = assertPrintedCode("import java.lang.{String=>Str}") - -// @Test def testImport3 = assertPrintedCode("import java.lang.{String=>Str, Object=>_, _}") - -// @Test def testImport4 = assertPrintedCode("import scala.collection._") -// } - -// trait ClassPrintTests { -// @Test def testClass = assertPrintedCode("class *") - -// @Test def testClassWithBody = assertPrintedCode(sm""" -// |class X { -// | def y = "test" -// |}""") - -// @Test def testClassWithPublicParams = assertPrintedCode("class X(val x: Int, val s: String)") - -// @Test def testClassWithParams1 = assertPrintedCode("class X(x: Int, s: String)") - -// @Test def testClassWithParams2 = assertPrintedCode("class X(@test x: Int, s: String)") - -// @Test def testClassWithParams3 = assertPrintedCode("class X(implicit x: Int, s: String)") - -// @Test def testClassWithParams4 = assertPrintedCode("class X(implicit @test x: Int, s: String)") - -// @Test def testClassWithParams5 = assertPrintedCode("class X(override private[this] val x: Int, s: String) extends Y") - -// @Test def testClassWithParams6 = assertPrintedCode("class X(@test1 override private[this] val x: Int, @test2(param1 = 7) s: String) extends Y") - -// @Test def testClassWithParams7 = assertPrintedCode("class X protected (val x: Int, val s: String)") - -// @Test def testClassWithParams8 = assertPrintedCode("class X(var x: Int)") - -// @Test def testClassWithParams9 = assertPrintedCode("class X(var x: Int*)") - -// @Test def testClassWithByNameParam = assertPrintedCode("class X(x: => Int)") - -// @Test def testClassWithDefault = assertPrintedCode("class X(var x: Int = 5)") - -// @Test def testClassWithParams10 = assertPrintedCode("class X(protected[zzz] var x: Int)") - -// @Test def testClassWithParams11 = assertPrintedCode("class X(override var x: Int) extends F(x) with E(x)") - -// @Test def testClassWithParams12 = assertPrintedCode("class X(val y: Int)()(var z: Double)") - -// @Test def testClassWithImplicitParams = assertPrintedCode("class X(var i: Int)(implicit val d: Double, var f: Float)") - -// @Test def testClassWithEarly = assertPrintedCode(sm""" -// |class X(var i: Int) extends { -// | val a: String = i; -// | type B -// |} with Y""") - -// @Test def testClassWithThrow1 = assertPrintedCode(sm""" -// |class Throw1 { -// | throw new Exception("exception!") -// |}""") - -// @Test def testClassWithThrow2 = assertPrintedCode(sm""" -// |class Throw2 { -// | var msg = " "; -// | val e = new Exception(msg); -// | throw e -// |}""") - -// /* -// class Test { -// val (a, b) = (1, 2) -// } -// */ -// @Test def testClassWithAssignmentWithTuple1 = assertPrintedCode(sm""" -// |class Test { -// | private[this] val x$$1 = (scala.Tuple2(1, 2): @scala.unchecked) match { -// | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2(a, b) -// | }; -// | val a = x$$1._1; -// | val b = x$$1._2 -// |}""") - -// /* -// class Test { -// val (a, b) = (1).->(2) -// } -// */ -// @Test def testClassWithAssignmentWithTuple2 = assertPrintedCode(sm""" -// |class Test { -// | private[this] val x$$1 = ((1).->(2): @scala.unchecked) match { -// | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2(a, b) -// | }; -// | val a = x$$1._1; -// | val b = x$$1._2 -// |}""") - -// /* -// class Test { -// val List(one, three, five) = List(1,3,5) -// } -// */ -// @Test def testClassWithPatternMatchInAssignment = assertPrintedCode(sm""" -// |class Test { -// | private[this] val x$$1 = (List(1, 3, 5): @scala.unchecked) match { -// | case List((one @ _), (three @ _), (five @ _)) => scala.Tuple3(one, three, five) -// | }; -// | val one = x$$1._1; -// | val three = x$$1._2; -// | val five = x$$1._3 -// |}""") - -// //class A(l: List[_]) -// @Test def testClassWithExistentialParameter1 = assertPrintedCode(sm""" -// |class Test(l: (List[_$$1] forSome { -// | type _$$1 -// |}))""") - -// @Test def testClassWithExistentialParameter2 = assertPrintedCode(sm""" -// |class B(l: (List[T] forSome { -// | type T -// |}))""") - -// @Test def testClassWithCompoundTypeTree = assertPrintedCode(sm""" -// |{ -// | trait A; -// | trait B; -// | abstract class C(val a: A with B) { -// | def method(x: A with B with C { -// | val x: Float -// | }): A with B -// | }; -// | () -// |}""") - -// @Test def testClassWithSelectFromTypeTree = assertPrintedCode(sm""" -// |{ -// | trait A { -// | type T -// | }; -// | class B(t: (A)#T); -// | () -// |}""") - -// @Test def testImplicitClass = assertPrintedCode("implicit class X(protected[zzz] var x: Int)") - -// @Test def testAbstractClass = assertPrintedCode("abstract class X(protected[zzz] var x: Int)") - -// @Test def testCaseClassWithParams1 = assertPrintedCode("case class X(x: Int, s: String)") - -// @Test def testCaseClassWithParams2 = assertPrintedCode("case class X(protected val x: Int, s: String)") - -// @Test def testCaseClassWithParams3 = assertPrintedCode("case class X(implicit x: Int, s: String)") - -// @Test def testCaseClassWithParams4 = assertPrintedCode("case class X(override val x: Int, s: String) extends Y") - -// @Test def testCaseClassWithBody = assertPrintedCode(sm""" -// |case class X() { -// | def y = "test" -// |}""") - -// @Test def testLocalClass = assertPrintedCode(sm""" -// |def test = { -// | class X(var a: Int) { -// | def y = "test" -// | }; -// | new X(5) -// |}""") - -// @Test def testLocalCaseClass = assertPrintedCode(sm""" -// |def test = { -// | case class X(var a: Int) { -// | def y = "test" -// | }; -// | new X(5) -// |}""") - -// @Test def testSuperInClass = assertPrintedCode(sm""" -// |{ -// | trait Root { -// | def r = "Root" -// | }; -// | class X extends Root { -// | def superX = super.r -// | }; -// | class Y extends X with Root { -// | class Inner { -// | val myY = Y.super.r -// | }; -// | def fromX = super[X].r; -// | def fromRoot = super[Root].r -// | }; -// | () -// |}""") - -// @Test def testThisInClass = assertPrintedCode(sm""" -// |class Outer { -// | class Inner { -// | val outer = Root.this -// | }; -// | val self = this -// |}""") - -// @Test def testCaseClassWithParamsAndBody = assertPrintedCode(sm""" -// |case class X(x: Int, s: String) { -// | def y = "test" -// |}""") - -// @Test def testObject = assertPrintedCode("object *") - -// @Test def testObjectWithBody = assertPrintedCode(sm""" -// |object X { -// | def y = "test" -// |}""") - -// @Test def testObjectWithEarly1 = assertPrintedCode(sm""" -// |object X extends { -// | val early: T = v -// |} with Bar""") - -// @Test def testObjectWithEarly2 = assertPrintedCode(sm""" -// |object X extends { -// | val early: T = v; -// | type EarlyT = String -// |} with Bar""") - -// @Test def testObjectWithSelf = assertPrintedCode(sm""" -// |object Foo extends Foo { self => -// | body -// |}""") - -// @Test def testObjectInh = assertPrintedCode("private[Y] object X extends Bar with Baz") - -// @Test def testObjectWithPatternMatch1 = assertPrintedCode(sm""" -// |object PM1 { -// | List(1, 2) match { -// | case (i @ _) => i -// | } -// |}""") - -// @Test def testObjectWithPatternMatch2 = assertPrintedCode(sm""" -// |object PM2 { -// | List(1, 2).map({ -// | case (i @ _) if i.>(5) => i -// | }) -// |}""") - -// //case i: Int => i -// @Test def testObjectWithPatternMatch3 = assertPrintedCode(sm""" -// |object PM3 { -// | List(1, 2).map({ -// | case (i @ ((_): Int)) => i -// | }) -// |}""") - -// //case a @ (i: Int) => i -// @Test def testObjectWithPatternMatch4 = assertPrintedCode(sm""" -// |object PM4 { -// | List(1, 2).map({ -// | case (a @ (i @ ((_): Int))) => i -// | }) -// |}""") - -// @Test def testObjectWithPatternMatch5 = assertPrintedCode(sm""" -// |object PM5 { -// | List(1, 2).map({ -// | case _ => 42 -// | }) -// |}""") - -// @Test def testObjectWithPatternMatch6 = assertPrintedCode(sm""" -// |object PM6 { -// | List(1, 2) match { -// | case ::((x @ _), (xs @ _)) => x -// | } -// |}""") - -// @Test def testObjectWithPatternMatch7 = assertPrintedCode(sm""" -// |object PM7 { -// | List(1, 2).map({ -// | case (0| 1) => true -// | case _ => false -// | }) -// |}""") - -// @Test def testObjectWithPatternMatch8 = assertPrintedCode(sm""" -// |object PM8 { -// | "abcde".toList match { -// | case Seq((car @ _), _*) => car -// | } -// |}""") - -// @Test def testObjectWithPatternMatch9 = assertPrintedCode(sm""" -// |{ -// | object Extractor { -// | def unapply(i: Int) = Some(i) -// | }; -// | object PM9 { -// | 42 match { -// | case (a @ Extractor((i @ _))) => i -// | } -// | }; -// | () -// |}""") - -// @Test def testObjectWithPartialFunc = assertPrintedCode(sm""" -// |object Test { -// | def partFuncTest[A, B](e: Either[A, B]): scala.Unit = e match { -// | case Right(_) => () -// | } -// |}""") - -// @Test def testObjectWithTry = assertPrintedCode(sm""" -// |object Test { -// | import java.io; -// | var file: PrintStream = null; -// | try { -// | val out = new FileOutputStream("myfile.txt"); -// | file = new PrintStream(out) -// | } catch { -// | case (ioe @ ((_): IOException)) => println("ioe") -// | case (e @ ((_): Exception)) => println("e") -// | } finally println("finally") -// |}""") -// } - -// trait TraitPrintTests { -// @Test def testTrait = assertPrintedCode("trait *") - -// @Test def testTraitWithBody = assertPrintedCode(sm""" -// |trait X { -// | def y = "test" -// |}""") - -// @Test def testTraitWithSelfTypeAndBody = assertPrintedCode(sm""" -// |trait X { self: Order => -// | def y = "test" -// |}""") - -// @Test def testTraitWithSelf1 = assertPrintedCode(sm""" -// |trait X { self => -// | def y = "test" -// |}""") - -// @Test def testTraitWithSelf2 = assertPrintedCode(sm""" -// |trait X { self: Foo with Bar => -// | val x: Int = 1 -// |}""") - -// @Test def testTraitTypeParams = assertPrintedCode("trait X[A, B]") - -// @Test def testTraitWithBody2 = assertPrintedCode(sm""" -// |trait X { -// | def foo: scala.Unit; -// | val bar: Baz -// |}""") - -// @Test def testTraitWithInh = assertPrintedCode("trait X extends A with B") - -// @Test def testTraitWithEarly1 = assertPrintedCode(sm""" -// |trait X extends { -// | val x: Int = 1 -// |} with Any""") - -// @Test def testTraitWithEarly2 = assertPrintedCode(sm""" -// |trait X extends { -// | val x: Int = 0; -// | type Foo = Bar -// |} with Y""") - -// @Test def testTraitWithEarly3 = assertPrintedCode(sm""" -// |trait X extends { -// | val x: Int = 5; -// | val y: Double = 4.0; -// | type Foo; -// | type XString = String -// |} with Y""") - -// @Test def testTraitWithEarly4 = assertPrintedCode(sm""" -// |trait X extends { -// | val x: Int = 5; -// | val y: Double = 4.0; -// | type Foo; -// | type XString = String -// |} with Y { -// | val z = 7 -// |}""") - -// @Test def testTraitWithEarly5 = assertPrintedCode(sm""" -// |trait X extends { -// | override protected[this] val x: Int = 5; -// | val y: Double = 4.0; -// | private type Foo; -// | private[ee] type XString = String -// |} with Y { -// | val z = 7 -// |}""") - -// @Test def testTraitWithSingletonTypeTree = assertPrintedCode(sm""" -// |trait Test { -// | def testReturnSingleton(): this.type -// |}""") - -// @Test def testTraitWithThis = assertPrintedCode(sm""" -// |trait Test { _ : X with Y => -// | -// |}""", q"trait Test { this: X with Y => }") - -// @Test def testTraitWithWhile1 = assertPrintedCode(sm""" -// |trait Test { -// | while (true.!=(false)) -// | println("testing...") -// | -// |}""") - -// @Test def testTraitWithWhile2 = assertPrintedCode(sm""" -// |trait Test { -// | while (true) -// | { -// | println("testing..."); -// | println("testing...") -// | } -// | -// |}""") - -// @Test def testTraitWithDoWhile1 = assertPrintedCode(sm""" -// |trait Test { -// | do -// | println("testing...") -// | while (true) -// |}""") - -// @Test def testTraitWithTypes = assertPrintedCode(sm""" -// |trait Test { -// | type A = Int; -// | type B >: Nothing <: AnyRef; -// | protected type C >: Nothing; -// | type D <: AnyRef -// |}""") -// } - -// trait ValAndDefPrintTests { -// @Test def testVal1 = assertPrintedCode("val a: Unit = null") - -// @Test def testVal2 = assertPrintedCode("val * : Unit = null") - -// @Test def testVal3 = assertPrintedCode("val a_ : Unit = null") - -// @Test def testDef1 = assertPrintedCode("def a: Unit = null") - -// @Test def testDef2 = assertPrintedCode("def * : Unit = null") - -// @Test def testDef3 = assertPrintedCode("def a_(x: Int): Unit = null") - -// @Test def testDef4 = assertPrintedCode("def a_ : Unit = null") - -// @Test def testDef5 = assertPrintedCode("def a_(* : Int): Unit = null") - -// @Test def testDef6 = assertPrintedCode("def a_(b_ : Int): Unit = null") - -// @Test def testDef7 = assertPrintedCode(sm""" -// |{ -// | def test1 = (); -// | def test2() = () -// |}""", -// Block( -// DefDef(NoMods, newTermName("test1"), Nil, Nil, EmptyTree, Literal(Constant(()))), -// DefDef(NoMods, newTermName("test2"), Nil, Nil :: Nil, EmptyTree, Literal(Constant(()))) -// ) -// ) - -// @Test def testDef8 = { -// val arg = ValDef(Modifiers(Flag.IMPLICIT) , newTermName("a"), -// AppliedTypeTree(Ident(newTypeName("R")), List(Ident(newTypeName("X")))), EmptyTree) - -// //def m[X](implicit a: R[X]) = () -// val tree = DefDef(NoMods, newTermName("test"), TypeDef(NoMods, newTypeName("X"), Nil, EmptyTree) :: Nil, -// List(List(arg)), EmptyTree, Literal(Constant(()))) - -// assertPrintedCode("def test[X](implicit a: R[X]) = ()", tree) -// } - -// @Test def testDefWithParams1 = assertPrintedCode("def foo(x: Int*) = null") - -// @Test def testDefWithParams2 = assertPrintedCode("def foo(x: Int)(y: Int = 1) = null") - -// @Test def testDefWithTypeParams1 = assertPrintedCode("def foo[A, B, C](x: A)(y: Int = 1): C = null") - -// @Test def testDefWithTypeParams2 = assertPrintedCode("def foo[A, B <: Bar] = null") - -// @Test def testDefWithAnn1 = assertPrintedCode("@annot def foo = null") - -// @Test def testDefWithAnn2 = assertPrintedCode("@a(x) def foo = null") - -// @Test def testDefWithAnn3 = assertPrintedCode("@Foo[A, B] def foo = null") - -// @Test def testDefWithAnn4 = assertPrintedCode("@Foo(a)(b)(x, y) def foo = null") - -// @Test def testDefWithAnn5 = assertPrintedCode("@Foo[A, B](a)(b) @Bar def foo(x: Int) = null") - -// @Test def testDefWithAnn6 = assertPrintedCode("@test1(new test2()) def foo = 42") - -// @Test def testDefWithAnn7 = assertPrintedCode("@`t*` def foo = 42") - -// @Test def testDefWithAnn8 = assertPrintedCode("@throws(classOf[Exception]) def foo = throw new Exception()") - -// @Test def testAnnotated1 = assertPrintedCode("def foo = 42: @test1") - -// @Test def testAnnotated2 = assertPrintedCode("""def foo = 42: @test1(42, z = "5")""") - -// @Test def testAnnotated3 = assertPrintedCode("def foo = (42: @test1): @test2(new test1())") - -// @Test def testAnnotated4 = assertPrintedCode("""def foo = 42: @test1(4, "testing")(4.2)""") - -// @Test def testAnnotated5 = assertPrintedCode("""def foo = (42: @test1(4, "testing")(4.2)): @test2(1, "bar")(3.14)""") - -// @Test def testAnnotated6 = assertPrintedCode("def foo = ((42: @test1): @test2(new test1())): @test3(1)(2, 3)(4)") - -// @Test def testAnnotated7 = assertPrintedCode(sm""" -// |(x: @unchecked) match { -// | case ((_): Int) => true -// | case _ => false -// |}""") - -// @Test def testAnnotated8 = assertPrintedCode(sm""" -// |((x: @unchecked): @test1(1, "testing")(3.14)) match { -// | case _ => true -// |}""") -// } - -// trait PackagePrintTests { -// @Test def testPackage1 = assertPrintedCode(sm""" -// |package foo.bar { -// | -// |}""") - -// @Test def testPackage2 = assertPrintedCode(sm""" -// |package foo { -// | class C -// | -// | object D -// |}""") - -// //package object foo extends a with b -// @Test def testPackage3 = assertPrintedCode(sm""" -// |package foo { -// | object `package` extends a with b -// |}""") - -// //package object foo { def foo; val x = 1 } -// @Test def testPackage4 = assertPrintedCode(sm""" -// |package foo { -// | object `package` { -// | def foo: scala.Unit; -// | val x = 1 -// | } -// |}""") - -// //package object foo extends { val x = 1; type I = Int } with Any -// @Test def testPackage5 = assertPrintedCode(sm""" -// |package foo { -// | object `package` extends { -// | val x = 1; -// | type I = Int -// | } with Any -// |}""") -// } - -// trait QuasiTreesPrintTests { -// @Test def testQuasiIdent = assertPrintedCode("*", q"*") - -// @Test def testQuasiVal = assertPrintedCode("val * : Unit = null", q"val * : Unit = null") - -// @Test def testQuasiDef = assertPrintedCode("def * : Unit = null", q"def * : Unit = null") - -// @Test def testQuasiTrait = assertPrintedCode("trait *", q"trait *") - -// @Test def testQuasiClass = assertPrintedCode("class *", q"class *") - -// @Test def testQuasiClassWithPublicParams = assertPrintedCode( "class X(val x: Int, val s: String)", q"class X(val x: Int, val s:String)" ) - -// @Test def testQuasiClassWithParams = assertPrintedCode("class X(x: Int, s: String)", q"class X(x: Int, s:String)") - -// @Test def testQuasiObject = assertPrintedCode("object *", q"object *") - -// @Test def testQuasiObjectWithBody = assertPrintedCode(sm""" -// |object X { -// | def y = "test" -// |}""", q"""object X{ def y = "test" }""") - -// @Test def testQuasiClassWithBody = assertPrintedCode(sm""" -// |class X { -// | def y = "test" -// |}""", q"""class X{ def y = "test" }""") - -// @Test def testQuasiTraitWithBody = assertPrintedCode(sm""" -// |trait X { -// | def y = "test" -// |}""", q"""trait X{ def y = "test" }""") - -// @Test def testQuasiTraitWithSelfTypeAndBody = assertPrintedCode(sm""" -// |trait X { self: Order => -// | def y = "test" -// |}""", q"""trait X{ self: Order => def y = "test" }""") - -// @Test def testQuasiTraitWithSelf = assertPrintedCode(sm""" -// |trait X { self => -// | def y = "test" -// |}""", q"""trait X{ self => def y = "test" }""") - -// @Test def testQuasiCaseClassWithBody = assertPrintedCode(sm""" -// |case class X() { -// | def y = "test" -// |}""", q"""case class X() { def y = "test" }""") - -// @Test def testQuasiCaseClassWithParamsAndBody = assertPrintedCode(sm""" -// |case class X(x: Int, s: String) { -// | def y = "test" -// |}""", q"""case class X(x: Int, s: String){ def y = "test" }""") -// } +/** +package scala.reflect.internal + +import org.junit.Test +import org.junit.Assert._ +import scala.tools.reflect._ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{currentMirror=>cm} +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +@RunWith(classOf[JUnit4]) +class PrintersTest extends BasePrintTests + with ClassPrintTests + with TraitPrintTests + with ValAndDefPrintTests + with QuasiTreesPrintTests + with PackagePrintTests + +object PrinterHelper { + val toolbox = cm.mkToolBox() + + import scala.reflect.internal.Chars._ + private def normalizeEOL(resultCode: String) = + resultCode.lines mkString s"$LF" + + def assertResultCode(code: String)(parsedCode: String = "", typedCode: String = "", wrap: Boolean = false) = { + def toolboxTree(tree: => Tree) = try{ + tree + } catch { + case e:scala.tools.reflect.ToolBoxError => throw new Exception(e.getMessage + ": " + code) + } + + def wrapCode(source: String) = { + val context = sm""" + |trait PrintersContext { + | class baz extends scala.annotation.StaticAnnotation; + | class foo1[A, B] extends scala.annotation.StaticAnnotation; + | class foo2[A, B](a: scala.Int)(b: scala.Int) extends scala.annotation.StaticAnnotation; + | class foo3[Af, Bf](a: scala.Int)(b: scala.Float, c: PrintersContext.this.foo1[Af, Bf]) extends scala.annotation.StaticAnnotation; + | trait A1; + | trait B1; + |${source.trim.lines map {" " + _} mkString s"$LF"} + |}""" + + if (wrap) context.trim() else source.trim + } + + val parsedTree = toolboxTree(toolbox.parse(wrapCode(code))) + if (!parsedCode.isEmpty()) + assertEquals("using toolbox parser" + LF, wrapCode(parsedCode), normalizeEOL(showCode(parsedTree))) + if (!typedCode.isEmpty()) { + val typedTree = toolboxTree(toolbox.typecheck(parsedTree)) + assertEquals("using toolbox typechecker" + LF, wrapCode(typedCode), normalizeEOL(showCode(typedTree))) + } + } + + def assertTreeCode(tree: Tree)(code: String) = { + assertEquals("using quasiquote or given tree"+LF, code.trim, normalizeEOL(showCode(tree))) + } + + def assertPrintedCode(source: String, checkTypedTree: Boolean = true, wrapCode: Boolean = false) = { + if (checkTypedTree) + assertResultCode(source)(source, source, wrapCode) + else assertResultCode(source)(parsedCode = source, wrap = wrapCode) + } + + implicit class StrContextStripMarginOps(val stringContext: StringContext) extends util.StripMarginInterpolator +} + +import PrinterHelper._ + +trait BasePrintTests { + @Test def testIdent = assertTreeCode(Ident("*"))("*") + + @Test def testConstant1 = assertTreeCode(Literal(Constant("*")))("\"*\"") + + @Test def testConstant2 = assertTreeCode(Literal(Constant(42)))("42") + + @Test def testConstantFloat = assertTreeCode(Literal(Constant(42f)))("42.0F") + + @Test def testConstantDouble = assertTreeCode(Literal(Constant(42d)))("42.0") + + @Test def testConstantLong = assertTreeCode(Literal(Constant(42l)))("42L") + + @Test def testOpExpr = assertPrintedCode("(5).+(4)", checkTypedTree = false) + + @Test def testName1 = assertPrintedCode("class test") + + @Test def testName2 = assertPrintedCode("class *") + + @Test def testName4 = assertPrintedCode("class `a*`") + + @Test def testName5 = assertPrintedCode("val :::: = 1") + + @Test def testName6 = assertPrintedCode("val `::::t` = 1") + + @Test def testName7 = assertPrintedCode("""class \/""") + + @Test def testName8 = assertPrintedCode("""class \\\\""") + + @Test def testName9 = assertPrintedCode("""class test_\/""") + + @Test def testName10 = assertPrintedCode("""class `*_*`""") + + @Test def testName11 = assertPrintedCode("""class `a_*`""") + + @Test def testName12 = assertPrintedCode("""class `*_a`""") + + @Test def testName13 = assertPrintedCode("""class a_a""") + + @Test def testName14 = assertPrintedCode("val x$11 = 5") + + @Test def testName15 = assertPrintedCode("class `[]`") + + @Test def testName16 = assertPrintedCode("class `()`") + + @Test def testName17 = assertPrintedCode("class `{}`") + + @Test def testName18 = assertPrintedCode("class <>") + + @Test def testName19 = assertPrintedCode("""class `class`""") + + @Test def testName20 = assertPrintedCode("""class `test name`""") + + @Test def testIfExpr1 = assertResultCode(code = sm""" + |val a = 1 + |if (a > 1) + | a: Int + |else + | (a.toString): String + """)( + parsedCode = sm""" + |val a = 1; + |if (a.>(1)) + | ((a): Int) + |else + | ((a.toString): String)""", + typedCode=sm""" + |val a = 1; + |if (PrintersContext.this.a.>(1)) + | ((PrintersContext.this.a): scala.Int) + |else + | ((PrintersContext.this.a.toString()): scala.Predef.String) + """, wrap = true) + + @Test def testIfExpr2 = assertPrintedCode(sm""" + |class A { + | (if (true) + | { + | false; + | () + | } + |else + | { + | true; + | () + | }).toString() + |}""") + + @Test def testIfExpr3 = assertPrintedCode(sm""" + |class A { + | (if (true) + | { + | false; + | () + | } + |else + | { + | true; + | () + | }).toString().hashCode() + |}""") + + //val x = true && true && false.! + @Test def testBooleanExpr1 = assertPrintedCode("val x = true.&&(true).&&(false.`unary_!`)", checkTypedTree = false) + + //val x = true && !(true && false) + @Test def testBooleanExpr2 = assertPrintedCode("val x = true.&&(true.&&(false).`unary_!`)", checkTypedTree = false) + + @Test def testNewExpr1 = assertResultCode( + code = sm""" + |class foo + |new foo() + |""")( + parsedCode = sm""" + |class foo; + |new foo()""", + typedCode = sm""" + |class foo; + |new PrintersContext.this.foo() + |""", + wrap = true) + + @Test def testNewExpr2 = assertResultCode( + code = sm""" + |class foo + |new foo { "test" } + |""")( + parsedCode = sm""" + |class foo; + |{ + | final class $$anon extends foo { + | "test" + | }; + | new $$anon() + |}""", + typedCode = sm""" + |class foo; + |{ + | final class $$anon extends PrintersContext.this.foo { + | "test" + | }; + | new $$anon() + |}""", + wrap = true) + + @Test def testNewExpr3 = assertPrintedCode(sm""" + |{ + | class foo[t]; + | new foo[scala.Int]() + |}""") + + @Test def testNewExpr4 = assertPrintedCode(sm""" + |{ + | class foo(x: scala.Int); + | val x = 5; + | new foo(x) + |}""") + + @Test def testNewExpr5 = assertPrintedCode(sm""" + |{ + | class foo[t](x: scala.Int); + | val x = 5; + | new foo[scala.Predef.String](x) + |}""") + + //new foo[t](x) { () } + @Test def testNewExpr6 = assertResultCode( + code = sm""" + |class foo[t](x: Int) + |new foo[String](3) { () } + |""")( + parsedCode = sm""" + |{ + | class foo[t](x: Int); + | { + | final class $$anon extends foo[String](3) { + | () + | }; + | new $$anon() + | } + |}""", + typedCode = sm""" + |{ + | class foo[t](x: scala.Int); + | { + | final class $$anon extends foo[scala.Predef.String](3) { + | () + | }; + | new $$anon() + | } + |}""") + + //new foo with bar + @Test def testNewExpr7 = assertPrintedCode(sm""" + |{ + | trait foo; + | trait bar; + | { + | final class $$anon extends foo with bar; + | new $$anon() + | } + |}""") + + //new { anonymous } + @Test def testNewExpr8 = assertPrintedCode(sm""" + |{ + | final class $$anon { + | 5 + | }; + | new $$anon() + |}""") + + //new { val early = 1 } with Parent[Int] { body } + @Test def testNewExpr9 = assertPrintedCode(sm""" + |{ + | class Parent[t]; + | { + | final class $$anon extends { + | val early = 1 + | } with Parent[scala.Int] { + | "testNewExpr" + | }; + | new $$anon() + | } + |}""") + + //new Foo { self => } + @Test def testNewExpr10 = assertPrintedCode(sm""" + |{ + | class Foo; + | { + | final class $$anon extends Foo { self => + | + | }; + | new $$anon() + | } + |}""") + + @Test def testReturn = assertPrintedCode("def test: scala.Int = return 42") + + @Test def testFunc1 = assertResultCode( + code = "List(1, 2, 3).map((i: Int) => i - 1)")( + parsedCode = "List(1, 2, 3).map(((i: Int) => i.-(1)))", + typedCode = sm"scala.collection.immutable.List.apply(1, 2, 3).map(((i: scala.Int) => i.-(1)))(scala.collection.immutable.List.canBuildFrom)") + + @Test def testFunc2 = assertResultCode( + code = "val sum: Seq[Int] => Int = _ reduceLeft (_+_)")( + parsedCode = "val sum: _root_.scala.Function1[Seq[Int], Int] = ((x$1) => x$1.reduceLeft(((x$2, x$3) => x$2.+(x$3))))", + typedCode = "val sum: _root_.scala.Function1[scala.`package`.Seq[scala.Int], scala.Int] = ((x$1) => x$1.reduceLeft(((x$2, x$3) => x$2.+(x$3))))") + + @Test def testFunc3 = assertResultCode( + code = "List(1, 2, 3) map (_ - 1)")( + parsedCode = "List(1, 2, 3).map(((x$1) => x$1.-(1))) ", + typedCode = "scala.collection.immutable.List.apply(1, 2, 3).map(((x$1) => x$1.-(1)))(scala.collection.immutable.List.canBuildFrom)") + + @Test def testImport1 = assertPrintedCode("import scala.collection.mutable") + + @Test def testImport2 = assertPrintedCode("import java.lang.{String=>Str}") + + @Test def testImport3 = assertPrintedCode("import java.lang.{String=>Str, Object=>_, _}") + + @Test def testImport4 = assertPrintedCode("import scala.collection._") +} + +trait ClassPrintTests { + @Test def testClass = assertPrintedCode("class *") + + @Test def testClassWithBody = assertPrintedCode(sm""" + |class X { + | def y = "test" + |}""") + + @Test def testClassWithPublicParams = assertPrintedCode("class X(val x: scala.Int, val s: scala.Predef.String)") + + @Test def testClassWithParams1 = assertPrintedCode("class X(x: scala.Int, s: scala.Predef.String)") + + @Test def testClassWithParams2 = assertPrintedCode("class X(@test x: Int, s: String)", checkTypedTree = false) + + @Test def testClassWithParams3 = assertPrintedCode("class X(implicit x: Int, s: String)", checkTypedTree = false) + + @Test def testClassWithParams4 = assertPrintedCode("class X(implicit @unchecked x: Int, s: String)", checkTypedTree = false) + + @Test def testClassWithParams5 = assertPrintedCode(sm""" + |{ + | class Y { + | val x = 5 + | }; + | class X(override private[this] val x: scala.Int, s: scala.Predef.String) extends Y; + | () + |}""") + + @Test def testClassWithParams6 = assertPrintedCode("class X(@test1 override private[this] val x: Int, @test2(param1 = 7) s: String) extends Y", checkTypedTree = false) + + @Test def testClassWithParams7 = assertPrintedCode("class X protected (val x: scala.Int, val s: scala.Predef.String)") + + @Test def testClassWithParams8 = assertPrintedCode("class X(var x: scala.Int)") + + @Test def testClassWithParams9 = assertPrintedCode("def test(x: scala.Int*) = 5") + + @Test def testClassWithByNameParam = assertPrintedCode("class X(x: => scala.Int)") + + @Test def testClassWithDefault = assertPrintedCode(sm""" + |{ + | class X(var x: scala.Int = 5); + | () + |}""") + + @Test def testClassWithParams10 = assertPrintedCode("class X(protected[zzz] var x: Int)", checkTypedTree = false) + + @Test def testClassWithParams11 = assertPrintedCode(sm""" + |{ + | class F(x: scala.Int); + | trait E { + | var x: scala.Int + | }; + | class X(override var x: scala.Int = 5) extends F(x) with E; + | () + |}""") + + @Test def testClassWithParams12 = assertPrintedCode("class X(val y: scala.Int)()(var z: scala.Double)") + + @Test def testClassWithImplicitParams = assertPrintedCode("class X(var i: scala.Int)(implicit val d: scala.Double, var f: scala.Float)") + + @Test def testClassWithEarly = assertPrintedCode(sm""" + |class X(var i: scala.Int) extends { + | val a = i; + | type B + |} with scala.Serializable""") + + @Test def testClassWithThrow1 = assertPrintedCode(sm""" + |class Throw1 { + | throw new scala.`package`.Exception("exception!") + |}""") + + @Test def testClassWithThrow2 = assertPrintedCode(sm""" + |class Throw2 { + | var msg = " "; + | val e = new scala.`package`.Exception(Throw2.this.msg); + | throw Throw2.this.e + |}""") + + /* + class Test { + val (a, b) = (1, 2) + } + */ + @Test def testClassWithAssignmentWithTuple1 = assertPrintedCode(sm""" + |class Test { + | private[this] val x$$1 = (scala.Tuple2.apply(1, 2): @scala.unchecked) match { + | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2.apply(a, b) + | }; + | val a = Test.this.x$$1._1; + | val b = Test.this.x$$1._2 + |}""") + + @Test def testClassWithAssignmentWithTuple2 = assertResultCode( + code = sm""" + |class Test { + | val (a, b) = (1).->(2) + |}""")( + parsedCode = sm""" + |class Test { + | private[this] val x$$1 = ((1).->(2): @scala.unchecked) match { + | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2(a, b) + | }; + | val a = x$$1._1; + | val b = x$$1._2 + |}""", + typedCode = sm""" + |class Test { + | private[this] val x$$1 = (scala.Predef.ArrowAssoc(1).->(2): @scala.unchecked) match { + | case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2.apply(a, b) + | }; + | val a = Test.this.x$$1._1; + | val b = Test.this.x$$1._2 + |}""") + + /* + class Test { + val List(one, three, five) = List(1,3,5) + } + */ + @Test def testClassWithPatternMatchInAssignment = assertPrintedCode(sm""" + |class Test { + | private[this] val x$$1 = (scala.collection.immutable.List.apply(1, 3, 5): @scala.unchecked) match { + | case scala.collection.immutable.List((one @ _), (three @ _), (five @ _)) => scala.Tuple3.apply(one, three, five) + | }; + | val one = Test.this.x$$1._1; + | val three = Test.this.x$$1._2; + | val five = Test.this.x$$1._3 + |}""") + + //class A(l: List[_]) + @Test def testClassWithExistentialParameter1 = assertPrintedCode(sm""" + |class Test(l: (scala.`package`.List[_$$1] forSome { + | type _$$1 + |}))""") + + @Test def testClassWithExistentialParameter2 = assertPrintedCode(sm""" + |class B(l: (scala.`package`.List[T] forSome { + | type T + |}))""") + + @Test def testClassWithCompoundTypeTree = assertPrintedCode(sm""" + |{ + | trait A; + | trait B; + | abstract class C(val a: A with B) { + | def method(x: A with B with C { + | val x: scala.Float + | }): A with B + | }; + | () + |}""") + + @Test def testClassWithSelectFromTypeTree = assertPrintedCode(sm""" + |{ + | trait A { + | type T + | }; + | class B(t: (A)#T); + | () + |}""") + + @Test def testImplicitClass = assertPrintedCode(sm""" + |{ + | implicit class X(protected[this] var x: scala.Int); + | () + |}""", + checkTypedTree = true) + + @Test def testAbstractClass = assertPrintedCode("abstract class X(protected[this] var x: scala.Int)") + + @Test def testCaseClassWithParams1 = assertPrintedCode(sm""" + |{ + | case class X(x: scala.Int, s: scala.Predef.String); + | () + |}""") + + @Test def testCaseClassWithParams2 = assertPrintedCode(sm""" + |{ + | case class X(protected val x: scala.Int, s: scala.Predef.String); + | () + |}""") + + @Test def testCaseClassWithParams3 = assertPrintedCode(sm""" + |{ + | case class X(implicit x: scala.Int, s: scala.Predef.String); + | () + |}""") + + @Test def testCaseClassWithParams4 = assertPrintedCode(sm""" + |{ + | trait V { + | val x: scala.Int + | }; + | case class X(override val x: scala.Int, s: scala.Predef.String) extends scala.Cloneable; + | () + |}""") + + @Test def testCaseClassWithBody = assertPrintedCode(sm""" + |{ + | case class X() { + | def y = "test" + | }; + | () + |}""") + + @Test def testLocalClass = assertPrintedCode(sm""" + |def test = { + | class X(var a: scala.Int) { + | def y = "test" + | }; + | new X(5) + |}""") + + @Test def testLocalCaseClass = assertPrintedCode(sm""" + |def test = { + | case class X(var a: scala.Int) { + | def y = "test" + | }; + | new X(5) + |}""") + + @Test def testSuperInClass = assertPrintedCode(sm""" + |{ + | trait Root { + | def r = "Root" + | }; + | class X extends Root { + | def superX = super.r + | }; + | class Y extends X with Root { + | class Inner { + | val myY = Y.super.r + | }; + | def fromX = super[X].r; + | def fromRoot = super[Root].r + | }; + | () + |}""") + + @Test def testThisInClass = assertPrintedCode(sm""" + |class Outer { + | class Inner { + | val outer = Outer.this + | }; + | val self = this + |}""") + + @Test def testCaseClassWithParamsAndBody = assertPrintedCode(sm""" + |{ + | case class X(var x: scala.Int, var s: scala.Predef.String) { + | def y = "test" + | }; + | () + |}""") + + @Test def testObject = assertPrintedCode("object *") + + @Test def testObjectWithBody = assertPrintedCode(sm""" + |object X { + | def y = "test" + |}""") + + @Test def testObjectWithEarly1 = assertPrintedCode(sm""" + |object X extends { + | val early: scala.Int = 42 + |} with scala.Serializable""") + + @Test def testObjectWithEarly2 = assertPrintedCode(sm""" + |object X extends { + | val early: scala.Int = 42; + | type EarlyT = scala.Predef.String + |} with scala.Serializable""") + + @Test def testObjectWithSelf = assertPrintedCode(sm""" + |object Foo extends scala.Serializable { self => + | 42 + |}""") + + @Test def testObjectInh = assertPrintedCode(sm""" + |trait Y { + | private[Y] object X extends scala.Serializable with scala.Cloneable + |}""") + + @Test def testObjectWithPatternMatch1 = assertPrintedCode(sm""" + |object PM1 { + | scala.collection.immutable.List.apply(1, 2) match { + | case (i @ _) => i + | } + |}""") + + @Test def testObjectWithPatternMatch2 = assertResultCode( + code = sm""" + |object PM2 { + | List(1, 2).map { + | case i if i > 5 => i + | } + |}""")( + parsedCode = sm""" + |object PM2 { + | List(1, 2).map({ + | case (i @ _) if i.>(5) => i + | }) + |}""") + /* + typedCode = sm""" + |object PM2 { + | scala.collection.immutable.List.apply(1, 2).map(((x0$$1) => x0$$1 match { + | case (i @ _) if i.>(5) => i + | }))(scala.collection.immutable.List.canBuildFrom) + |}""") + * + */ + + @Test def testObjectWithPatternMatch3 = assertResultCode( + code = sm""" + |object PM3 { + | List(1, 2).map { + | case i: Int => i + | } + |}""")( + parsedCode = sm""" + |object PM3 { + | List(1, 2).map({ + | case (i @ ((_): Int)) => i + | }) + |}""") + /* + typedCode = sm""" + |object PM3 { + | scala.collection.immutable.List.apply(1, 2).map(((x0$$2) => x0$$2 match { + | case (i @ ((_): scala.Int)) => i + | }))(scala.collection.immutable.List.canBuildFrom) + |}""") + * + */ + + @Test def testObjectWithPatternMatch4 = assertResultCode( + code = sm""" + |object PM4 { + | List(1, 2).map { + | case _ => 42 + | } + |}""")( + parsedCode = sm""" + |object PM4 { + | List(1, 2).map({ + | case _ => 42 + | }) + |}""") + /* + typedCode = sm""" + |object PM4 { + | scala.collection.immutable.List.apply(1, 2).map(((x0$$3) => x0$$3 match { + | case _ => 42 + | }))(scala.collection.immutable.List.canBuildFrom) + |}""") + * + */ + + @Test def testObjectWithPatternMatch5 = assertResultCode( + code = sm""" + |object PM5 { + | List(1, 2) match { + | case x :: xs => x + | } + |}""")( + parsedCode = sm""" + |object PM5 { + | List(1, 2) match { + | case ::((x @ _), (xs @ _)) => x + | } + |}""", + typedCode = sm""" + |object PM5 { + | scala.collection.immutable.List.apply(1, 2) match { + | case scala.`package`.::((x @ _), (xs @ _)) => x + | } + |}""") + + @Test def testObjectWithPatternMatch6 = assertResultCode( + code = sm""" + |object PM6 { + | List(1, 2).map { + | case (0 | 1) => true + | case _ => false + | } + |}""")( + parsedCode = sm""" + |object PM6 { + | List(1, 2).map({ + | case (0| 1) => true + | case _ => false + | }) + |}""") + /* + typedCode = sm""" + |object PM6 { + | scala.collection.immutable.List.apply(1, 2).map(((x0$$4) => x0$$4 match { + | case (0| 1) => true + | case _ => false + | }))(scala.collection.immutable.List.canBuildFrom) + |}""" + * + */ + + @Test def testObjectWithPatternMatch7 = assertPrintedCode(sm""" + |object PM7 { + | scala.Predef.augmentString("abcde").toList match { + | case scala.collection.Seq((car @ _), _*) => car + | } + |}""") + + @Test def testObjectWithPatternMatch8 = assertPrintedCode(sm""" + |{ + | object Extractor { + | def unapply(i: scala.Int) = scala.Some.apply(i) + | }; + | object PM9 { + | 42 match { + | case (a @ Extractor((i @ _))) => i + | } + | }; + | () + |}""") + + @Test def testObjectWithPartialFunc = assertPrintedCode(sm""" + |object Test { + | def partFuncTest[A, B](e: scala.`package`.Either[A, B]): scala.Unit = e match { + | case scala.`package`.Right(_) => () + | } + |}""") + + @Test def testObjectWithTry = assertResultCode( + code = sm""" + |object Test { + | import java.io._; + | var file: PrintStream = null; + | try { + | val out = new FileOutputStream("myfile.txt"); + | file = new PrintStream(out) + | } catch { + | case ioe: IOException => println("ioe") + | case e: Exception => println("e") + | } finally println("finally") + |}""")( + parsedCode = sm""" + |object Test { + | import java.io._; + | var file: PrintStream = null; + | try { + | val out = new FileOutputStream("myfile.txt"); + | file = new PrintStream(out) + | } catch { + | case (ioe @ ((_): IOException)) => println("ioe") + | case (e @ ((_): Exception)) => println("e") + | } finally println("finally") + |}""", + typedCode = sm""" + |object Test { + | import java.io._; + | var file: java.io.PrintStream = null; + | try { + | val out = new java.io.FileOutputStream("myfile.txt"); + | Test.this.`file_=`(new java.io.PrintStream(out)) + | } catch { + | case (ioe @ ((_): java.io.IOException)) => scala.Predef.println("ioe") + | case (e @ ((_): scala.`package`.Exception)) => scala.Predef.println("e") + | } finally scala.Predef.println("finally") + |}""") +} + +trait TraitPrintTests { + @Test def testTrait = assertPrintedCode("trait *") + + @Test def testTraitWithBody = assertPrintedCode(sm""" + |trait X { + | def y = "test" + |}""") + + @Test def testTraitWithSelfTypeAndBody = assertPrintedCode(sm""" + |trait X { self: scala.Cloneable => + | def y = "test" + |}""") + + @Test def testTraitWithSelf1 = assertPrintedCode(sm""" + |trait X { self => + | def y = "test" + |}""") + + @Test def testTraitWithSelf2 = assertPrintedCode(sm""" + |trait X { self: scala.Cloneable with scala.Serializable => + | val x: scala.Int = 1 + |}""") + + @Test def testTraitTypeParams = assertPrintedCode("trait X[A, B]") + + @Test def testTraitWithBody2 = assertPrintedCode(sm""" + |trait X { + | def foo: scala.Unit; + | val bar: scala.Predef.String + |}""") + + @Test def testTraitWithInh = assertPrintedCode("trait X extends scala.Cloneable with scala.Serializable") + + @Test def testTraitWithEarly1 = assertPrintedCode(sm""" + |trait X extends { + | val x: Int = 1 + |} with AnyRef""", checkTypedTree = false) + + @Test def testTraitWithEarly2 = assertPrintedCode(sm""" + |trait X extends { + | val x: scala.Int = 0; + | type Foo = scala.Unit + |} with scala.Cloneable""") + + @Test def testTraitWithEarly3 = assertPrintedCode(sm""" + |trait X extends { + | val x: scala.Int = 5; + | val y: scala.Double = 4.0; + | type Foo; + | type XString = scala.Predef.String + |} with scala.Serializable""") + + @Test def testTraitWithEarly4 = assertPrintedCode(sm""" + |trait X extends { + | val x: scala.Int = 5; + | val y: scala.Double = 4.0; + | type Foo; + | type XString = scala.Predef.String + |} with scala.Serializable { + | val z = 7 + |}""") + + @Test def testTraitWithSingletonTypeTree = assertPrintedCode(sm""" + |trait Test { + | def testReturnSingleton(): Test.this.type + |}""") + + @Test def testTraitWithThis = assertTreeCode(q"trait Test { this: X with Y => }")(sm""" + |trait Test { _ : X with Y => + | + |}""") + + @Test def testTraitWithWhile1 = assertPrintedCode(sm""" + |trait Test { + | while (false) + | scala.Predef.println("testing...") + | + |}""") + + @Test def testTraitWithWhile2 = assertPrintedCode(sm""" + |trait Test { + | while (true) + | { + | scala.Predef.println("testing..."); + | scala.Predef.println("testing...") + | } + | + |}""") + + @Test def testTraitWithDoWhile1 = assertPrintedCode(sm""" + |trait Test { + | do + | scala.Predef.println("testing...") + | while (true) + |}""") + + @Test def testTraitWithTypes = assertResultCode( + code = sm""" + |trait Test { + | type A = Int; + | type B >: Nothing <: AnyRef; + | protected type C >: Nothing; + | type D <: AnyRef + |}""")( + parsedCode = sm""" + |trait Test { + | type A = Int; + | type B >: Nothing <: AnyRef; + | protected type C >: Nothing; + | type D <: AnyRef + |}""", + typedCode = sm""" + |trait Test { + | type A = scala.Int; + | type B <: scala.AnyRef; + | protected type C; + | type D <: scala.AnyRef + |}""") +} + +trait ValAndDefPrintTests { + @Test def testVal1 = assertPrintedCode("val a: scala.Unit = ()") + + @Test def testVal2 = assertPrintedCode("val * : scala.Unit = ()") + + @Test def testVal3 = assertPrintedCode("val a_ : scala.Unit = ()") + + @Test def testDef1 = assertPrintedCode("def a = ()") + + @Test def testDef2 = assertPrintedCode("def * : scala.Unit = ()") + + @Test def testDef3 = assertPrintedCode("def a_(x: scala.Int): scala.Unit = ()") + + @Test def testDef4 = assertPrintedCode("def a_ : scala.Unit = ()") + + @Test def testDef5 = assertPrintedCode("def a_(* : scala.Int): scala.Unit = ()") + + @Test def testDef6 = assertPrintedCode("def a_(b_ : scala.Int) = ()") + + @Test def testDef7 = assertTreeCode{ + Block( + DefDef(NoMods, newTermName("test1"), Nil, Nil, EmptyTree, Literal(Constant(()))), + DefDef(NoMods, newTermName("test2"), Nil, Nil :: Nil, EmptyTree, Literal(Constant(()))) + ) + }(sm""" + |{ + | def test1 = (); + | def test2() = () + |}""") + + @Test def testDef8 = { + val arg = ValDef(Modifiers(Flag.IMPLICIT) , newTermName("a"), + AppliedTypeTree(Ident(newTypeName("R")), List(Ident(newTypeName("X")))), EmptyTree) + + //def m[X](implicit a: R[X]) = () + val tree = DefDef(NoMods, newTermName("test"), TypeDef(NoMods, newTypeName("X"), Nil, EmptyTree) :: Nil, + List(List(arg)), EmptyTree, Literal(Constant(()))) + + assertTreeCode(tree)("def test[X](implicit a: R[X]) = ()") + } + + @Test def testDef9 = assertPrintedCode("def a(x: scala.Int)(implicit z: scala.Double, y: scala.Float): scala.Unit = ()") + + @Test def testDefWithParams1 = assertPrintedCode("def foo(x: scala.Int*) = ()") + + @Test def testDefWithParams2 = assertPrintedCode(sm""" + |{ + | def foo(x: scala.Int)(y: scala.Int = 1) = (); + | () + |}""") + + @Test def testDefWithTypeParams1 = assertPrintedCode(sm""" + |{ + | def foo[A, B, C](x: A)(y: scala.Int = 1): C = ().asInstanceOf[C]; + | () + |}""") + + @Test def testDefWithTypeParams2 = assertPrintedCode("def foo[A, B <: scala.AnyVal] = ()") + + @Test def testDefWithAnn1 = assertPrintedCode("@annot def foo = null", checkTypedTree = false) + + @Test def testDefWithAnn2 = assertPrintedCode("@a(x) def foo = null", checkTypedTree = false) + + @Test def testDefWithAnn3 = assertPrintedCode("@Foo[A, B] def foo = null", checkTypedTree = false) + + @Test def testDefWithAnn4 = assertPrintedCode("@Foo(a)(b)(x, y) def foo = null", checkTypedTree = false) + + @Test def testDefWithAnn5 = assertPrintedCode("@Foo[A, B](a)(b) @Bar def foo(x: Int) = null", checkTypedTree = false) + + @Test def testDefWithAnn6 = assertPrintedCode("@test1(new test2()) def foo = 42", checkTypedTree = false) + + @Test def testDefWithAnn7 = assertPrintedCode("@`t*` def foo = 42", checkTypedTree = false) + + @Test def testDefWithAnn8 = assertPrintedCode("@throws(classOf[Exception]) def foo = throw new Exception()", checkTypedTree = false) + + @Test def testAnnotated1 = assertResultCode( + code = "def foo = 42: @baz")( + parsedCode = "def foo = 42: @baz", + typedCode = "def foo = (42: @baz)", + wrap = true) + + @Test def testAnnotated2 = assertResultCode( + code = "def foo = 42: @foo2[A1, B1](4)(2)")( + parsedCode = "def foo = 42: @foo2[A1, B1](4)(2)", + typedCode = "def foo = (42: @foo2[A1, B1](4)(2))", + wrap = true) + + @Test def testAnnotated3 = assertResultCode( + code = "def foo = (42: @foo1[A1, B1]): @foo2[A1, B1](4)(2)")( + parsedCode = "def foo = (42: @foo1[A1, B1]): @foo2[A1, B1](4)(2)", + typedCode = "def foo = ((42: @foo1[A1, B1]): @foo2[A1, B1](4)(2))", + wrap = true) + + @Test def testAnnotated4 = assertResultCode( + code = "def foo = 42: @foo3[A1, B1](4)(2.0F, new foo1[A1, B1]())")( + parsedCode = "def foo = 42: @foo3[A1, B1](4)(2.0F, new foo1[A1, B1]())", + typedCode = "def foo = (42: @foo3[A1, B1](4)(2.0F, new foo1[A1, B1]()))", + wrap = true) + + @Test def testAnnotated5 = assertPrintedCode(sm""" + |{ + | val x = 5; + | (x: @unchecked) match { + | case ((_): scala.Int) => true + | case _ => false + | } + |}""") + + @Test def testAnnotated8 = assertPrintedCode(sm""" + |{ + | val x = 5; + | ((x: @unchecked): @foo3(4)(2.0F, new foo1[A1, B1]())) match { + | case _ => true + | } + |}""", wrapCode = true) +} + +trait PackagePrintTests { + @Test def testPackage1 = assertPrintedCode(sm""" + |package foo.bar { + | + |}""", checkTypedTree = false) + + @Test def testPackage2 = assertPrintedCode(sm""" + |package foo { + | class C + | + | object D + |}""", checkTypedTree = false) + + //package object foo extends a with b + @Test def testPackage3 = assertPrintedCode(sm""" + |package foo { + | object `package` extends a with b + |}""", checkTypedTree = false) + + //package object foo { def foo; val x = 1 } + @Test def testPackage4 = assertPrintedCode(sm""" + |package foo { + | object `package` { + | def foo: scala.Unit = (); + | val x = 1 + | } + |}""", checkTypedTree = false) + + //package object foo extends { val x = 1; type I = Int } with Any + @Test def testPackage5 = assertPrintedCode(sm""" + |package foo { + | object `package` extends { + | val x = 1; + | type I = Int + | } with AnyRef + |}""", checkTypedTree = false) +} + +trait QuasiTreesPrintTests { + @Test def testQuasiIdent = assertTreeCode(q"*")("*") + + @Test def testQuasiVal = assertTreeCode(q"val * : Unit = null")("val * : Unit = null") + + @Test def testQuasiDef = assertTreeCode(q"def * : Unit = null")("def * : Unit = null") + + @Test def testQuasiTrait = assertTreeCode(q"trait *")("trait *") + + @Test def testQuasiClass = assertTreeCode(q"class *")("class *") + + @Test def testQuasiClassWithPublicParams = assertTreeCode(q"class X(val x: Int, val s:String)")("class X(val x: Int, val s: String)") + + @Test def testQuasiClassWithParams = assertTreeCode(q"class X(x: Int, s:String)")("class X(x: Int, s: String)") + + @Test def testQuasiObject = assertTreeCode(q"object *")("object *") + + @Test def testQuasiObjectWithBody = assertTreeCode(q"""object X{ def y = "test" }""")(sm""" + |object X { + | def y = "test" + |}""") + + @Test def testQuasiClassWithBody = assertTreeCode(q"""class X{ def y = "test" }""")(sm""" + |class X { + | def y = "test" + |}""") + + @Test def testQuasiTraitWithBody = assertTreeCode(q"""trait X{ def y = "test" }""")(sm""" + |trait X { + | def y = "test" + |}""") + + @Test def testQuasiTraitWithSelfTypeAndBody = assertTreeCode(q"""trait X{ self: Order => def y = "test" }""")(sm""" + |trait X { self: Order => + | def y = "test" + |}""") + + @Test def testQuasiTraitWithSelf = assertTreeCode(q"""trait X{ self => def y = "test" }""")(sm""" + |trait X { self => + | def y = "test" + |}""") + + @Test def testQuasiCaseClassWithBody = assertTreeCode(q"""case class X() { def y = "test" }""")(sm""" + |case class X() { + | def y = "test" + |}""") + + @Test def testQuasiCaseClassWithParamsAndBody = assertTreeCode(q"""case class X(x: Int, s: String){ def y = "test" }""")(sm""" + |case class X(x: Int, s: String) { + | def y = "test" + |}""") +} +*/
\ No newline at end of file |