0
# Plugin Development API
1
2
Framework for creating compiler plugins that extend the Scala 3 compilation pipeline with custom phases, transformations, and analysis capabilities.
3
4
## Capabilities
5
6
### Plugin Base Trait
7
8
Base trait defining the interface for all compiler plugins with metadata and lifecycle methods.
9
10
```scala { .api }
11
/**
12
* Base trait for all compiler plugins
13
* Defines the plugin interface and metadata requirements
14
*/
15
sealed trait Plugin {
16
/**
17
* Unique name identifying this plugin
18
* Used for plugin registration and dependency resolution
19
* @return String identifier for the plugin
20
*/
21
def name: String
22
23
/**
24
* Human-readable description of the plugin's functionality
25
* @return String describing what the plugin does
26
*/
27
def description: String
28
29
/**
30
* Optional help text describing plugin-specific options
31
* @return Option containing help text for plugin options, or None
32
*/
33
def optionsHelp: Option[String]
34
}
35
```
36
37
### Standard Plugin
38
39
Standard plugin type that inserts phases into the normal compilation pipeline without modifying the overall phase plan.
40
41
```scala { .api }
42
/**
43
* Standard plugin that inserts phases into normal compilation pipeline
44
* Suitable for most plugin use cases that add transformation or analysis phases
45
*/
46
trait StandardPlugin extends Plugin {
47
/**
48
* Initialize plugin and return list of phases to insert into compilation pipeline
49
* Called once during compiler initialization with plugin-specific options
50
* @param options List of options passed to this plugin
51
* @param ctx Compilation context for initialization
52
* @return List of PluginPhase instances to add to the compilation pipeline
53
*/
54
def initialize(options: List[String])(using Context): List[PluginPhase]
55
}
56
```
57
58
**Usage Example:**
59
60
```scala
61
import dotty.tools.dotc.plugins.{StandardPlugin, PluginPhase}
62
import dotty.tools.dotc.core.Contexts.Context
63
64
class MyPlugin extends StandardPlugin {
65
val name = "my-plugin"
66
val description = "Custom transformation plugin"
67
68
override def initialize(options: List[String])(using Context): List[PluginPhase] = {
69
List(new MyTransformPhase)
70
}
71
}
72
73
class MyTransformPhase extends PluginPhase {
74
val phaseName = "my-transform"
75
76
override def transformTree(tree: Tree)(using Context): Tree = {
77
// Custom tree transformation logic
78
tree
79
}
80
}
81
```
82
83
### Research Plugin
84
85
Research plugin type that can completely customize the compilation pipeline by modifying the phase plan.
86
87
```scala { .api }
88
/**
89
* Research plugin that can customize the compilation pipeline freely
90
* Allows complete control over phase ordering and structure
91
* Use with caution as it can significantly modify compilation behavior
92
*/
93
trait ResearchPlugin extends Plugin {
94
/**
95
* Customize the compilation phase plan
96
* Called during compiler initialization to allow complete pipeline modification
97
* @param options List of options passed to this plugin
98
* @param plan Current phase plan as nested list of phases
99
* @param ctx Compilation context for initialization
100
* @return Modified phase plan with custom phase organization
101
*/
102
def init(options: List[String], plan: List[List[Phase]])(using Context): List[List[Phase]]
103
}
104
```
105
106
**Usage Example:**
107
108
```scala
109
import dotty.tools.dotc.plugins.ResearchPlugin
110
import dotty.tools.dotc.core.Phases.Phase
111
112
class MyResearchPlugin extends ResearchPlugin {
113
val name = "research-plugin"
114
val description = "Experimental compilation pipeline modification"
115
116
override def init(options: List[String], plan: List[List[Phase]])(using Context): List[List[Phase]] = {
117
// Insert custom phases at specific positions
118
val customPhases = List(List(new MyAnalysisPhase))
119
plan.take(2) ++ customPhases ++ plan.drop(2)
120
}
121
}
122
```
123
124
### Plugin Phase
125
126
Base class for plugin phases that integrate into the compilation pipeline.
127
128
```scala { .api }
129
/**
130
* Base class for plugin phases
131
* Extends MiniPhase to provide efficient transformation capabilities
132
*/
133
abstract class PluginPhase extends MiniPhase {
134
/**
135
* Name of this phase for identification and logging
136
* @return String name of the phase
137
*/
138
def phaseName: String
139
140
/**
141
* Set of phase names this phase must run before
142
* Used for phase ordering constraints
143
* @return Set of phase names that must run after this phase
144
*/
145
def runsBefore: Set[String] = Set.empty
146
147
/**
148
* Set of phase names this phase must run after
149
* Used for phase ordering constraints
150
* @return Set of phase names that must run before this phase
151
*/
152
def runsAfter: Set[String] = Set.empty
153
154
/**
155
* Transform a tree node during compilation
156
* Override this method to implement custom transformations
157
* @param tree Tree node to transform
158
* @param ctx Compilation context
159
* @return Transformed tree node
160
*/
161
def transformTree(tree: Tree)(using Context): Tree = tree
162
163
/**
164
* Check if this phase is enabled for the given compilation unit
165
* @param unit Compilation unit being processed
166
* @param ctx Compilation context
167
* @return True if phase should run on this unit
168
*/
169
def isEnabled(unit: CompilationUnit)(using Context): Boolean = true
170
}
171
```
172
173
**Usage Example:**
174
175
```scala
176
import dotty.tools.dotc.plugins.PluginPhase
177
import dotty.tools.dotc.ast.Trees._
178
import dotty.tools.dotc.core.Contexts.Context
179
180
class LoggingPhase extends PluginPhase {
181
val phaseName = "logging"
182
override val runsAfter = Set("typer")
183
override val runsBefore = Set("pickler")
184
185
override def transformTree(tree: Tree)(using Context): Tree = {
186
tree match {
187
case DefDef(name, _, _, _) =>
188
println(s"Found method definition: $name")
189
tree
190
case ClassDef(name, _, _) =>
191
println(s"Found class definition: $name")
192
tree
193
case _ => tree
194
}
195
}
196
}
197
```
198
199
### Mini Phase Framework
200
201
Base framework for creating efficient transformation phases that operate on individual tree nodes.
202
203
```scala { .api }
204
/**
205
* Base class for mini-phases that provide efficient tree transformations
206
* Mini-phases are combined into mega-phases for optimal performance
207
*/
208
abstract class MiniPhase extends Phase {
209
/**
210
* Transform a tree node
211
* @param tree Tree to transform
212
* @param ctx Compilation context
213
* @return Transformed tree
214
*/
215
def transformTree(tree: Tree)(using Context): Tree = tree
216
217
/**
218
* Transform a definition (class, method, value, etc.)
219
* @param tree Definition tree to transform
220
* @param ctx Compilation context
221
* @return Transformed definition tree
222
*/
223
def transformDef(tree: Tree)(using Context): Tree = transformTree(tree)
224
225
/**
226
* Transform an expression
227
* @param tree Expression tree to transform
228
* @param ctx Compilation context
229
* @return Transformed expression tree
230
*/
231
def transformExpr(tree: Tree)(using Context): Tree = transformTree(tree)
232
}
233
```
234
235
## Plugin Registration
236
237
### Plugin Discovery
238
239
Plugins are discovered through the Java ServiceLoader mechanism or explicit registration.
240
241
```scala { .api }
242
// META-INF/services/dotty.tools.dotc.plugins.Plugin file content:
243
// com.example.MyPlugin
244
245
class MyPlugin extends StandardPlugin {
246
val name = "my-plugin"
247
val description = "Example plugin"
248
249
def initialize(options: List[String])(using Context): List[PluginPhase] = {
250
List(new MyPhase)
251
}
252
}
253
```
254
255
### Compiler Integration
256
257
```scala
258
// Registering plugins programmatically
259
val driver = new Driver {
260
override def newCompiler(using Context) = {
261
val compiler = super.newCompiler
262
// Plugin registration logic
263
compiler
264
}
265
}
266
```
267
268
## Types
269
270
### Phase
271
272
```scala { .api }
273
/**
274
* Base class for all compilation phases
275
*/
276
abstract class Phase {
277
def phaseName: String
278
def run(using Context): Unit
279
def isRunnable(using Context): Boolean = true
280
}
281
```
282
283
### Tree
284
285
```scala { .api }
286
/**
287
* Abstract syntax tree node
288
* Base class for all AST elements in the Scala 3 compiler
289
*/
290
abstract class Tree[T] {
291
def pos: Position
292
def symbol: Symbol
293
def tpe: Type
294
}
295
```
296
297
### Context
298
299
```scala { .api }
300
/**
301
* Compilation context containing settings, symbols, and phase information
302
*/
303
abstract class Context {
304
def settings: Settings
305
def definitions: Definitions
306
def phase: Phase
307
}
308
```