scalac -Yshow-trees -Xprint:typer TwoStatements.scala
scalac -Yshow-trees-compact -Xprint:typer TwoStatements.scala
scalac -Yshow-trees-stringified -Xprint:typer TwoStatements.scala
scalac -Ybrowse:typer TwoStatements.scala
注こと。したがって、自分のプラグインが実行されているフェーズに適したフェーズを選択してください。
-Yshow-trees-compact
は、自分のコードで使用するものに正確に(またはかなり近い)出力を生成するものですが、読む。
他のものは読みやすく、独自のコードに翻訳するのは混乱するかもしれません。 -Yshow-trees-stringified
は、ほとんどの情報を表示するので、-Yshow-trees
より役立つでしょう。一方、-Ybrowse:typer
はインタラクティブで、選択したツリーノードのコードを表示します。これは、特に大きなプログラムを見る場合に便利です。それでは、私は示唆していますが、あなたが処理したいコードが変換される方法を見ていることである
Apply(
Select(
Select(This(newTypeName("Test")), newTermName("five")), // assigned to rcvr
newTermName("$div") // compared to nme.DIV
),
List(Literal(Constant(0)))) // as is
)
:リンクされたブログの例で-Yshow-trees-compact
をしようとした場合
、あなたはこのスニペットが表示されますプラグインが動作しているフェーズに入り、スニペットをつかんで、関心のない部分があればそれを変数に置き換えてください。
すべてDefDef
には本文が6番目の要素として含まれています。複数のステートメントのList
を持つBlock
があり、メソッド呼び出し(Apply
)、ゲッター(Select
)、アサイメント(Assign
)、ifステートメント(If
)などがあります。 ValDef
のような他の種類の宣言にも、コードが関連付けられています。
tree @ Statement(...)
のようなものをお探しの場合は存在しません。コードを表すものを識別するためにTermTree
(より良い方法ではisTerm
)を使用できますが、式の一部または完全なブロックから文を区別することはできません。
実際のコードのASTを見て、それがどのように機能するかを学んでください。a presentationを見て
EDIT
はちょうどscala/reflecti/api/Trees.scala
ファイルの末尾にこのコメントに私をclued:あなたが仕事を示唆
// A standard pattern match
case EmptyTree =>
case PackageDef(pid, stats) =>
// package pid { stats }
case ClassDef(mods, name, tparams, impl) =>
// mods class name [tparams] impl where impl = extends parents { defs }
case ModuleDef(mods, name, impl) => (eliminated by refcheck)
// mods object name impl where impl = extends parents { defs }
case ValDef(mods, name, tpt, rhs) =>
// mods val name: tpt = rhs
// note missing type information is expressed by tpt = TypeTree()
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
// mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs
// note missing type information is expressed by tpt = TypeTree()
case TypeDef(mods, name, tparams, rhs) => (eliminated by erasure)
// mods type name[tparams] = rhs
// mods type name[tparams] >: lo <: hi, where lo, hi are in a TypeBoundsTree,
and DEFERRED is set in mods
case LabelDef(name, params, rhs) =>
// used for tailcalls and like
// while/do are desugared to label defs as follows:
// while (cond) body ==> LabelDef($L, List(), if (cond) { body; L$() } else())
// do body while (cond) ==> LabelDef($L, List(), body; if (cond) L$() else())
case Import(expr, selectors) => (eliminated by typecheck)
// import expr.{selectors}
// Selectors are a list of pairs of names (from, to).
// The last (and maybe only name) may be a nme.WILDCARD
// for instance
// import qual.{x, y => z, _} would be represented as
// Import(qual, List(("x", "x"), ("y", "z"), (WILDCARD, null)))
case Template(parents, self, body) =>
// extends parents { self => body }
// if self is missing it is represented as emptyValDef
case Block(stats, expr) =>
// { stats; expr }
case CaseDef(pat, guard, body) => (eliminated by transmatch/explicitouter)
// case pat if guard => body
case Alternative(trees) => (eliminated by transmatch/explicitouter)
// pat1 | ... | patn
case Star(elem) => (eliminated by transmatch/explicitouter)
// pat*
case Bind(name, body) => (eliminated by transmatch/explicitouter)
// name @ pat
case UnApply(fun: Tree, args) (introduced by typer, eliminated by transmatch/explicitouter)
// used for unapply's
case ArrayValue(elemtpt, trees) => (introduced by uncurry)
// used to pass arguments to vararg arguments
// for instance, printf("%s%d", foo, 42) is translated to after uncurry to:
// Apply(
// Ident("printf"),
// Literal("%s%d"),
// ArrayValue(<Any>, List(Ident("foo"), Literal(42))))
case Function(vparams, body) => (eliminated by lambdaLift)
// vparams => body where vparams:List[ValDef]
case Assign(lhs, rhs) =>
// lhs = rhs
case AssignOrNamedArg(lhs, rhs) => (eliminated by typer, resurrected by reifier)
// @annotation(lhs = rhs)
case If(cond, thenp, elsep) =>
// if (cond) thenp else elsep
case Match(selector, cases) =>
// selector match { cases }
case Return(expr) =>
// return expr
case Try(block, catches, finalizer) =>
// try block catch { catches } finally finalizer where catches: List[CaseDef]
case Throw(expr) =>
// throw expr
case New(tpt) =>
// new tpt always in the context: (new tpt).<init>[targs](args)
case Typed(expr, tpt) => (eliminated by erasure)
// expr: tpt
case TypeApply(fun, args) =>
// fun[args]
case Apply(fun, args) =>
// fun(args)
// for instance fun[targs](args) is expressed as Apply(TypeApply(fun, targs), args)
case ApplyDynamic(qual, args) (introduced by erasure, eliminated by cleanup)
// fun(args)
case Super(qual, mix) =>
// qual.super[mix] qual is always This(something), if mix is empty, it is tpnme.EMPTY
case This(qual) =>
// qual.this
case Select(qualifier, selector) =>
// qualifier.selector
case Ident(name) =>
// name
// note: type checker converts idents that refer to enclosing fields or methods
// to selects; name ==> this.name
case ReferenceToBoxed(ident) => (created by typer, eliminated by lambdalift)
// synthetic node emitted by macros to reference capture vars directly without going through ``elem''
// var x = ...; fun { x } will emit Ident(x), which gets transformed to Select(Ident(x), "elem")
// if ReferenceToBoxed were used instead of Ident, no transformation would be performed
case Literal(value) =>
// value
case TypeTree() => (introduced by refcheck)
// a type that's not written out, but given in the tpe attribute
case Annotated(annot, arg) => (eliminated by typer)
// arg @annot for types, arg: @annot for exprs
case SingletonTypeTree(ref) => (eliminated by uncurry)
// ref.type
case SelectFromTypeTree(qualifier, selector) => (eliminated by uncurry)
// qualifier # selector, a path-dependent type p.T is expressed as p.type # T
case CompoundTypeTree(templ: Template) => (eliminated by uncurry)
// parent1 with ... with parentN { refinement }
case AppliedTypeTree(tpt, args) => (eliminated by uncurry)
// tpt[args]
case TypeBoundsTree(lo, hi) => (eliminated by uncurry)
// >: lo <: hi
case ExistentialTypeTree(tpt, whereClauses) => (eliminated by uncurry)
// tpt forSome { whereClauses }
コマンドが、私はにScalaのコードを探していますCompilationUnitツリーからステートメントを取得できるコンパイラプラグインを入れてください。ありがとう。 –
@BrianTarbox "ステートメント"を定義し、その定義をScala仕様の観点から行います。それ以外は正確な答えを与えることができます。そうしないと、実際のコードを検索し、取得したいものがどのように表現されているかを特定する必要があります。 –
@BrianTarbox別のプレゼンテーションで見たことだけを追加しました。それは完全なパターンマッチのように見えるでしょう。 –