Scalaのソースコードを読んでみる　その７


# ClassDef()がどれぐらい呼び出されているか調べる

もしも、ClassDef()と同レベルに新しい文法と追加したら、
それに伴って変更しなければいけないファイルがどれぐらいあるか調べたいので、以下のコマンドで調べてみました。


```bash:
$ find . -name *.scala -print | xargs grep ClassDef
```

その結果が以下。
長過ぎるので、途中は省略しています。

```text:
./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)
```

ここから、ファイル名だけ取り出してみましょう。

```text:
./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
```

ファイルだけでも、６０ぐらいありますね。

# 今後の方針

なんでこんなことを調べたかというと、文法に変更をくわえるのに、

１．手を抜いて、字句解析器・構文解析器だけ修正してすませる
２．きちんと、字句解析器・構文解析器はもちろん、意味解析や型推論やバックエンドも実装する。

という２つの手段を思いついたので、どっちがいいのか考えていました。
もちろん、理想は２なんですが、あまり手間がかかるようなら１でいいんじゃないかと…。

で、とりあえずの方針ですが、２だと修正を加えるファイルが多すぎるので、１で試しに実装してみることにします。


（実装編につづく？）