dotty tools で遊んでみる
dotty tools 触ってみるぞい
Driver
dotty compiler でコンパイルを実行するための class
InteractiveDriver
IDE から dotty compiler を利用するときのために作られた Driver subclass、多分ここがエンドポイント
使ってみる
こういうプロジェクトで sbt console でいろいろ
code:project/plugins.sbt
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.6")
code:build.sbt
val dottyVersion = "3.0.0-M2"
lazy val root = project
.in(file("."))
.settings(
name := "dotty-simple",
version := "0.1.0",
scalaVersion := dottyVersion,
libraryDependencies += "org.scala-lang" %% "scala3-compiler" % scalaVersion.value,
libraryDependencies += "org.scala-lang" %% "scala3-library" % scalaVersion.value
)
code:scala
scala> import dotty.tools.dotc.interactive.InteractiveDriver
scala> val driver = new InteractiveDriver(List.empty)
dotty.tools.dotc.MissingCoreLibraryException: Could not find package scalaShadowing from compiler core libraries.
Make sure the compiler core libraries are on the classpath.
もうだめだ〜〜
scala3-library ってやつを class path に渡せば良いってこと?
scala3-library とかはどこにあるんだろうか???
sbt show runtime:fullClasspath でロードしてる classpath 全部みてみる ~/Library/Caches/Coursier/ 以下だった
code:scala
scala> val drive = new InteractiveDriver(List("-classpath", "/Users/tanishiking/Library/Caches/Coursi
er/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3.0.0-M2/3.0.0-M2/scala3-library_3.0
.0-M2-3.0.0-M2.jar"))
死ななかった!
コンパイル対象のコードを用意する。 virtual の第一引数に与えたパスに実際にアクセスすることはないはず(表示のためのみのはず)
code:scala
scala> val source = "object X { class A {} }"
val source: String = object X { class A {} }
scala> val uri = new URI("file:///foo/bar")
val uri: java.net.URI = file:///foo/bar
scala> val virtualFile = SourceFile.virtual(Paths.get(uri).toString, source)
val virtualFile: dotty.tools.dotc.util.SourceFile = /foo/bar
scala> driver.run(new URI("file:///Users/tanishiking/hoge.scala"), "object X { }")
java.lang.ClassCastException: class dotty.tools.dotc.core.Symbols$NoSymbol$ cannot be cast to class dotty.tools.dotc.core.Symbols$ClassSymbol (dotty.tools.dotc.core.Symbols$NoSymbol$ and dotty.tools.dotc.core.Symbols$ClassSymbol are in unnamed module of loader sbt.internal.inc.classpath.ClasspathUtil$$anon$2 @521db1dd)
scala> driver.run(uri, "class X {}")
scala> driver.openedFiles
scala> driver.openedTrees(uri)
val res27: Listdotty.tools.dotc.interactive.SourceTree = List(SourceTree(TypeDef(X,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,EmptyTree,EmptyTree),List())),/foo/bar)) う〜ん? 空の class 定義以外はほとんど NoSymbol cast うんちゃらエラーで死ぬのなぜ?? 助けて〜〜〜
openedTrees はなんで Tree の List を返すんだ??? -> ファイルに対して複数の top level tree が帰ってくるのは普通じゃい!
code:scala
scala> import dotty.tools.dotc.util.Spans
scala> import dotty.tools.dotc.util.SourcePosition
scala> import dotty.tools.dotc.core.Contexts._
scala> given ctx as Context= driver.currentCtx
lazy val ctx: dotty.tools.dotc.core.Contexts.Context
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(3))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<3..3>
The official standard library for Scala 3.0 is the Scala 2.13 library. Not only the source code is unchanged but it is even not compiled and published under 3.0. It could be, but it would be useless because, as we have seen, a Scala 3.0 module can depend on a Scala 2.13 artifact.
そうなのか、classpath に 2.13.4 の scala-library も追加したほうが良いのか?? これでどうよ
code:scala
scala> val classpaths = Seq(
| "/Users/tanishiking/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala3-library_3.0.0-M2/3.0.0-M2/scala3-library_3.0.0-M2-3.0.0-M2.jar",
| "/Users/tanishiking/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.4/scala-library-
2.13.4.jar"
| )
scala> val driver = new InteractiveDriver(List("-classpath", classpaths.mkString(java.io.File.pathSeparator)))
val driver: dotty.tools.dotc.interactive.InteractiveDriver = dotty.tools.dotc.interactive.InteractiveDriver@4123624c
scala> driver.run(uri, "object X { def x = 1; def y = 3 }")
scala> driver.run(uri, "object X { def x = 1; def y = }")
val res6: Listdotty.tools.dotc.reporting.Diagnostic = List(class dotty.tools.dotc.reporting.Diagnostic$Error at /foo/bar:<31..31>: expression expected but '}' found, class dotty.tools.dotc.reporting.Diagnostic$Info at ?: 1 error found) いけるじゃん!
code:scala
scala> val source = "object X { case class Y () }"
val source: String = object X { case class Y () }
scala> driver.run(uri, source)
scala> driver.openedTrees(uri).head.tree
val res16: dotty.tools.dotc.ast.tpd.Import | dotty.tools.dotc.ast.tpd.NameTree = TypeDef(X$,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,SingletonTypeTree(Ident(X)),EmptyTree),List(TypeDef(Y,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), Select(Select(Ident(_root_),scala),Product), Select(Select(Ident(_root_),scala),Serializable)),ValDef(_,EmptyTree,EmptyTree),List(DefDef(copy,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y),Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y)),<init>),List()))))), ValDef(Y,Ident(Y$),Apply(Select(New(Ident(Y$)),<init>),List())), TypeDef(Y$,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), AppliedTypeTree(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),trait Function0),List(TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y)))),ValDef(_,SingletonTypeTree(Ident(Y)),EmptyTree),List(DefDef(apply,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y),Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y)),<init>),List())), DefDef(unapply,List(),List(List(ValDef(x$1,TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y),EmptyTree))),SingletonTypeTree(Literal(Constant(true))),Literal(Constant(true))), DefDef(toString,List(),List(),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class String),Literal(Constant(Y))))))))) Interactive.enclosingTree
position を囲う最も近い構文木を取得する
code:scala
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf("Y")))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<22..22>
scala> Interactive.enclosingTree(driver.openedTrees(uri), pos)
val res17: dotty.tools.dotc.ast.tpd.Tree = TypeDef(Y,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), Select(Select(Ident(_root_),scala),Product), Select(Select(Ident(_root_),scala),Serializable)),ValDef(_,EmptyTree,EmptyTree),List(DefDef(copy,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y),Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class X$)),class Y)),<init>),List()))))) Completion.completions
code:scala
scala> val source = "object X { def x = 1. } "
val source: String = "object X { def x = 1. } "
scala> driver.run(uri, source)
val res20: Listdotty.tools.dotc.reporting.Diagnostic = List(class dotty.tools.dotc.reporting.Diagnostic$Error at /foo/bar:<22..22>: an identifier expected, but '}' found, class dotty.tools.dotc.reporting.Diagnostic$Info at ?: 1 error found) scala> driver.openedTrees(uri)
val res22: Listdotty.tools.dotc.interactive.SourceTree = List(SourceTree(TypeDef(X$,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,SingletonTypeTree(Ident(X)),EmptyTree),List(DefDef(x,List(),List(),TypeTreedotty.tools.dotc.core.Types$UnspecifiedErrorType$@32617a55,Select(Literal(Constant(1)),<error>))))),/foo/bar)) scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf(".") + 1))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<21..21>
不完全な構文木だが、パース結果は保持されている
code:scala
scala> given ctx as Context= driver.currentCtx
lazy val ctx: dotty.tools.dotc.core.Contexts.Context
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf(".") + 1))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<21..21>
scala> Completion.completions(pos)(using ctx.fresh.setCompilationUnit(driver.compilationUnits.get(uri).get))
val res29: (Int, Listdotty.tools.dotc.interactive.Completion) = (22,List(Completion(unifiedPrimitiveEquals,(x: Any): Boolean,List(method unifiedPrimitiveEquals)), Completion(<=,(x: Double): Boolean,List(method <=)), Completion(isValidChar,=> Boolean,List(method isValidChar)), Completion(isPosInfinity,=> Boolean,List(method isPosInfinity)), Completion(min,(that: Float): Float,List(method min)), Completion(signum,=> Int,List(method signum)), Completion(→,B(y: B): (A, B),List(method →)), Completion(isValidLong,=> Boolean,List(method isValidLong)), Completion(equals,(x$0: Any): Boolean,List(method equals)), Completion(self,=> Float,List(method self)), Completion(>>,(x: Long): Int,List(method >>)), Completion(wait,(x$0: Long, x$1: Int): Unit,List(method wait)), Completion(floatValue,(): Float,List(method floatValue)), Completion(*,(x: Double): Double,List(method *)), Completion(ceil,=> Float,List(method ceil)), Completion(notifyAll,(): Unit,List(method notifyAll)), Completion(-,(x: Double): Double,List(method -)), Completion(isNaN,=> Boolean,List(method isNaN)), Completion(toLong,=> Long,List(method toLong)), Completion(toDouble,=> Double,List(method toDouble)), Completion(isInfinite,(): Boolean,List(method isInfinite)), Completion(ensuring,(cond: A => Boolean, msg: => Any): A,List(method ensuring)), Completion(toFloat,=> Float,List(method toFloat)), Completion(toInt,=> Int,List(method toInt)), Completion(num,=> FractionalFloat,List(method num)), Completion(asInstanceOf,X0 => X0,List(method asInstanceOf)), Completion(round,=> Int,List(method round)), Completion(isFinite,=> Boolean,List(method isFinite)), Completion(isInfinity,=> Boolean,List(method isInfinity)), Completion(notify,(): Unit,List(method notify)), Completion(finalize,(): Unit,List(method finalize)), Completion(intValue,(): Int,List(method intValue)), Completion(toByte,=> Byte,List(method toByte)), Completion(>>>,(x: Long): Int,List(method >>>)), Completion(==,(x: Double): Boolean,List(method ==)), Completion(toString,(): String,List(method toString)), Completion(unifiedPrimitiveHashcode,=> Int,List(method unifiedPrimitiveHashcode)), Completion(clone,(): Object,List(method clone)), Completion(toHexString,=> String,List(method toHexString)), Completion(+,(x: Double): Double,List(method +)), Completion(hashCode,(): Int,List(method hashCode)), Completion(toBinaryString,=> String,List(method toBinaryString)), Completion(formatted,(fmtstr: String): String,List(method formatted)), Completion(>,(x: Double): Boolean,List(method >)), Completion(max,(that: Float): Float,List(method max)), Completion(compareTo,(x$0: Long): Int,List(method compareTo)), Completion(getClass,X0 >: (Any.this : Any)(): Class? <: X0,List(method getClass)), Completion(ne,(x$0: Object): Boolean,List(method ne)), Completion(toDegrees,=> Float,List(method toDegrees)), Completion(isInstanceOf,X0 => Boolean,List(method isInstanceOf)), Completion(byteValue,(): Byte,List(method byteValue)), Completion(longValue,(): Long,List(method longValue)), Completion(/,(x: Double): Double,List(method /)), Completion(sign,=> T,List(method sign)), Completion(->,B(y: B): (A, B),List(method ->)), Completion(unary_-,=> Int,List(method unary_-)), Completion(to,(end: T, step: T): scala.collection.immutable.NumericRange.InclusiveT,List(method to)), Completion(^,(x: Long): Long,List(method ^)), Completion(isWhole,=> Boolean,List(method isWhole)), Completion(toChar,=> Char,List(method toChar)), Completion(##,=> Int,List(method ##)), Completion(abs,=> Float,List(method abs)), Completion(!=,(x: Double): Boolean,List(method !=)), Completion(doubleValue,(): Double,List(method doubleValue)), Completion(eq,(x$0: Object): Boolean,List(method eq)), Completion(floor,=> Float,List(method floor)), Completion(toShort,=> Short,List(method toShort)), Completion(isValidShort,=> Boolean,List(method isValidShort)), Completion(isNegInfinity,=> Boolean,List(method isNegInfinity)), Completion(&,(x: Long): Long,List(method &)), Completion(isValidByte,=> Boolean,List(method isValidByte)), Completion(<,(x: Double): Boolean,List(method <)), Completion(<<,(x: Long): Int,List(method <<)), Completion(shortValue,(): Short,List(method shortValue)), Completion(synchronized,X0(x$0: X0): X0,List(method synchronized)), Completion(compare,(y: T): Int,List(method compare)), Completion(unary_~,=> Int,List(method unary_~)), Completion(|,(x: Long): Long,List(method |)), Completion(%,(x: Double): Double,List(method %)), Completion(isValidInt,=> Boolean,List(method isValidInt)), Completion(toRadians,=> Float,List(method toRadians)), Completion(until,(end: T, step: T): scala.collection.immutable.NumericRange.ExclusiveT,List(method until)), Completion(>=,(x: Double): Boolean,List(method >=)), Completion(toOctalString,=> String,List(method toOctalString)), Completion(ord,=> OrderingFloat,List(method ord)), Completion(unary_+,=> Int,List(method unary_+)))) 多すぎ!!! toString を補完してもらってみよう
code:scala
scala> val source = "object X { def x = 1.toSt } "
val source: String = "object X { def x = 1.toSt } "
scala> driver.run(uri, source)
val res32: Listdotty.tools.dotc.reporting.Diagnostic = List(class dotty.tools.dotc.reporting.Diagnostic$Error at /foo/bar:19..21..25: value toSt is not a member of Int - did you mean (1 : Int).toInt?, class dotty.tools.dotc.reporting.Diagnostic$Info at ?: 1 error found) scala> given ctx as Context= driver.currentCtx
lazy val ctx: dotty.tools.dotc.core.Contexts.Context
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf("toSt") + "toSt".length))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<25..25>
scala> Completion.completions(pos)(using ctx.fresh.setCompilationUnit(driver.compilationUnits.get(uri).get))
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf("toSt") + "to".length))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<23..23>
scala> Completion.completions(pos)(using ctx.fresh.setCompilationUnit(driver.compilationUnits.get(uri).get))
val res36: (Int, Listdotty.tools.dotc.interactive.Completion) = (21,List(Completion(toFloat,=> Float,List(method toFloat)), Completion(toInt,=> Int,List(method toInt)), Completion(toByte,=> Byte,List(method toByte)), Completion(toString,(): String,List(method toString)), Completion(toHexString,=> String,List(method toHexString)), Completion(toBinaryString,=> String,List(method toBinaryString)), Completion(toDegrees,=> Float,List(method toDegrees)), Completion(to,(end: T, step: T): scala.collection.immutable.NumericRange.InclusiveT,List(method to)), Completion(toChar,=> Char,List(method toChar)), Completion(toShort,=> Short,List(method toShort)), Completion(toRadians,=> Float,List(method toRadians)), Completion(toOctalString,=> String,List(method toOctalString)), Completion(toLong,=> Long,List(method toLong)), Completion(toDouble,=> Double,List(method toDouble)))) いいね、prefix マッチで絞り込んでくれてる
Interactive.findDefinitions
code:scala
scala> val source = "object X { def x = 1; val y = x + 1 }"
val source: String = object X { def x = 1; val y = x + 1 }
scala> driver.run(uri, source)
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf("x + 1")))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<30..30>
scala> val path = Interactive.pathTo(driver.openedTrees(uri), pos)
val path: Listdotty.tools.dotc.ast.tpd.Tree = List(Ident(x), Select(Ident(x),+), Apply(Select(Ident(x),+),List(Literal(Constant(1)))), ValDef(y,TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int),Apply(Select(Ident(x),+),List(Literal(Constant(1))))), Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,SingletonTypeTree(Ident(X)),EmptyTree),List(DefDef(x,List(),List(),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int),Literal(Constant(1))), ValDef(y,TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int),Apply(Select(Ident(x),+),List(Literal(Constant(1))))))), TypeDef(X$,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,SingletonTypeTree(Ident(X)),EmptyTree),List(DefDef(x,List(),List(),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int),Literal(Constant(1))), ValDef(y,TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Int),Apply(Select(Ident(x),+),List(Literal(Constant(1))))))))) scala> Interactive.findDefinitions(path, pos, driver)
scala> Interactive.findDefinitions(path, pos, driver).head.pos
val res42: dotty.tools.dotc.util.SourcePosition = /foo/bar:11..15..20 scala> source.slice(11, 20)
val res43: String = def x = 1
すげ〜
型の名前とか外部ライブラリの definition は見つけられるんか?
code:scala
scala> val source = "object X { given stringToInt as ConversionString, Int { def apply(str: String): Int = str.length } }" val source: String = object X { given stringToInt as ConversionString, Int { def apply(str: String): Int = str.length } } scala> driver.run(uri, source)
scala> val pos = new SourcePosition(driver.openedFiles(uri), Spans.Span(source.indexOf("String") + 1))
val pos: dotty.tools.dotc.util.SourcePosition = /foo/bar:<44..44>
scala> val path = Interactive.pathTo(driver.openedTrees(uri), pos)
scala> Interactive.findDefinitions(path, pos, driver)
だめ~?
code:scala
scala> given ctx as Context= driver.currentCtx
lazy val ctx: dotty.tools.dotc.core.Contexts.Context
scala> Interactive.enclosingSourceSymbols(path, pos)
symbol は見つかってて...
うーん
hr.icon
Context
compiler のいろんなところに設定を与えるためのなんか設定的なやつ
hr.icon
Mode
initCtx.fresh.addMode(Mode.ReadPositions).addMode(Mode.Interactive).addMode(Mode.ReadComments) みたいな感じで Context に Mode を追加して、compiler の動作を制御できる設計になっている。
例えば
Mode.Interactive
Mode.ReadPositions
hr.icon
Scala3 Parser で遊んでみる
code:scala
scala> import dotty.tools.dotc.core.Contexts._
scala> given Context = (new ContextBase).initialCtx
lazy val given_Context: dotty.tools.dotc.core.Contexts.Context
scala> import dotty.tools.dotc.parsing.Parsers
scala> import dotty.tools.dotc.util.SourceFile
scala> val parser = new Parsers.Parser(SourceFile.virtual("<meta>", "class X {} extends Base;"))
val parser: dotty.tools.dotc.parsing.Parsers.Parser = dotty.tools.dotc.parsing.Parsers$Parser@175db8b0
scala> parser.parse()
val res1: dotty.tools.dotc.ast.untpd.Tree = PackageDef(Ident(<empty>),List(TypeDef(X,Template(DefDef(<init>,List(),List(),TypeTree,EmptyTree),List(),ValDef(_,EmptyTree,EmptyTree),List(EmptyTree)))))
hr.icon
metals から使ってみる
code:scala
package a
object A {
trait Base {
def foo(x: Int): Int
def bar(x: String): String
}
class <<Concrete>> extends Base {
}
}
pos に <<Concrete>> の先頭部分にして
pathTo
pathTo は pos の外側にある木からどんどん外側に辿っていく
class Concrete extends Base {} -> { ... class Concrete ... } -> object A { ... } と辿っている
code:scala
TypeDef(Concrete,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), Ident(Base)),ValDef(_,EmptyTree,EmptyTree),List())) code:scala
Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,SingletonTypeTree(Ident(A)),EmptyTree),List(TypeDef(Base,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),ValDef(_,EmptyTree,EmptyTree),List(DefDef(foo,List(),List(List(ValDef(x,Ident(Int),EmptyTree))),Ident(Int),EmptyTree), DefDef(bar,List(),List(List(ValDef(x,Ident(String),EmptyTree))),Ident(String),EmptyTree)))), TypeDef(Concrete,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), Ident(Base)),ValDef(_,EmptyTree,EmptyTree),List())))) code:scala
TypeDef(A$,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List())),ValDef(_,SingletonTypeTree(Ident(A)),EmptyTree),List(TypeDef(Base,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),ValDef(_,EmptyTree,EmptyTree),List(DefDef(foo,List(),List(List(ValDef(x,Ident(Int),EmptyTree))),Ident(Int),EmptyTree), DefDef(bar,List(),List(List(ValDef(x,Ident(String),EmptyTree))),Ident(String),EmptyTree)))), TypeDef(Concrete,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), Ident(Base)),ValDef(_,EmptyTree,EmptyTree),List()))))) enclosingTree
code:scala
TypeDef(Concrete,Template(DefDef(<init>,List(),List(List()),TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Unit),EmptyTree),List(Apply(Select(New(TypeTreeTypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object)),<init>),List()), Ident(Base)),ValDef(_,EmptyTree,EmptyTree),List()))