0
# Symbol System
1
2
Symbol representation for all definitions including classes, methods, fields, and modules with complete metadata access. Symbols represent named entities in Scala programs and provide access to their properties, relationships, and type information.
3
4
## Capabilities
5
6
### Base Symbol API
7
8
Core symbol operations and properties available on all symbol types.
9
10
```scala { .api }
11
/**
12
* Base symbol trait providing fundamental symbol operations
13
*/
14
trait SymbolApi { this: Symbol =>
15
/** Name of this symbol */
16
def name: Name
17
18
/** Full name including package path */
19
def fullName: String
20
21
/** Type signature of this symbol */
22
def info: Type
23
24
/** Type signature in the context of a specific type */
25
def infoIn(site: Type): Type
26
27
/** Owner symbol (enclosing class, method, or package) */
28
def owner: Symbol
29
30
/** Check if this symbol is private */
31
def isPrivate: Boolean
32
33
/** Check if this symbol is protected */
34
def isProtected: Boolean
35
36
/** Check if this symbol is public */
37
def isPublic: Boolean
38
39
/** Check if this symbol is a package */
40
def isPackage: Boolean
41
42
/** Check if this symbol is a class */
43
def isClass: Boolean
44
45
/** Check if this symbol is a module (object) */
46
def isModule: Boolean
47
48
/** Check if this symbol is a method */
49
def isMethod: Boolean
50
51
/** Check if this symbol is a term (value, variable, method, object) */
52
def isTerm: Boolean
53
54
/** Check if this symbol is a type (class, trait, type alias) */
55
def isType: Boolean
56
57
/** Check if this symbol is abstract */
58
def isAbstract: Boolean
59
60
/** Check if this symbol is final */
61
def isFinal: Boolean
62
63
/** Check if this symbol is static */
64
def isStatic: Boolean
65
66
/** Check if this symbol is synthetic (compiler-generated) */
67
def isSynthetic: Boolean
68
69
/** Get annotations on this symbol */
70
def annotations: List[Annotation]
71
72
/** Convert to term symbol (if applicable) */
73
def asTerm: TermSymbol
74
75
/** Convert to type symbol (if applicable) */
76
def asType: TypeSymbol
77
78
/** Convert to class symbol (if applicable) */
79
def asClass: ClassSymbol
80
81
/** Convert to method symbol (if applicable) */
82
def asMethod: MethodSymbol
83
84
/** Convert to module symbol (if applicable) */
85
def asModule: ModuleSymbol
86
}
87
```
88
89
### Term Symbols
90
91
Symbols representing terms (values, variables, methods, objects).
92
93
```scala { .api }
94
/**
95
* Term symbol representing values, variables, methods, and objects
96
*/
97
trait TermSymbolApi extends SymbolApi { this: TermSymbol =>
98
/** Check if this is a val */
99
def isVal: Boolean
100
101
/** Check if this is a var */
102
def isVar: Boolean
103
104
/** Check if this is a lazy val */
105
def isLazy: Boolean
106
107
/** Check if this is stable (val or object) */
108
def isStable: Boolean
109
110
/** Check if this is an accessor method */
111
def isAccessor: Boolean
112
113
/** Check if this is a getter */
114
def isGetter: Boolean
115
116
/** Check if this is a setter */
117
def isSetter: Boolean
118
119
/** Check if this is a case accessor */
120
def isCaseAccessor: Boolean
121
122
/** Check if this is a parameter */
123
def isParameter: Boolean
124
125
/** Check if this has a default value */
126
def isParamWithDefault: Boolean
127
128
/** Check if this is implicit */
129
def isImplicit: Boolean
130
131
/** Associated getter for var/val */
132
def getter: Symbol
133
134
/** Associated setter for var */
135
def setter: Symbol
136
137
/** Accessed field for accessor methods */
138
def accessed: Symbol
139
}
140
```
141
142
### Type Symbols
143
144
Symbols representing types (classes, traits, type aliases).
145
146
```scala { .api }
147
/**
148
* Type symbol representing classes, traits, and type aliases
149
*/
150
trait TypeSymbolApi extends SymbolApi { this: TypeSymbol =>
151
/** Check if this is a type alias */
152
def isAliasType: Boolean
153
154
/** Check if this is an abstract type */
155
def isAbstractType: Boolean
156
157
/** Check if this type is covariant */
158
def isCovariant: Boolean
159
160
/** Check if this type is contravariant */
161
def isContravariant: Boolean
162
163
/** Get type parameters */
164
def typeParams: List[Symbol]
165
166
/** Convert to class symbol if this is a class */
167
def asClass: ClassSymbol
168
169
/** Get the aliased type for type aliases */
170
def aliasedType: Type
171
172
/** Get type bounds for abstract types */
173
def bounds: TypeBounds
174
}
175
```
176
177
### Class Symbols
178
179
Symbols representing classes and traits.
180
181
```scala { .api }
182
/**
183
* Class symbol representing classes and traits
184
*/
185
trait ClassSymbolApi extends TypeSymbolApi { this: ClassSymbol =>
186
/** Check if this is a trait */
187
def isTrait: Boolean
188
189
/** Check if this is a case class */
190
def isCaseClass: Boolean
191
192
/** Check if this is a module class (object implementation) */
193
def isModuleClass: Boolean
194
195
/** Check if this is a primitive class */
196
def isPrimitive: Boolean
197
198
/** Check if this is a numeric class */
199
def isNumeric: Boolean
200
201
/** Check if this is derived from a value class */
202
def isDerivedValueClass: Boolean
203
204
/** Get primary constructor */
205
def primaryConstructor: Symbol
206
207
/** Get all constructors */
208
def constructors: List[Symbol]
209
210
/** Get base classes in linearization order */
211
def baseClasses: List[Symbol]
212
213
/** Get companion module (object) */
214
def companion: Symbol
215
216
/** Get this type (C.this.type) */
217
def thisType: Type
218
219
/** Get self type */
220
def selfType: Type
221
222
/** Get type signature as ClassInfoType */
223
def toType: Type
224
225
/** Check if this class is derived from another class */
226
def isSubClass(that: Symbol): Boolean
227
}
228
```
229
230
### Method Symbols
231
232
Symbols representing methods (def).
233
234
```scala { .api }
235
/**
236
* Method symbol representing method definitions
237
*/
238
trait MethodSymbolApi extends TermSymbolApi { this: MethodSymbol =>
239
/** Check if this is a constructor */
240
def isConstructor: Boolean
241
242
/** Parameter lists (for multiple parameter lists) */
243
def paramLists: List[List[Symbol]]
244
245
/** Return type */
246
def returnType: Type
247
248
/** Check if this method is varargs */
249
def isVarargs: Boolean
250
251
/** Check if this is a macro */
252
def isMacro: Boolean
253
254
/** Type parameters */
255
def typeParams: List[Symbol]
256
257
/** Check if method has multiple parameter lists */
258
def isMultipleParameterLists: Boolean
259
}
260
```
261
262
### Module Symbols
263
264
Symbols representing objects and packages.
265
266
```scala { .api }
267
/**
268
* Module symbol representing objects and packages
269
*/
270
trait ModuleSymbolApi extends TermSymbolApi { this: ModuleSymbol =>
271
/** Check if this is a package object */
272
def isPackageObject: Boolean
273
274
/** Get the module class (implementation class) */
275
def moduleClass: Symbol
276
277
/** Get companion class */
278
def companion: Symbol
279
}
280
```
281
282
### Symbol Navigation and Lookup
283
284
Methods for navigating symbol relationships and lookups.
285
286
```scala { .api }
287
/**
288
* Symbol lookup and navigation operations
289
*/
290
trait SymbolNavigation {
291
/** Find member by name */
292
def member(name: Name): Symbol
293
294
/** Find declaration by name */
295
def decl(name: Name): Symbol
296
297
/** Get all members */
298
def members: MemberScope
299
300
/** Get all declarations */
301
def decls: MemberScope
302
303
/** Get owner chain */
304
def ownerChain: List[Symbol]
305
306
/** Check if symbol is accessible from given context */
307
def isAccessibleFrom(site: Type): Boolean
308
309
/** Get all overridden symbols */
310
def allOverriddenSymbols: List[Symbol]
311
312
/** Get directly overridden symbol */
313
def overriddenSymbol: Symbol
314
315
/** Get all symbols that override this one */
316
def overridingSymbol: Symbol
317
}
318
```
319
320
**Usage Examples:**
321
322
```scala
323
import scala.reflect.runtime.universe._
324
import scala.reflect.runtime.{currentMirror => cm}
325
326
// Basic symbol inspection
327
case class Person(name: String, age: Int) {
328
def greet(other: String): String = s"Hello $other, I'm $name"
329
var mood: String = "happy"
330
}
331
332
val personType = typeOf[Person]
333
val personClass = personType.typeSymbol.asClass
334
335
println(s"Class name: ${personClass.name}")
336
println(s"Full name: ${personClass.fullName}")
337
println(s"Is case class: ${personClass.isCaseClass}")
338
println(s"Is final: ${personClass.isFinal}")
339
340
// Constructor inspection
341
val constructor = personClass.primaryConstructor.asMethod
342
println(s"Constructor: ${constructor.name}")
343
println(s"Parameter lists: ${constructor.paramLists}")
344
345
constructor.paramLists.head.foreach { param =>
346
println(s" Parameter: ${param.name} -> ${param.info}")
347
println(s" Is implicit: ${param.asMethod.isImplicit}")
348
}
349
350
// Method inspection
351
val greetMethod = personType.decl(TermName("greet")).asMethod
352
println(s"Greet method: ${greetMethod.name}")
353
println(s"Return type: ${greetMethod.returnType}")
354
println(s"Is public: ${greetMethod.isPublic}")
355
356
greetMethod.paramLists.head.foreach { param =>
357
println(s" Parameter: ${param.name} -> ${param.info}")
358
}
359
360
// Field inspection
361
val nameField = personType.decl(TermName("name")).asTerm
362
println(s"Name field: ${nameField.name}")
363
println(s"Is val: ${nameField.isVal}")
364
println(s"Is stable: ${nameField.isStable}")
365
println(s"Is case accessor: ${nameField.isCaseAccessor}")
366
367
val moodField = personType.decl(TermName("mood")).asTerm
368
println(s"Mood field: ${moodField.name}")
369
println(s"Is var: ${moodField.isVar}")
370
println(s"Getter: ${moodField.getter}")
371
println(s"Setter: ${moodField.setter}")
372
```
373
374
### Symbol Filtering and Analysis
375
376
```scala { .api }
377
/**
378
* Utility methods for filtering and analyzing symbols
379
*/
380
object SymbolUtils {
381
/** Get all methods from a type */
382
def methods(tpe: Type): List[MethodSymbol] =
383
tpe.members.filter(_.isMethod).map(_.asMethod).toList
384
385
/** Get all fields from a type */
386
def fields(tpe: Type): List[TermSymbol] =
387
tpe.members.filter(m => m.isTerm && !m.isMethod).map(_.asTerm).toList
388
389
/** Get all nested types from a type */
390
def nestedTypes(tpe: Type): List[TypeSymbol] =
391
tpe.members.filter(_.isType).map(_.asType).toList
392
393
/** Get public members only */
394
def publicMembers(tpe: Type): List[Symbol] =
395
tpe.members.filter(_.isPublic).toList
396
397
/** Get constructors */
398
def constructors(cls: ClassSymbol): List[MethodSymbol] =
399
cls.info.members.filter(_.isConstructor).map(_.asMethod).toList
400
}
401
```
402
403
**Complete Symbol Analysis Example:**
404
405
```scala
406
import scala.reflect.runtime.universe._
407
408
def analyzeSymbol(sym: Symbol): Unit = {
409
println(s"Symbol: ${sym.name} (${sym.getClass.getSimpleName})")
410
println(s"Full name: ${sym.fullName}")
411
println(s"Owner: ${sym.owner.name}")
412
println(s"Type: ${sym.info}")
413
414
// Visibility
415
val visibility = if (sym.isPublic) "public"
416
else if (sym.isProtected) "protected"
417
else "private"
418
println(s"Visibility: $visibility")
419
420
// Modifiers
421
val modifiers = List(
422
if (sym.isFinal) Some("final") else None,
423
if (sym.isAbstract) Some("abstract") else None,
424
if (sym.isStatic) Some("static") else None,
425
if (sym.isSynthetic) Some("synthetic") else None
426
).flatten
427
428
if (modifiers.nonEmpty) {
429
println(s"Modifiers: ${modifiers.mkString(", ")}")
430
}
431
432
// Annotations
433
if (sym.annotations.nonEmpty) {
434
println("Annotations:")
435
sym.annotations.foreach { ann =>
436
println(s" @${ann.tree}")
437
}
438
}
439
440
// Type-specific analysis
441
if (sym.isClass) {
442
val cls = sym.asClass
443
println(s"Is trait: ${cls.isTrait}")
444
println(s"Is case class: ${cls.isCaseClass}")
445
println(s"Base classes: ${cls.baseClasses.map(_.name).mkString(", ")}")
446
}
447
448
if (sym.isMethod) {
449
val method = sym.asMethod
450
println(s"Return type: ${method.returnType}")
451
println(s"Parameter lists: ${method.paramLists.size}")
452
method.paramLists.zipWithIndex.foreach { case (params, i) =>
453
println(s" Param list $i: ${params.map(p => s"${p.name}: ${p.info}").mkString(", ")}")
454
}
455
}
456
457
println()
458
}
459
460
// Analyze various symbols
461
val stringType = typeOf[String]
462
analyzeSymbol(stringType.typeSymbol)
463
464
val listType = typeOf[List[Int]]
465
analyzeSymbol(listType.typeSymbol)
466
467
val optionType = typeOf[Option[String]]
468
analyzeSymbol(optionType.typeSymbol)
469
```