summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
blob: 1fe33f78e758443258716a254856c6492338c27a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* NSC -- new scala compiler
 * Copyright 2005-2013 LAMP/EPFL
 * @author  Martin Odersky
 */

package scala.tools.nsc
package backend
package icode

import java.io.PrintWriter

trait Printers { self: ICodes =>
  import global._

  class TextPrinter(writer: PrintWriter, lin: Linearizer) {
    private var margin = 0
    private var out = writer

    final val TAB = 2

    def setWriter(w: PrintWriter) { out = w }

    def indent() { margin += TAB }
    def undent() { margin -= TAB }

    def print(s: String) { out.print(s) }
    def print(o: Any) { print(o.toString()) }

    def println(s: String) {
      print(s)
      println()
    }

    def println() {
      out.println()
      var i = 0
      while (i < margin) {
        print(" ")
        i += 1
      }
    }

    def printList[A](l: List[A], sep: String): Unit = l match {
      case Nil =>
      case x :: Nil => print(x)
      case x :: xs  => print(x); print(sep); printList(xs, sep)
    }

    def printList[A](pr: A => Unit)(l: List[A], sep: String): Unit = l match {
      case Nil =>
      case x :: Nil => pr(x)
      case x :: xs  => pr(x); print(sep); printList(pr)(xs, sep)
    }

    def printClass(cls: IClass) {
      print(cls.symbol.toString()); print(" extends ")
      printList(cls.symbol.info.parents, ", ")
      indent(); println(" {")
      println("// fields:")
      cls.fields.foreach(printField); println()
      println("// methods")
      cls.methods.foreach(printMethod)
      undent(); println()
      println("}")
    }

    def printField(f: IField) {
      print(f.symbol.keyString); print(" ")
      print(f.symbol.nameString); print(": ")
      println(f.symbol.info.toString())
    }

    def printMethod(m: IMethod) {
      print("def "); print(m.symbol.name)
      print("("); printList(printParam)(m.params, ", "); print(")")
      print(": "); print(m.symbol.info.resultType)

      if (!m.isAbstractMethod) {
        println(" {")
        println("locals: " + m.locals.mkString("", ", ", ""))
        println("startBlock: " + m.startBlock)
        println("blocks: " + m.code.blocks.mkString("[", ",", "]"))
        println()
        lin.linearize(m) foreach printBlock
        println("}")

        indent(); println("Exception handlers: ")
        m.exh foreach printExceptionHandler

        undent(); println()
      } else
        println()
    }

    def printParam(p: Local) {
      print(p.sym.name); print(": "); print(p.sym.info)
      print(" ("); print(p.kind); print(")")
    }

    def printExceptionHandler(e: ExceptionHandler) {
      indent()
      println("catch (" + e.cls.simpleName + ") in " + e.covered.toSeq.sortBy(_.label) + " starting at: " + e.startBlock)
      println("consisting of blocks: " + e.blocks)
      undent()
      println("with finalizer: " + e.finalizer)
      //      linearizer.linearize(e.startBlock) foreach printBlock;
    }

    def printBlock(bb: BasicBlock) {
      print(bb.label)
      if (bb.loopHeader) print("[loop header]")
      print(": ")
      if (settings.debug) print("pred: " + bb.predecessors + " succs: " + bb.successors + " flags: " + bb.flagsString)
      indent(); println()
      bb.toList foreach printInstruction
      undent(); println()
    }

    def printInstruction(i: Instruction) {
//      if (settings.Xdce.value)
//        print(if (i.useful) "   " else " * ");
      if (i.pos.isDefined) print(i.pos.line.toString + "\t") else print("?\t")
      println(i.toString())
    }
  }
}