Skip to content

fluttercandies/aopd

Repository files navigation

AOPD

pub package GitHub stars GitHub forks GitHub license GitHub issues FlutterCandies QQ 群

English | 简体中文

AOPD is a Flutter/Dart AOP and compiler-extension framework evolved from AspectD, Beike_AspectD, and other AspectD-derived projects. It keeps the familiar annotation model while moving AOP integration out of compiler/pkg/*, so the mirrored Dart/Flutter SDK packages can stay close to upstream sources.

Before you start: AOPD is not a drop-in flutter pub add. Like all AspectD-style frameworks it weaves at compile time, so it requires a one-time patch to your Flutter SDK checkout (git apply flutter_tools.patch, see Quick Start) for the supported SDK line declared in pubspec.yaml. Adding the dependency alone does nothing until the patch is applied.

What It Provides

AOPD transforms Dart kernel output during Flutter compilation. It supports:

  • @Call for replacing call sites, including constructor call sites.
  • @Execute for wrapping method execution.
  • @Inject for inserting statements at stable source locations.
  • @Add for adding methods to matched classes.
  • @FieldGet for replacing field reads.
  • AopLocation and AopHasCreationLocation for optional runtime widget source-location tracking.

Why It Is Different

The main architecture change is that AOP-specific logic is no longer stored as patches inside compiler/pkg/*.

  • compiler/pkg/* is treated as a pristine SDK mirror.
  • AOPD installs an AOP-owned Flutter target, AopdFlutterTarget, during frontend server startup.
  • Widget location tracking uses aopLocation and $creationLocationAopd_..., so it can coexist with Flutter Inspector's _location tracking.
  • The frontend server snapshot is generated per app under .dart_tool/aopd; prebuilt platform-specific snapshots are not committed to this repository.

Requirements

AOPD targets the Flutter/Dart SDK line declared in pubspec.yaml. The package uses strict Dart SDK constraints so unsupported SDK versions fail during dependency resolution instead of failing later during compilation. Release support changes are recorded in CHANGELOG.md.

The first AOPD-enabled build may take longer because the Flutter tool prepares an app-local compiler workspace, resolves dependencies, and compiles a local frontend-server snapshot. Later builds reuse the snapshot while the cache key is unchanged.

Keep your project in a short ASCII-only path. Chinese characters or very long paths may cause frontend-server snapshot compilation to fail.

Quick Start

Apply the Flutter tool patch to your Flutter SDK checkout:

cd /path/to/flutter
git apply /path/to/aopd/flutter_tools.patch
rm bin/cache/flutter_tools.stamp
flutter doctor

Add AOPD to your Flutter app:

dependencies:
  aopd: any

Enable AOPD in the app pubspec.yaml:

aopd:
  enabled: true

Enable widget source-location tracking only when your app needs AopLocation or AopHasCreationLocation:

aopd:
  enabled: true
  track_widget_creation: true

track_widget_creation defaults to false.

Minimal Aspect

import 'package:aopd/aopd.dart';

@Aspect()
@pragma('vm:entry-point')
class DemoAspect {
  const DemoAspect();

  @Call('package:example/main.dart', 'CounterService', '-increment')
  @pragma('vm:entry-point')
  int onIncrement(PointCut pointCut) {
    final int result = pointCut.proceed() as int;
    return result + 1;
  }
}

Import the aspect library from your app so it is included in the kernel input. In release/profile builds, use @pragma('vm:entry-point') on aspect classes and advice methods you need to keep.

Method name prefixes follow AOPD conventions:

  • -methodName matches an instance method.
  • +methodName matches a static or top-level function.

Example App

The example/ app is the main showcase. It demonstrates:

  • basic annotations and pointcut data;
  • code coverage and wildcard coverage;
  • auto analytics, network tracing, and feature flags;
  • around advice, exception guards, argument rewriting, framework patching, and JSON model serialization;
  • performance monitoring with widget rebuild, frame phase, and image loading hooks.

Run it after applying the Flutter tool patch:

cd example
flutter pub get
flutter run

Flutter may regenerate Android wrapper files for the example project during normal flutter run / flutter build usage.

Documentation

License

AOPD is released under the MIT License. SDK-derived mirror sources under compiler/pkg/* keep their original upstream license headers and notices. See Third-Party Notices for upstream attribution.

About

A Flutter/Dart AOP and compiler-extension framework with app-local frontend-server snapshots and SDK-mirror-friendly compiler integration.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages