Dart has introduced macros, a powerful feature that enhances metaprogramming by enabling developers to generate and manipulate code at compile time.
This capability can significantly reduce boilerplate code, streamline development, and improve application performance.
In this blog, we will explore what Dart macros are and how they work.
What Are Dart Macros?
Dart macros enable you to create custom annotations that can be applied to code elements, streamlining automatic code generation.
This allows you to define behaviours and properties without the need to manually write repetitive code.
- The
JsonCodable
macro: A ready-made macro is available today (behind an experimental flag) to seamlessly address the common issue of tedious JSON serialization and deserialization in Dart. - The macros feature in general: Why we are adding macros to Dart: explaining use cases, benefits over existing code gen solutions, and a brief overview of how writing macros will work in the future once the feature is complete.
Key Features of Dart Macros:-
- Static Metaprogramming: Macros enable code generation and manipulation at compile-time.
- Real-time Operation: They operate on code as it is being written, providing immediate feedback.
- Language Integration: Unlike external code generation tools, macros are fully integrated into the Dart language.
- Customizable: Developers can create their own macros to solve specific problems.
While the full potential of Dart Macros is still being explored, let’s look at an example that’s available for experimentation: the JsonCodable macro.
Setting Up the Dart Macros:-
1. Switch to the Dart dev channel or the Flutter master channel.
2. Run dart --version
and make sure you have the Dart version 3.5.0-152
or later.
3. Add the package json
to dependencies
: dart pub add json
.
4. Enable the experiment in your project’s analysis_options.yaml file located at the root of your package:
1 2 3 |
analyzer: enable-experiment: - macros |
6. Import the package in the file you plan to use it:
1 |
import 'package:json/json.dart'; |
To run your project, use the following command:
1 |
dart run --enable-experiment=macros project/data_macros.dart |
Use the Macros:-
To use the JSnable macro, apply the annotations to the class you want to serialize:
1 2 3 4 5 6 7 8 9 10 |
import 'package:json/json.dart'; @JsonCodable() // Macro annotation. class Employee { final int? employeeID; final String name; final String team; final String jobPost; final String address; } |
The macro examines the User class and generates the implementations of fromJson and toJson based on the fields of the User class.
As a result, you can use toJson and fromJson on objects of the annotated class without having to define them yourself.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void main() { // Given some arbitrary JSON: var employeeJson = { 'employeeID': 10992, 'name': 'Sakshi Rai', 'team': 'Mobikul' 'jobPost': 'Software Engineer' 'address': 'H-28, ARV Park, Sector 63, Noida, Uttar Pradesh 201301' }; // Use the generated members: var employee = Employee.fromJson(employeeJson); } |
Conclusion:-
Macros are a major advancement in the Flutter development ecosystem. By enabling developers to write code that generates other code, macros offer new opportunities for efficiency and innovation.
You can also check other blogs from here.
Thanks for reading this blog ❤️
Hope this blog helped you to better understand Metaprogramming with Code Generation.