|
1 | 1 | package dotty.tools.backend.jvm |
2 | 2 |
|
3 | | -import dotty.tools.dotc.ast.Trees.Thicket |
4 | | -import dotty.tools.dotc.ast.{Trees, tpd} |
| 3 | +import dotty.tools.dotc.ast.tpd |
5 | 4 | import dotty.tools.dotc.core.Contexts.Context |
6 | | -import dotty.tools.dotc.core.Types |
| 5 | +import dotty.tools.dotc.core.Flags._ |
| 6 | +import dotty.tools.dotc.core.Symbols._ |
7 | 7 | import dotty.tools.dotc.transform.MegaPhase._ |
8 | | -import dotty.tools.dotc |
9 | | -import dotty.tools.dotc.backend.jvm.DottyPrimitives |
10 | | -import dotty.tools.dotc.core.Flags.FlagSet |
11 | | -import dotty.tools.dotc.transform.Erasure |
12 | | -import dotty.tools.dotc.transform.SymUtils._ |
13 | | -import java.io.{File => JFile} |
14 | 8 |
|
15 | | -import scala.collection.generic.Clearable |
16 | 9 | import scala.collection.mutable |
17 | | -import scala.collection.mutable.{ListBuffer, ArrayBuffer} |
18 | | -import scala.reflect.ClassTag |
19 | | -import dotty.tools.io.{Directory, PlainDirectory, AbstractFile} |
20 | | -import scala.tools.asm.{ClassVisitor, FieldVisitor, MethodVisitor} |
21 | | -import scala.tools.nsc.backend.jvm.{BCodeHelpers, BackendInterface} |
22 | | -import dotty.tools.dotc.core._ |
23 | | -import Periods._ |
24 | | -import SymDenotations._ |
25 | | -import Contexts._ |
26 | | -import Types._ |
27 | | -import Symbols._ |
28 | | -import Denotations._ |
29 | | -import Phases._ |
30 | | -import java.lang.AssertionError |
31 | | -import dotty.tools.dotc.util.Positions.Position |
32 | | -import Decorators._ |
33 | | -import tpd._ |
34 | | -import Flags._ |
35 | | -import StdNames.nme |
36 | 10 |
|
37 | 11 | /** |
38 | 12 | * Verifies that each Label DefDef has only a single address to jump back and |
@@ -82,68 +56,48 @@ import StdNames.nme |
82 | 56 | * @author Dmitry Petrashko |
83 | 57 | */ |
84 | 58 | class LabelDefs extends MiniPhase { |
85 | | - def phaseName: String = "labelDef" |
| 59 | + import tpd._ |
86 | 60 |
|
87 | | - val queue = new ArrayBuffer[Tree]() |
88 | | - val beingAppended = new mutable.HashSet[Symbol]() |
89 | | - var labelLevel = 0 |
| 61 | + def phaseName: String = "labelDef" |
90 | 62 |
|
91 | | - override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = { |
92 | | - if (tree.symbol is Flags.Label) tree |
| 63 | + override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = { |
| 64 | + if (tree.symbol is Label) tree |
93 | 65 | else { |
94 | | - collectLabelDefs.clear |
95 | | - val newRhs = collectLabelDefs.transform(tree.rhs) |
96 | | - var labelDefs = collectLabelDefs.labelDefs |
| 66 | + val labelDefs = collectLabelDefs(tree.rhs) |
97 | 67 |
|
98 | 68 | def putLabelDefsNearCallees = new TreeMap() { |
99 | | - |
100 | | - override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = { |
| 69 | + override def transform(tree: Tree)(implicit ctx: Context): Tree = { |
101 | 70 | tree match { |
102 | 71 | case t: Apply if labelDefs.contains(t.symbol) => |
103 | 72 | val labelDef = labelDefs(t.symbol) |
104 | 73 | labelDefs -= t.symbol |
105 | | - |
106 | | - val labelDef2 = transform(labelDef) |
| 74 | + val labelDef2 = cpy.DefDef(labelDef)(rhs = transform(labelDef.rhs)) |
107 | 75 | Block(labelDef2:: Nil, t) |
108 | | - |
| 76 | + case t: DefDef => |
| 77 | + assert(t.symbol is Label) |
| 78 | + EmptyTree |
109 | 79 | case _ => if (labelDefs.nonEmpty) super.transform(tree) else tree |
110 | 80 | } |
111 | 81 | } |
112 | 82 | } |
113 | 83 |
|
114 | | - val res = cpy.DefDef(tree)(rhs = putLabelDefsNearCallees.transform(newRhs)) |
115 | | - |
116 | | - res |
| 84 | + if (labelDefs.isEmpty) tree |
| 85 | + else cpy.DefDef(tree)(rhs = putLabelDefsNearCallees.transform(tree.rhs)) |
117 | 86 | } |
118 | 87 | } |
119 | 88 |
|
120 | | - object collectLabelDefs extends TreeMap() { |
121 | | - |
| 89 | + private def collectLabelDefs(tree: Tree)(implicit ctx: Context): mutable.HashMap[Symbol, DefDef] = { |
122 | 90 | // labelSymbol -> Defining tree |
123 | | - val labelDefs = new mutable.HashMap[Symbol, Tree]() |
124 | | - |
125 | | - def clear = { |
126 | | - labelDefs.clear() |
127 | | - } |
128 | | - |
129 | | - override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = tree match { |
130 | | - case t: Template => t |
131 | | - case t: Block => |
132 | | - val r = super.transform(t) |
133 | | - r match { |
134 | | - case t: Block if t.stats.isEmpty => t.expr |
135 | | - case _ => r |
136 | | - } |
137 | | - case t: DefDef => |
138 | | - assert(t.symbol is Flags.Label) |
139 | | - val r = super.transform(tree) |
140 | | - labelDefs(r.symbol) = r |
141 | | - EmptyTree |
142 | | - case t: Apply if t.symbol is Flags.Label => |
143 | | - val sym = t.symbol |
144 | | - super.transform(tree) |
145 | | - case _ => |
146 | | - super.transform(tree) |
147 | | - } |
| 91 | + val labelDefs = new mutable.HashMap[Symbol, DefDef]() |
| 92 | + new TreeTraverser { |
| 93 | + override def traverse(tree: Tree)(implicit ctx: Context): Unit = tree match { |
| 94 | + case t: DefDef => |
| 95 | + assert(t.symbol is Label) |
| 96 | + labelDefs(t.symbol) = t |
| 97 | + traverseChildren(t) |
| 98 | + case _ => traverseChildren(tree) |
| 99 | + } |
| 100 | + }.traverse(tree) |
| 101 | + labelDefs |
148 | 102 | } |
149 | 103 | } |
0 commit comments