ClassDef()がどれぐらい呼び出されているか調べる
もしも、ClassDef()と同レベルに新しい文法と追加したら、
それに伴って変更しなければいけないファイルがどれぐらいあるか調べたいので、以下のコマンドで調べてみました。
$ find . -name *.scala -print | xargs grep ClassDef
その結果が以下。
長過ぎるので、途中は省略しています。
./compiler/scala/reflect/macros/compiler/Resolvers.scala: val invoker = atPos(bundleClass.pos)(ClassDef(NoMods, invokerName, Nil, Template(List(Ident(bundleClass)), emptyValDef, List(contextField, invokerCtor))))
./compiler/scala/reflect/reify/package.scala: val enclosingClasses = typer0.context.enclosingContextChain map (_.tree) collect { case classDef: ClassDef => classDef }
./compiler/scala/reflect/reify/phases/Reshape.scala: case classDef @ ClassDef(mods, name, params, impl) =>
…(略)...
./compiler/scala/tools/nsc/ast/parser/Parsers.scala: * TmplDef ::= [case] class ClassDef
./compiler/scala/tools/nsc/typechecker/Unapplies.scala: // `enterClassDef`), the case class ClassDef is added as an attachment to the
./reflect/scala/reflect/api/Trees.scala: abstract class ClassDefExtractor {
./reflect/scala/reflect/internal/Trees.scala: case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
ここから、ファイル名だけ取り出してみましょう。
./compiler/scala/reflect/macros/compiler/Resolvers.scala
./compiler/scala/reflect/reify/package.scala
./compiler/scala/reflect/reify/phases/Reshape.scala
./compiler/scala/reflect/reify/utils/Extractors.scala
./compiler/scala/tools/nsc/ast/NodePrinters.scala
./compiler/scala/tools/nsc/ast/parser/Parsers.scala
./compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
./compiler/scala/tools/nsc/ast/Printers.scala
./compiler/scala/tools/nsc/ast/TreeBrowsers.scala
./compiler/scala/tools/nsc/ast/Trees.scala
./compiler/scala/tools/nsc/backend/icode/GenICode.scala
./compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
./compiler/scala/tools/nsc/backend/jvm/BCodeSkelBuilder.scala
./compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
./compiler/scala/tools/nsc/javac/JavaParsers.scala
./compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala
./compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
./compiler/scala/tools/nsc/transform/AddInterfaces.scala
./compiler/scala/tools/nsc/transform/CleanUp.scala
./compiler/scala/tools/nsc/transform/Constructors.scala
./compiler/scala/tools/nsc/transform/Erasure.scala
./compiler/scala/tools/nsc/transform/Flatten.scala
./compiler/scala/tools/nsc/transform/LambdaLift.scala
./compiler/scala/tools/nsc/transform/LazyVals.scala
./compiler/scala/tools/nsc/transform/SpecializeTypes.scala
./compiler/scala/tools/nsc/transform/UnCurry.scala
./compiler/scala/tools/nsc/typechecker/Analyzer.scala
./compiler/scala/tools/nsc/typechecker/AnalyzerPlugins.scala
./compiler/scala/tools/nsc/typechecker/ContextErrors.scala
./compiler/scala/tools/nsc/typechecker/Contexts.scala
./compiler/scala/tools/nsc/typechecker/Duplicators.scala
./compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
./compiler/scala/tools/nsc/typechecker/Namers.scala
./compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
./compiler/scala/tools/nsc/typechecker/RefChecks.scala
./compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
./compiler/scala/tools/nsc/typechecker/Typers.scala
./compiler/scala/tools/nsc/typechecker/Unapplies.scala
./reflect/scala/reflect/api/FlagSets.scala
./reflect/scala/reflect/api/ImplicitTags.scala
./reflect/scala/reflect/api/Printers.scala
./reflect/scala/reflect/api/Trees.scala
./reflect/scala/reflect/internal/Definitions.scala
./reflect/scala/reflect/internal/Importers.scala
./reflect/scala/reflect/internal/pickling/UnPickler.scala
./reflect/scala/reflect/internal/Printers.scala
./reflect/scala/reflect/internal/TreeInfo.scala
./reflect/scala/reflect/internal/Trees.scala
./reflect/scala/reflect/internal/TypeDebugging.scala
./reflect/scala/reflect/internal/Variances.scala
./reflect/scala/reflect/macros/Enclosures.scala
./reflect/scala/reflect/macros/Synthetics.scala
./reflect/scala/reflect/runtime/JavaMirrors.scala
./reflect/scala/reflect/runtime/ReflectionUtils.scala
./reflect/scala/reflect/runtime/SymbolLoaders.scala
./repl/scala/tools/nsc/interpreter/AbstractOrMissingHandler.scala
./repl/scala/tools/nsc/interpreter/ILoop.scala
./repl/scala/tools/nsc/interpreter/JavapClass.scala
./repl/scala/tools/nsc/interpreter/MemberHandlers.scala
ファイルだけでも、60ぐらいありますね。
今後の方針
なんでこんなことを調べたかというと、文法に変更をくわえるのに、
1.手を抜いて、字句解析器・構文解析器だけ修正してすませる
2.きちんと、字句解析器・構文解析器はもちろん、意味解析や型推論やバックエンドも実装する。
という2つの手段を思いついたので、どっちがいいのか考えていました。
もちろん、理想は2なんですが、あまり手間がかかるようなら1でいいんじゃないかと…。
で、とりあえずの方針ですが、2だと修正を加えるファイルが多すぎるので、1で試しに実装してみることにします。
(実装編につづく?)