Skip to content

Commit

Permalink
fix bug mixin not work
Browse files Browse the repository at this point in the history
fix bug dispatchEvent inject not work
  • Loading branch information
lancexin committed Oct 27, 2022
1 parent 9df26ed commit 5ad6d6a
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 44 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ dart --deterministic --no-sound-null-safety --packages=rebased_package_config.js
## 编译aot dill
dart run frontend_server.dart.snapshot --sdk-root /Users/lixin/Documents/flutter_macos_stable/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --target=flutter --aot --tfa --no-print-incremental-dependencies -Dflutter.inspector.structuredErrors=true -DFLUTTER_WEB_AUTO_DETECT=true -Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation --packages /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/package_config.json --output-dill app.dill --depfile /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/flutter_build/1f083b7beecc20d87dfa8f7e4ca58986/kernel_snapshot.d package:example/main.dart



## 编译运行时dill
dart run frontend_server.dart.snapshot --sdk-root /Users/lixin/Documents/flutter_macos_stable/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --target=flutter --no-print-incremental-dependencies -Dflutter.inspector.structuredErrors=true -DFLUTTER_WEB_AUTO_DETECT=true -Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation --packages /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/package_config.json --output-dill app.dill --depfile /Users/lixin/Documents/FlutterWorkspace/aspect_frontend_server/example/.dart_tool/flutter_build/1f083b7beecc20d87dfa8f7e4ca58986/kernel_snapshot.d package:example/main.dart

Expand All @@ -44,7 +42,6 @@ dart run frontend_server.dart.snapshot --sdk-root /Users/lixin/Documents/flutter
## dill 文件注入成功检测
dart run dump_kernel.dart.snapshot app.dill injected.out.dill.txt

dart /Users/lixin/Documents/FlutterWorkspace/dart_sdk/sdk/pkg/vm/bin/dump_kernel.dart example/.dart_tool/flutter_build/1f083b7beecc20d87dfa8f7e4ca58986/app.dill injected.out.dill.txt

# 替换flutter中的frontend_server.dart.snapshot
1.将新编译的frontend_server.dart.snapshot覆盖 flutter_macos_stable/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot
Expand Down
4 changes: 0 additions & 4 deletions analysis_options.yaml

This file was deleted.

20 changes: 11 additions & 9 deletions example/lib/inject.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';

//普通方法拦截
@pragma("aopd:aspect")
Expand Down Expand Up @@ -183,24 +184,25 @@ class Inject {
"isRegex": false
})
//必须是static,不然不起作用
static void hookHitTest(
static dynamic dispatchEvent(
Object target,
String functionName,
List<dynamic> positionalParams,
Map<String, dynamic> namedParams,
Function proceed) {
debugPrint('hookHitTest - start');
Function.apply(proceed, positionalParams, _transToNamedParams(namedParams));
debugPrint('hookHitTest - end');
PointerEvent event = positionalParams[0];
debugPrint('dispatchEvent - start ${event.kind.name}');
return Function.apply(
proceed, positionalParams, _transToNamedParams(namedParams));
}

//Mixin里方法拦截的例子
@pragma('vm:entry-point')
@pragma("aopd:inject", {
"importUri": "package:example/main.dart",
"clsName": r"__.+MixinHomePageState",
"clsName": "Test6Mixin",
"methodName": "-_test6",
"isRegex": true
"isRegex": false
})
//必须是static,不然不起作用
static void _injectTest6(
Expand Down Expand Up @@ -300,9 +302,9 @@ class Inject {
@pragma('vm:entry-point')
@pragma("aopd:inject", {
"importUri": "package:example/test_mixin.dart",
"clsName": r"_?&BaseController.*&MixinBaseController",
"clsName": "MixinBaseController",
"methodName": "-testMixin",
"isRegex": true
"isRegex": false
})
//必须是static,不然不起作用
static dynamic testMixin(
Expand All @@ -311,7 +313,7 @@ class Inject {
List<dynamic> positionalParams,
Map<String, dynamic> namedParams,
Function proceed) async {
debugPrint("[Inject] testMixin start: ${namedParams["packageName"]}");
debugPrint("[Inject] testMixin start");

return Function.apply(
proceed, positionalParams, _transToNamedParams(namedParams));
Expand Down
6 changes: 3 additions & 3 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ extension ExtensionHomePageState on MyHomePageState {
}
}

mixin MixinHomePageState {
mixin Test6Mixin {
void _test6(int key1, String key2, {String key3 = 'namedkey6'}) {
total++;
debugPrint("$total _test6 $key1 $key2 $key3");
Expand Down Expand Up @@ -144,7 +144,7 @@ class RepositoryImpl extends BaseRepository {
}

class MyHomePageState extends State<MyHomePage>
with MixinHomePageState, MixinHomePageState2 {
with Test6Mixin, MixinHomePageState2 {
int _counter = 0;

final BaseRepository repository = RepositoryImpl();
Expand Down Expand Up @@ -175,7 +175,7 @@ class MyHomePageState extends State<MyHomePage>
// _test3(_counter, "positional3");
// await _test4(_counter, "positional4");
// await _test5(_counter, "positional5");
// _test6(_counter, "positional6");
_test6(_counter, "positional6");
_test7(_counter, "positional7");
// await repository.getAppVersion(packageName: "packageName");
// await repository.getAppVersion2(packageName: "packageName2");
Expand Down
Binary file modified frontend_server.dart.snapshot
Binary file not shown.
66 changes: 41 additions & 25 deletions lib/method_transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,48 +206,40 @@ class _MethodExecuteVisitor extends RecursiveVisitor<void> {

@override
void visitLibrary(Library library) {
String importUri = library.importUri.toString();

bool matches = false;
int aopItemInfoListLen = _aopItemList.length;
for (int i = 0; i < aopItemInfoListLen && !matches; i++) {
MethodItem aopItem = _aopItemList[i];
if ((aopItem.isRegex && RegExp(aopItem.importUri).hasMatch(importUri)) ||
(!aopItem.isRegex && importUri == aopItem.importUri)) {
matches = true;
break;
}
}
if (matches) {
library.visitChildren(this);
}
library.visitChildren(this);
}

@override
void visitClass(Class node) {
String clsName = node.name;

Library originalLibrary = node.enclosingLibrary;

if (node.isAnonymousMixin && node.isEliminatedMixin) {
print(
"[MethodAopTransformer] ${node.name} isAnonymousMixin:${originalLibrary.importUri.toString()}}");
if (node.implementedTypes.isNotEmpty) {
originalLibrary =
node.implementedTypes.first.classNode.enclosingLibrary;
clsName = node.implementedTypes.first.classNode.name;
}
//print(
// "[MethodAopTransformer] visitClass isAnonymousMixin ${node.name} ${originalLibrary.importUri.toString()}}");
}
bool matches = false;
int aopItemInfoListLen = _aopItemList.length;
for (int i = 0; i < aopItemInfoListLen && !matches; i++) {
MethodItem aopItem = _aopItemList[i];

if ((aopItem.isRegex && RegExp(aopItem.clsName).hasMatch(clsName)) ||
(!aopItem.isRegex && clsName == aopItem.clsName) &&
originalLibrary.importUri.toString() == aopItem.importUri) {
if (((aopItem.isRegex && RegExp(aopItem.clsName).hasMatch(clsName)) ||
(!aopItem.isRegex && clsName == aopItem.clsName)) &&
originalLibrary.importUri.toString() == aopItem.importUri) {
matches = true;
break;
}
}

if (matches) {
print(
"[MethodAopTransformer] visitClass match ${node.parent.runtimeType.toString()} ${node.name}");
"[MethodAopTransformer] visitClass match ${originalLibrary.importUri} ${node.name}");
node.visitChildren(this);
}
}
Expand Down Expand Up @@ -283,7 +275,7 @@ class _MethodExecuteVisitor extends RecursiveVisitor<void> {
if (node.parent is Class) {
needCompareClass = true;
originalClass = node.parent as Class;
originalLibrary = originalClass.enclosingLibrary;
originalLibrary = node.enclosingLibrary;
}

String? clsName = null;
Expand All @@ -293,6 +285,20 @@ class _MethodExecuteVisitor extends RecursiveVisitor<void> {
importUri = originalLibrary?.importUri.toString();
}

if (needCompareClass &&
originalClass != null &&
originalClass.isAnonymousMixin &&
originalClass.isEliminatedMixin) {
if (originalClass.implementedTypes.isNotEmpty) {
clsName = originalClass.implementedTypes.first.classNode.name;
importUri = originalClass
.implementedTypes.first.classNode.enclosingLibrary.importUri
.toString();
//print(
// "[MethodAopTransformer] visitProcedure isAnonymousMixin so transform it clasName[${originalClass.name} to $clsName] importUri[${originalLibrary?.importUri.toString()} to $importUri]");
}
}

MethodItem? matchedAopItem = null;
int aopItemInfoListLen = _aopItemList.length;
for (int i = 0; i < aopItemInfoListLen && matchedAopItem == null; i++) {
Expand All @@ -316,7 +322,17 @@ class _MethodExecuteVisitor extends RecursiveVisitor<void> {
}
}
if (matchedAopItem == null) {
if ((originalClass?.isAnonymousMixin ?? false) &&
(originalClass?.isEliminatedMixin ?? false)) {
//print(
// "[MethodAopTransformer] visitProcedure isAnonymousMixin so transform it clasName[${originalClass?.name} to $clsName] importUri[${originalLibrary?.importUri.toString()} to $importUri]");
//print(
// "[MethodAopTransformer] visitProcedure notMatch ${originalLibrary?.importUri.toString()}|${originalClass?.name}|$procedureName");
}
return;
} else {
print(
"[MethodAopTransformer] visitProcedure match ${originalLibrary?.importUri.toString()}|${originalClass?.name}|$procedureName");
}

try {
Expand All @@ -329,20 +345,20 @@ class _MethodExecuteVisitor extends RecursiveVisitor<void> {
node.parent?.parent as Library, matchedAopItem, node);
} else {
print(
"[MethodAopTransformer] error ${node.parent.runtimeType.toString()} ${node.name.text}");
"[MethodAopTransformer] visitProcedure error ${node.parent.runtimeType.toString()} ${node.name.text}");
}
} else {
if (node.parent != null) {
transformInstanceMethodProcedure(
node.parent?.parent as Library, matchedAopItem, node);
} else {
print(
"[MethodAopTransformer] error node.parent == null ${node.name.text}");
"[MethodAopTransformer] visitProcedure error node.parent == null ${node.name.text}");
}
}
} catch (error, stack) {
print(
"[MethodAopTransformer] ${error.toString()} \n ${stack.toString()}");
"[MethodAopTransformer] visitProcedure ${error.toString()} \n ${stack.toString()}");
}
}

Expand Down

0 comments on commit 5ad6d6a

Please sign in to comment.