CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-lang--scala-reflect

Reflection Library for the Scala Programming Language providing runtime reflection capabilities and metaprogramming support

Pending
Overview
Eval results
Files

mirrors-reflective-operations.mddocs/

Mirrors and Reflective Operations

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.

Capabilities

Base Mirror API

Core mirror functionality providing symbol resolution and reflective access.

/**
 * Base mirror providing symbol resolution and basic reflection capabilities
 */
trait MirrorApi { this: Mirror =>
  /** Get the universe this mirror belongs to */
  def universe: Universe
  
  /** Convert a runtime class to a class symbol */
  def classSymbol(rtcls: RuntimeClass): ClassSymbol
  
  /** Convert a class symbol to a runtime class */
  def runtimeClass(cls: ClassSymbol): RuntimeClass
  
  /** Convert a module symbol to a runtime class */
  def runtimeClass(mod: ModuleSymbol): RuntimeClass
}

Reflective Mirror

Extended mirror providing comprehensive reflection capabilities.

/**
 * Reflective mirror providing comprehensive reflection operations
 */
trait ReflectiveMirror extends MirrorApi {
  /** Create an instance mirror for runtime operations on objects */
  def reflect(obj: Any): InstanceMirror
  
  /** Create a class mirror for static operations and construction */
  def reflectClass(cls: ClassSymbol): ClassMirror
  
  /** Create a module mirror for singleton object access */
  def reflectModule(mod: ModuleSymbol): ModuleMirror
}

Instance Mirror

Mirror for performing operations on object instances.

/**
 * Instance mirror for runtime operations on object instances
 */
trait InstanceMirrorApi { this: InstanceMirror =>
  /** The instance being reflected upon */
  def instance: Any
  
  /** Symbol of the instance's class */
  def symbol: ClassSymbol
  
  /** Create a method mirror for invoking instance methods */
  def reflectMethod(method: MethodSymbol): MethodMirror
  
  /** Create a field mirror for accessing instance fields */
  def reflectField(field: TermSymbol): FieldMirror
  
  /** Create a class mirror for the instance's class */
  def reflectClass: ClassMirror
}

Usage Example:

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

class Calculator {
  var result: Double = 0.0
  def add(x: Double, y: Double): Double = {
    result = x + y
    result
  }
  def getResult: Double = result
}

val calc = new Calculator
val instanceMirror = cm.reflect(calc)

// Method invocation
val addMethod = typeOf[Calculator].decl(TermName("add")).asMethod
val addMirror = instanceMirror.reflectMethod(addMethod)
val sum = addMirror(10.0, 5.0)
println(s"Sum: $sum")

// Field access
val resultField = typeOf[Calculator].decl(TermName("result")).asTerm
val fieldMirror = instanceMirror.reflectField(resultField)
println(s"Current result: ${fieldMirror.get}")

// Field modification
fieldMirror.set(100.0)
println(s"Modified result: ${fieldMirror.get}")

Method Mirror

Mirror for invoking methods reflectively.

/**
 * Method mirror for reflective method invocation
 */
trait MethodMirrorApi { this: MethodMirror =>
  /** Symbol of the method being reflected */
  def symbol: MethodSymbol
  
  /** Invoke the method with given arguments */
  def apply(args: Any*): Any
  
  /** The receiver instance (for instance methods) */
  def receiver: Any
}

Usage Example:

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

case class Person(firstName: String, lastName: String) {
  def fullName: String = s"$firstName $lastName"
  def greet(greeting: String, name: String): String = s"$greeting $name, I'm ${fullName}"
}

val person = Person("Alice", "Smith")
val instanceMirror = cm.reflect(person)

// Method with no parameters
val fullNameMethod = typeOf[Person].decl(TermName("fullName")).asMethod
val fullNameMirror = instanceMirror.reflectMethod(fullNameMethod)
val name = fullNameMirror()
println(s"Full name: $name")

// Method with parameters
val greetMethod = typeOf[Person].decl(TermName("greet")).asMethod  
val greetMirror = instanceMirror.reflectMethod(greetMethod)
val greeting = greetMirror("Hello", "Bob")
println(s"Greeting: $greeting")

Field Mirror

Mirror for accessing and modifying fields reflectively.

/**
 * Field mirror for reflective field access and modification
 */
trait FieldMirrorApi { this: FieldMirror =>
  /** Symbol of the field being reflected */
  def symbol: TermSymbol
  
  /** Get the current value of the field */
  def get: Any
  
  /** Set the field to a new value (for vars only) */
  def set(value: Any): Unit
  
  /** The receiver instance */
  def receiver: Any
  
  /** Check if this field is settable (var) */
  def isSettable: Boolean
}

Usage Example:

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

class Counter {
  var count: Int = 0
  val name: String = "MyCounter"
  
  def increment(): Unit = count += 1
}

val counter = new Counter
val instanceMirror = cm.reflect(counter)

// Access var field
val countField = typeOf[Counter].decl(TermName("count")).asTerm
val countMirror = instanceMirror.reflectField(countField)

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

// Access val field  
val nameField = typeOf[Counter].decl(TermName("name")).asTerm
val nameMirror = instanceMirror.reflectField(nameField)
println(s"Counter name: ${nameMirror.get}")

// Check if settable
println(s"Count is settable: ${countMirror.isSettable}")
println(s"Name is settable: ${nameMirror.isSettable}")

Class Mirror

Mirror for class-level operations like construction.

/**
 * Class mirror for static operations and object construction
 */
trait ClassMirrorApi { this: ClassMirror =>
  /** Symbol of the class being reflected */
  def symbol: ClassSymbol
  
  /** Create a constructor mirror for object instantiation */
  def reflectConstructor(constructor: MethodSymbol): MethodMirror
  
  /** Create a module mirror for the companion object */
  def companion: ModuleMirror
  
  /** The runtime class */
  def runtimeClass: RuntimeClass
}

Usage Example:

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

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

// Get class mirror
val bookClass = typeOf[Book].typeSymbol.asClass
val classMirror = cm.reflectClass(bookClass)

// Find primary constructor
val constructor = bookClass.primaryConstructor.asMethod
val constructorMirror = classMirror.reflectConstructor(constructor)

// Create new instance
val book = constructorMirror("Scala in Depth", "Joshua Suereth", 304).asInstanceOf[Book]
println(s"Created book: $book")

// Alternative: find constructor by parameter types
val constructors = bookClass.info.members.filter(_.isConstructor).map(_.asMethod)
constructors.foreach { ctor =>
  println(s"Constructor: ${ctor.name} -> ${ctor.paramLists}")
}

Module Mirror

Mirror for accessing singleton objects.

/**
 * Module mirror for singleton object access
 */
trait ModuleMirrorApi { this: ModuleMirror =>
  /** Symbol of the module being reflected */
  def symbol: ModuleSymbol
  
  /** Get the singleton instance */
  def instance: Any
  
  /** Create an instance mirror for the singleton object */
  def reflect: InstanceMirror
}

Usage Example:

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

object MathUtils {
  def add(x: Int, y: Int): Int = x + y
  def multiply(x: Int, y: Int): Int = x * y
  val PI: Double = 3.14159
}

// Get module mirror
val mathUtilsModule = cm.staticModule("MathUtils")
val moduleMirror = cm.reflectModule(mathUtilsModule)

// Get singleton instance
val mathUtilsInstance = moduleMirror.instance
println(s"Module instance: $mathUtilsInstance")

// Reflect on the instance
val instanceMirror = moduleMirror.reflect

// Call methods on the object
val addMethod = mathUtilsModule.info.decl(TermName("add")).asMethod
val addMirror = instanceMirror.reflectMethod(addMethod)
val sum = addMirror(3, 4)
println(s"3 + 4 = $sum")

// Access fields
val piField = mathUtilsModule.info.decl(TermName("PI")).asTerm
val piMirror = instanceMirror.reflectField(piField)
println(s"PI = ${piMirror.get}")

Complete Reflection Workflow

Comprehensive example showing the complete reflection workflow.

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

// Example class hierarchy
abstract class Animal(val name: String) {
  def speak: String
  def age: Int = 0
}

class Dog(name: String, val breed: String) extends Animal(name) {
  override def speak: String = "Woof!"
  override def age: Int = 3
  def wagTail(): String = s"$name is wagging tail"
}

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

// 1. Runtime type inspection
val dogType = typeOf[Dog]
println(s"Dog type: $dogType")
println(s"Base classes: ${dogType.baseClasses.map(_.name)}")

// 2. Create instance using reflection
val dogClass = dogType.typeSymbol.asClass
val classMirror = cm.reflectClass(dogClass)
val constructor = dogClass.primaryConstructor.asMethod
val constructorMirror = classMirror.reflectConstructor(constructor)
val dog = constructorMirror("Buddy", "Golden Retriever").asInstanceOf[Dog]

println(s"Created dog: $dog")

// 3. Instance reflection
val dogInstanceMirror = cm.reflect(dog)

// 4. Field access
val nameField = dogType.baseClasses
  .map(_.info)
  .find(_.decl(TermName("name")) != NoSymbol)
  .get.decl(TermName("name")).asTerm
val nameFieldMirror = dogInstanceMirror.reflectField(nameField)
println(s"Dog name: ${nameFieldMirror.get}")

val breedField = dogType.decl(TermName("breed")).asTerm
val breedFieldMirror = dogInstanceMirror.reflectField(breedField)  
println(s"Dog breed: ${breedFieldMirror.get}")

// 5. Method invocation
val speakMethod = dogType.decl(TermName("speak")).asMethod
val speakMirror = dogInstanceMirror.reflectMethod(speakMethod)
println(s"Dog says: ${speakMirror()}")

val wagTailMethod = dogType.decl(TermName("wagTail")).asMethod
val wagTailMirror = dogInstanceMirror.reflectMethod(wagTailMethod)
println(s"Action: ${wagTailMirror()}")

// 6. Object reflection
val shelterModule = cm.staticModule("AnimalShelter")
val shelterModuleMirror = cm.reflectModule(shelterModule)
val shelterInstanceMirror = shelterModuleMirror.reflect

val adoptMethod = shelterModule.info.decl(TermName("adoptAnimal")).asMethod
val adoptMirror = shelterInstanceMirror.reflectMethod(adoptMethod)
println(s"Adoption: ${adoptMirror(dog)}")

Error Handling in Reflective Operations

Common exceptions and error handling patterns:

import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => cm}
import scala.util.{Try, Success, Failure}

def safeReflectiveCall[T](operation: => T): Try[T] = {
  Try(operation).recover {
    case _: ScalaReflectionException => 
      println("Reflection operation failed")
      throw new RuntimeException("Reflection error")
    case _: IllegalArgumentException =>
      println("Invalid arguments provided")  
      throw new RuntimeException("Argument error")
    case _: IllegalAccessException =>
      println("Access denied")
      throw new RuntimeException("Access error")
  }
}

// Safe method invocation
class TestClass {
  def publicMethod(): String = "public"
  private def privateMethod(): String = "private"
}

val testInstance = new TestClass
val instanceMirror = cm.reflect(testInstance)

// This will succeed
safeReflectiveCall {
  val method = typeOf[TestClass].decl(TermName("publicMethod")).asMethod
  val methodMirror = instanceMirror.reflectMethod(method)
  methodMirror()
} match {
  case Success(result) => println(s"Success: $result")
  case Failure(ex) => println(s"Failed: ${ex.getMessage}")
}

// This may fail (accessing private method)
safeReflectiveCall {
  val method = typeOf[TestClass].decl(TermName("privateMethod")).asMethod
  val methodMirror = instanceMirror.reflectMethod(method)
  methodMirror()
} match {
  case Success(result) => println(s"Success: $result")
  case Failure(ex) => println(s"Failed: ${ex.getMessage}")
}

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-lang--scala-reflect

docs

abstract-syntax-trees.md

expressions-reification.md

index.md

macro-development.md

mirrors-reflective-operations.md

runtime-reflection.md

symbol-system.md

type-system.md

type-tags-type-information.md

tile.json