dart_macros library

A powerful macro processing system for Dart that enables compile-time code generation and metaprogramming capabilities.

This package provides a comprehensive macro system that allows you to:

  • Define and use C-style macros in Dart
  • Generate boilerplate code using annotations
  • Perform compile-time code transformations
  • Handle conditional compilation

Getting Started

Add the package to your pubspec.yaml:

dependencies:
  dart_macros: ^1.0.0

Basic Usage

Object-like Macros

Simple constant definitions:

#define VERSION "1.0.0"
#define DEBUG true

Function-like Macros

Parameterized code generation:

#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define ASSERT_NOT_NULL(x) if (x == null) throw ArgumentError('$x must not be null')

Data Class Generation

Automatic generation of common utility methods:

@Data()
class Person {
  final String name;
  final int age;

  Person(this.name, this.age);
}

This will generate:

  • toString() implementation
  • equals() and hashCode
  • copyWith() method
  • JSON serialization methods

Features

Macro Processing

The package provides a robust macro processing system that supports:

  • Object-like and function-like macros
  • Nested macro expansion
  • Recursion detection and prevention
  • Error reporting with source locations

Code Generation

Built-in code generation capabilities include:

  • Data class utilities
  • Builder methods
  • Serialization code
  • Custom annotations

Error Handling

Comprehensive error handling with:

  • Detailed error messages
  • Source code locations
  • Stack traces
  • Validation checks

Architecture

The package is organized into several core components:

Core Components

  • MacroProcessor - The main engine for macro processing
  • MacroDefinition - Represents macro definitions
  • Location - Tracks source code positions
  • ExpressionEvaluator - Evaluates compile-time expressions

Annotations

  • @Data - Generates common utility methods
  • More annotations coming soon...

Exception Handling

Examples

Basic Macro Usage

// Define a simple macro
#define PI 3.14159

// Use it in your code
double circumference(double radius) {
  return 2 * PI * radius;
}

Function Macro

// Define a function-like macro
#define MIN(x, y) ((x) < (y) ? (x) : (y))

// Use it in your code
int minimum = MIN(a, b);

Data Class

@Data(
  generateToString: true,
  generateEquality: true,
  generateJson: true,
)
class User {
  final String id;
  final String name;
  final int age;

  User(this.id, this.name, this.age);
}

Best Practices

  1. Macro Names

    • Use UPPERCASE for object-like macros
    • Use PascalCase for function-like macros
    • Avoid common variable names
  2. Parentheses

    • Always wrap macro parameters in parentheses
    • Use extra parentheses in expressions
  3. Error Handling

    • Always handle potential macro exceptions
    • Provide meaningful error messages
    • Include source locations in custom exceptions

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

This package is licensed under the MIT License. See the LICENSE file for details.

Classes

BuildConfig
Marks code as configurable via build configuration
Data
Debug
Defines a debug-only macro
Define
Defines a simple constant macro
DefineMacro
Defines a function-like macro
Feature
Marks code to be included only if a feature flag is enabled
FlutterMacros
Helper to register macros for Flutter applications.
MacroAnnotation
Base class for all macro annotations
MacroDefinition
Represents a macro definition in the system.
MacroFile
Marks a file for macro processing
MacroProcessor
The main engine responsible for macro processing and expansion.
Macros
Primary interface for defining and accessing macros at runtime.
Platform
Conditional compilation based on platform
PlatformSpecific
Marks code for platform-specific implementation
Release
Defines a release-only macro
ResourceLoader
Handles safe loading of resources relative to macro source files.

Enums

MacroType
Represents the different types of macros supported by the system.

Extensions

DataAnnotationHandler on MacroProcessor
Extension for handling @Data annotations in the macro processor.
DataClassMacros on Macros
JsonMacros on Macros
MacroFunctions on Macros
Built-in macro functions extension
ResourceLoaderExtension on MacroProcessor
Extension methods for MacroProcessor to support resource loading.
ResourceProcessorExtension on MacroProcessor
Extension for the MacroProcessor to support resource operations

Functions

initializeDartMacros() Future<void>
Initializes the Dart macros package.

Exceptions / Errors

ConditionalCompilationException
Exception thrown when there's an error in conditional compilation directives.
MacroArgumentException
Exception thrown when there's an error with macro arguments.
MacroDefinitionException
Exception thrown when there's an error in macro definition syntax or semantics.
MacroException
Base class for all macro-related exceptions in the system.
MacroUsageException
Exception thrown when a macro is used incorrectly.
RecursiveMacroException
Exception thrown when a recursive macro definition is detected.
UndefinedMacroException
Exception thrown when attempting to use a macro that hasn't been defined.