← All areas

Reflection

Reflection is the base technology that lets a Tom application assemble itself at runtime and lets tools read a codebase's API without re-running the analyzer. It is one of the seven building blocks of the Tom framework, and it answers a single recurring need: programs that must know about other programs — their classes, fields, methods, and metadata — without hard-coding that knowledge in advance.

The area splits cleanly into two complementary engines. Engine 1 is runtime reflection: the ability of a running Dart program to inspect an object's type, read and write its fields, construct instances, walk a class hierarchy, and invoke methods by name. Engine 2 is source analysis: the ability of a build-time tool to walk Dart source with the analyzer and emit a stable, serialized description of a codebase's structure, which downstream tooling — and this website's reference pages — then consume without ever loading the analyzer again. Both produce the same kind of value, a structured model of code, but at different times and in different places: one inside the live application, the other on a build machine.

The two engines also have different lineage, which is worth stating plainly. Engine 1 (tom_reflection and its generator) is derived from the Dart team's reflectable package (BSD-3-Clause), with Tom-specific refactoring, fixes, and enhancements. Engine 2 (tom_reflector and its model) is original work — renamed from the earlier tom_analyzer — that shares no code or lineage with reflectable. They are designed as siblings under one toolkit, but they are not two faces of one implementation.

Why it exists

Dart's built-in dart:mirrors is unavailable in AOT and Flutter and bloats output everywhere else, because the compiler cannot know in advance which members a program will reflect on. A framework that wants applications to wire themselves together from configuration — resolving widgets, forms, serializers, and services by name rather than by compiled-in references — needs a reflection mechanism that is lightweight, capability-scoped, and works on every target including the browser. Engine 1 provides exactly that, by generating the reflection data ahead of time and shipping only what each program declares it needs.

That last point is the central idea, inherited from reflectable: pay only for the reflection you use. You declare a const reflector whose constructor lists the capabilities you need (invoke methods? enumerate declarations? walk type relations? read metadata?), annotate your target classes with it, and a generator emits a *.reflection.dart file holding precomputed mirror data — only for the capabilities you asked for. A reflector that needs only method invocation produces far less code than one that asks for everything, so generated output stays small and tree-shakeable.

Engine 2 exists for a different but related reason. Tom's documentation, its API reference, its specification tooling, and its code generators all need a faithful, machine-readable picture of what a package exposes. Re-running the Dart analyzer in every consumer is slow and couples each one to a specific analyzer (and Dart) version. Instead, the analyzer is run once, and its findings are frozen into a serialized model that anyone can read as plain data — insulating downstream tools from analyzer churn.

The components and modules

The area is delivered by the Reflection component (reflection) and its five modules, which divide along the two engines above.

Engine 1 — runtime reflection

  • tom_reflection — code-generation-based runtime reflection for Dart, the

engine that gives you mirrors on live objects. Through a capability-gated reflector you invoke methods and accessors by name, construct instances, read declarations and metadata, and walk type relations — all without knowing the type at compile time. This is the module tom_core relies on to auto-assemble an application at runtime. - tom_reflection_generator — the code generator behind engine 1. It runs the analyzer over your sources, finds the classes annotated with a reflector, reads the capabilities that reflector declares, and writes exactly the required mirror data into a sibling *.reflection.dart. It ships two interchangeable surfaces over one pipeline — a build_runner builder for normal development and a standalone reflectiongenerator CLI (built on tom_build_base) for one-off and CI builds — that produce byte-identical output for the same input. - tom_reflection_test — the end-to-end fixture suite for engine 1. Each fixture declares a reflector with some set of capabilities, annotates targets, and asserts that reflection over the generated data behaves correctly; every fixture is paired with a committed *_test.reflection.dart (the expected generator output). It therefore guards both axes of the contract: a behaviour regression (a mirror returns the wrong thing) and a generation regression (the generator emits different code).

Engine 2 — source analysis

  • tom_reflector — an analyzer-based, build-time structural reflection

engine. It walks the Dart analyzer's element model and produces a serializable object graph of a codebase's shape — libraries, types, members, parameters, signatures, annotations, and source locations — plus optional *.r.dart reflection output. It offers both a barrel mode (reflect everything a package exports) and an entry-point reachability mode (reflect only what is reachable and wanted). This is the engine behind the API reference shown on this site. - tom_reflector_model — the pure, serializable object model behind engine 2, rooted at AnalysisResult. It defines the typed data structures that represent an analyzed codebase and their JSON/YAML round-trip, using stable id-based references so cyclic graphs serialize safely. Crucially it has no dependency on the Dart analyzer (only collection and yaml), so a snapshot taken on a build machine can be loaded anywhere — including in a pure web client — without the analyzer present.

How it fits the rest of Tom

Reflection sits underneath the application architecture rather than beside it. In the framework overview it is named as the underlying base technology for the runtime auto-assembly of Tom applications: tom_core_kernel carries the reflection glue that turns engine 1's generated data into live wiring, so a Tom app constructs its UI, forms, and services from declarative resources. On the tooling side, engine 2 (tom_reflector / tom_reflector_model) feeds the API reference and the specification tools, closing the loop between source code and the documentation that describes it.

In short: the runtime engine lets applications read themselves; the analysis engine lets tools read applications. Together they make Tom's "describe it once, wire it everywhere" model possible.

In this area
Explore other areas

D4rt Interpreter

1 member
The D4rt Interpreter is where Tom runs and generates Dart code at runtime, inside a permission-guarded sandbox, without ahead-of-time compilation.

Tom Brain Agent

1 member
Tom Brain is the intelligence layer of the Tom framework: from the outside it looks like an ordinary OpenAI-format LLM API server, but inside it is a single always-running engine that runs procedures — sandboxed D4rt scripts — over a self-organising, "dreaming" graph memory.

Docspecs/Codespecs Software Factory

0 members
The Docspecs/Codespecs Software Factory is the staged, AI-assisted process by which Tom applications are created — from an initial idea, through structured specifications, to working, tested code — with complete traceability from a business requirement to the implementation and the test that covers it.

Build tools

2 members
Build tools are the command-line machinery that develops, builds, tests, documents, and deploys the Tom framework and the applications made with it.

Core Application Framework

1 member
The Core Application Framework is the foundation every Tom application is built on: a Flutter client and a Dart server joined by a typed interface, both resting on a shared kernel.

VS Code Extension and VS Code Scripting

1 member
This area is how the Tom framework is developed inside the editor: a VS Code extension that hosts a Dart bridge, so framework tooling and automation can be written in Dart — the same language as the framework itself — with full access to the VS Code API.