or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

abstract-syntax-trees.mdexpressions-reification.mdindex.mdmacro-development.mdmirrors-reflective-operations.mdruntime-reflection.mdsymbol-system.mdtype-system.mdtype-tags-type-information.md

mirrors-reflective-operations.mddocs/

0

# Mirrors and Reflective Operations

1

2

Mirror system providing entry points for reflective operations including instance creation, method invocation, and field access. Mirrors act as the bridge between the symbolic representation of code and actual runtime operations.

3

4

## Capabilities

5

6

### Base Mirror API

7

8

Core mirror functionality providing symbol resolution and reflective access.

9

10

```scala { .api }

11

/**

12

* Base mirror providing symbol resolution and basic reflection capabilities

13

*/

14

trait MirrorApi { this: Mirror =>

15

/** Get the universe this mirror belongs to */

16

def universe: Universe

17

18

/** Convert a runtime class to a class symbol */

19

def classSymbol(rtcls: RuntimeClass): ClassSymbol

20

21

/** Convert a class symbol to a runtime class */

22

def runtimeClass(cls: ClassSymbol): RuntimeClass

23

24

/** Convert a module symbol to a runtime class */

25

def runtimeClass(mod: ModuleSymbol): RuntimeClass

26

}

27

```

28

29

### Reflective Mirror

30

31

Extended mirror providing comprehensive reflection capabilities.

32

33

```scala { .api }

34

/**

35

* Reflective mirror providing comprehensive reflection operations

36

*/

37

trait ReflectiveMirror extends MirrorApi {

38

/** Create an instance mirror for runtime operations on objects */

39

def reflect(obj: Any): InstanceMirror

40

41

/** Create a class mirror for static operations and construction */

42

def reflectClass(cls: ClassSymbol): ClassMirror

43

44

/** Create a module mirror for singleton object access */

45

def reflectModule(mod: ModuleSymbol): ModuleMirror

46

}

47

```

48

49

### Instance Mirror

50

51

Mirror for performing operations on object instances.

52

53

```scala { .api }

54

/**

55

* Instance mirror for runtime operations on object instances

56

*/

57

trait InstanceMirrorApi { this: InstanceMirror =>

58

/** The instance being reflected upon */

59

def instance: Any

60

61

/** Symbol of the instance's class */

62

def symbol: ClassSymbol

63

64

/** Create a method mirror for invoking instance methods */

65

def reflectMethod(method: MethodSymbol): MethodMirror

66

67

/** Create a field mirror for accessing instance fields */

68

def reflectField(field: TermSymbol): FieldMirror

69

70

/** Create a class mirror for the instance's class */

71

def reflectClass: ClassMirror

72

}

73

```

74

75

**Usage Example:**

76

77

```scala

78

import scala.reflect.runtime.universe._

79

import scala.reflect.runtime.{currentMirror => cm}

80

81

class Calculator {

82

var result: Double = 0.0

83

def add(x: Double, y: Double): Double = {

84

result = x + y

85

result

86

}

87

def getResult: Double = result

88

}

89

90

val calc = new Calculator

91

val instanceMirror = cm.reflect(calc)

92

93

// Method invocation

94

val addMethod = typeOf[Calculator].decl(TermName("add")).asMethod

95

val addMirror = instanceMirror.reflectMethod(addMethod)

96

val sum = addMirror(10.0, 5.0)

97

println(s"Sum: $sum")

98

99

// Field access

100

val resultField = typeOf[Calculator].decl(TermName("result")).asTerm

101

val fieldMirror = instanceMirror.reflectField(resultField)

102

println(s"Current result: ${fieldMirror.get}")

103

104

// Field modification

105

fieldMirror.set(100.0)

106

println(s"Modified result: ${fieldMirror.get}")

107

```

108

109

### Method Mirror

110

111

Mirror for invoking methods reflectively.

112

113

```scala { .api }

114

/**

115

* Method mirror for reflective method invocation

116

*/

117

trait MethodMirrorApi { this: MethodMirror =>

118

/** Symbol of the method being reflected */

119

def symbol: MethodSymbol

120

121

/** Invoke the method with given arguments */

122

def apply(args: Any*): Any

123

124

/** The receiver instance (for instance methods) */

125

def receiver: Any

126

}

127

```

128

129

**Usage Example:**

130

131

```scala

132

import scala.reflect.runtime.universe._

133

import scala.reflect.runtime.{currentMirror => cm}

134

135

case class Person(firstName: String, lastName: String) {

136

def fullName: String = s"$firstName $lastName"

137

def greet(greeting: String, name: String): String = s"$greeting $name, I'm ${fullName}"

138

}

139

140

val person = Person("Alice", "Smith")

141

val instanceMirror = cm.reflect(person)

142

143

// Method with no parameters

144

val fullNameMethod = typeOf[Person].decl(TermName("fullName")).asMethod

145

val fullNameMirror = instanceMirror.reflectMethod(fullNameMethod)

146

val name = fullNameMirror()

147

println(s"Full name: $name")

148

149

// Method with parameters

150

val greetMethod = typeOf[Person].decl(TermName("greet")).asMethod

151

val greetMirror = instanceMirror.reflectMethod(greetMethod)

152

val greeting = greetMirror("Hello", "Bob")

153

println(s"Greeting: $greeting")

154

```

155

156

### Field Mirror

157

158

Mirror for accessing and modifying fields reflectively.

159

160

```scala { .api }

161

/**

162

* Field mirror for reflective field access and modification

163

*/

164

trait FieldMirrorApi { this: FieldMirror =>

165

/** Symbol of the field being reflected */

166

def symbol: TermSymbol

167

168

/** Get the current value of the field */

169

def get: Any

170

171

/** Set the field to a new value (for vars only) */

172

def set(value: Any): Unit

173

174

/** The receiver instance */

175

def receiver: Any

176

177

/** Check if this field is settable (var) */

178

def isSettable: Boolean

179

}

180

```

181

182

**Usage Example:**

183

184

```scala

185

import scala.reflect.runtime.universe._

186

import scala.reflect.runtime.{currentMirror => cm}

187

188

class Counter {

189

var count: Int = 0

190

val name: String = "MyCounter"

191

192

def increment(): Unit = count += 1

193

}

194

195

val counter = new Counter

196

val instanceMirror = cm.reflect(counter)

197

198

// Access var field

199

val countField = typeOf[Counter].decl(TermName("count")).asTerm

200

val countMirror = instanceMirror.reflectField(countField)

201

202

println(s"Initial count: ${countMirror.get}")

203

countMirror.set(10)

204

println(s"Modified count: ${countMirror.get}")

205

206

// Access val field

207

val nameField = typeOf[Counter].decl(TermName("name")).asTerm

208

val nameMirror = instanceMirror.reflectField(nameField)

209

println(s"Counter name: ${nameMirror.get}")

210

211

// Check if settable

212

println(s"Count is settable: ${countMirror.isSettable}")

213

println(s"Name is settable: ${nameMirror.isSettable}")

214

```

215

216

### Class Mirror

217

218

Mirror for class-level operations like construction.

219

220

```scala { .api }

221

/**

222

* Class mirror for static operations and object construction

223

*/

224

trait ClassMirrorApi { this: ClassMirror =>

225

/** Symbol of the class being reflected */

226

def symbol: ClassSymbol

227

228

/** Create a constructor mirror for object instantiation */

229

def reflectConstructor(constructor: MethodSymbol): MethodMirror

230

231

/** Create a module mirror for the companion object */

232

def companion: ModuleMirror

233

234

/** The runtime class */

235

def runtimeClass: RuntimeClass

236

}

237

```

238

239

**Usage Example:**

240

241

```scala

242

import scala.reflect.runtime.universe._

243

import scala.reflect.runtime.{currentMirror => cm}

244

245

case class Book(title: String, author: String, pages: Int)

246

247

// Get class mirror

248

val bookClass = typeOf[Book].typeSymbol.asClass

249

val classMirror = cm.reflectClass(bookClass)

250

251

// Find primary constructor

252

val constructor = bookClass.primaryConstructor.asMethod

253

val constructorMirror = classMirror.reflectConstructor(constructor)

254

255

// Create new instance

256

val book = constructorMirror("Scala in Depth", "Joshua Suereth", 304).asInstanceOf[Book]

257

println(s"Created book: $book")

258

259

// Alternative: find constructor by parameter types

260

val constructors = bookClass.info.members.filter(_.isConstructor).map(_.asMethod)

261

constructors.foreach { ctor =>

262

println(s"Constructor: ${ctor.name} -> ${ctor.paramLists}")

263

}

264

```

265

266

### Module Mirror

267

268

Mirror for accessing singleton objects.

269

270

```scala { .api }

271

/**

272

* Module mirror for singleton object access

273

*/

274

trait ModuleMirrorApi { this: ModuleMirror =>

275

/** Symbol of the module being reflected */

276

def symbol: ModuleSymbol

277

278

/** Get the singleton instance */

279

def instance: Any

280

281

/** Create an instance mirror for the singleton object */

282

def reflect: InstanceMirror

283

}

284

```

285

286

**Usage Example:**

287

288

```scala

289

import scala.reflect.runtime.universe._

290

import scala.reflect.runtime.{currentMirror => cm}

291

292

object MathUtils {

293

def add(x: Int, y: Int): Int = x + y

294

def multiply(x: Int, y: Int): Int = x * y

295

val PI: Double = 3.14159

296

}

297

298

// Get module mirror

299

val mathUtilsModule = cm.staticModule("MathUtils")

300

val moduleMirror = cm.reflectModule(mathUtilsModule)

301

302

// Get singleton instance

303

val mathUtilsInstance = moduleMirror.instance

304

println(s"Module instance: $mathUtilsInstance")

305

306

// Reflect on the instance

307

val instanceMirror = moduleMirror.reflect

308

309

// Call methods on the object

310

val addMethod = mathUtilsModule.info.decl(TermName("add")).asMethod

311

val addMirror = instanceMirror.reflectMethod(addMethod)

312

val sum = addMirror(3, 4)

313

println(s"3 + 4 = $sum")

314

315

// Access fields

316

val piField = mathUtilsModule.info.decl(TermName("PI")).asTerm

317

val piMirror = instanceMirror.reflectField(piField)

318

println(s"PI = ${piMirror.get}")

319

```

320

321

### Complete Reflection Workflow

322

323

Comprehensive example showing the complete reflection workflow.

324

325

```scala

326

import scala.reflect.runtime.universe._

327

import scala.reflect.runtime.{currentMirror => cm}

328

329

// Example class hierarchy

330

abstract class Animal(val name: String) {

331

def speak: String

332

def age: Int = 0

333

}

334

335

class Dog(name: String, val breed: String) extends Animal(name) {

336

override def speak: String = "Woof!"

337

override def age: Int = 3

338

def wagTail(): String = s"$name is wagging tail"

339

}

340

341

object AnimalShelter {

342

def adoptAnimal(animal: Animal): String = s"${animal.name} has been adopted!"

343

}

344

345

// 1. Runtime type inspection

346

val dogType = typeOf[Dog]

347

println(s"Dog type: $dogType")

348

println(s"Base classes: ${dogType.baseClasses.map(_.name)}")

349

350

// 2. Create instance using reflection

351

val dogClass = dogType.typeSymbol.asClass

352

val classMirror = cm.reflectClass(dogClass)

353

val constructor = dogClass.primaryConstructor.asMethod

354

val constructorMirror = classMirror.reflectConstructor(constructor)

355

val dog = constructorMirror("Buddy", "Golden Retriever").asInstanceOf[Dog]

356

357

println(s"Created dog: $dog")

358

359

// 3. Instance reflection

360

val dogInstanceMirror = cm.reflect(dog)

361

362

// 4. Field access

363

val nameField = dogType.baseClasses

364

.map(_.info)

365

.find(_.decl(TermName("name")) != NoSymbol)

366

.get.decl(TermName("name")).asTerm

367

val nameFieldMirror = dogInstanceMirror.reflectField(nameField)

368

println(s"Dog name: ${nameFieldMirror.get}")

369

370

val breedField = dogType.decl(TermName("breed")).asTerm

371

val breedFieldMirror = dogInstanceMirror.reflectField(breedField)

372

println(s"Dog breed: ${breedFieldMirror.get}")

373

374

// 5. Method invocation

375

val speakMethod = dogType.decl(TermName("speak")).asMethod

376

val speakMirror = dogInstanceMirror.reflectMethod(speakMethod)

377

println(s"Dog says: ${speakMirror()}")

378

379

val wagTailMethod = dogType.decl(TermName("wagTail")).asMethod

380

val wagTailMirror = dogInstanceMirror.reflectMethod(wagTailMethod)

381

println(s"Action: ${wagTailMirror()}")

382

383

// 6. Object reflection

384

val shelterModule = cm.staticModule("AnimalShelter")

385

val shelterModuleMirror = cm.reflectModule(shelterModule)

386

val shelterInstanceMirror = shelterModuleMirror.reflect

387

388

val adoptMethod = shelterModule.info.decl(TermName("adoptAnimal")).asMethod

389

val adoptMirror = shelterInstanceMirror.reflectMethod(adoptMethod)

390

println(s"Adoption: ${adoptMirror(dog)}")

391

```

392

393

### Error Handling in Reflective Operations

394

395

Common exceptions and error handling patterns:

396

397

```scala

398

import scala.reflect.runtime.universe._

399

import scala.reflect.runtime.{currentMirror => cm}

400

import scala.util.{Try, Success, Failure}

401

402

def safeReflectiveCall[T](operation: => T): Try[T] = {

403

Try(operation).recover {

404

case _: ScalaReflectionException =>

405

println("Reflection operation failed")

406

throw new RuntimeException("Reflection error")

407

case _: IllegalArgumentException =>

408

println("Invalid arguments provided")

409

throw new RuntimeException("Argument error")

410

case _: IllegalAccessException =>

411

println("Access denied")

412

throw new RuntimeException("Access error")

413

}

414

}

415

416

// Safe method invocation

417

class TestClass {

418

def publicMethod(): String = "public"

419

private def privateMethod(): String = "private"

420

}

421

422

val testInstance = new TestClass

423

val instanceMirror = cm.reflect(testInstance)

424

425

// This will succeed

426

safeReflectiveCall {

427

val method = typeOf[TestClass].decl(TermName("publicMethod")).asMethod

428

val methodMirror = instanceMirror.reflectMethod(method)

429

methodMirror()

430

} match {

431

case Success(result) => println(s"Success: $result")

432

case Failure(ex) => println(s"Failed: ${ex.getMessage}")

433

}

434

435

// This may fail (accessing private method)

436

safeReflectiveCall {

437

val method = typeOf[TestClass].decl(TermName("privateMethod")).asMethod

438

val methodMirror = instanceMirror.reflectMethod(method)

439

methodMirror()

440

} match {

441

case Success(result) => println(s"Success: $result")

442

case Failure(ex) => println(s"Failed: ${ex.getMessage}")

443

}

444

```