Skip to content

Commit 98c2a29

Browse files
committed
fix bug use Future generic error
1 parent 0e46935 commit 98c2a29

7 files changed

Lines changed: 152 additions & 1 deletion

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dart compile kernel --output=dump_kernel.dart.snapshot bin/dump_kernel.dart
2727
# 测试编译
2828
1. 生成kernel_snapshot.d,先用普通方法run一下example,在example/.dart_tool/flutter_build下面会有生成编译临时的文件
2929

30-
2. 执行下面命令测试(注意目录替换)):
30+
2. 执行下面命令测试(注意目录替换):
3131

3232

3333
## 编译aot dill

example/lib/inject.dart

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,89 @@ class Inject {
256256
//Function.apply(proceed, positionalParams, _transToNamedParams(namedParams));
257257
}
258258

259+
@pragma('vm:entry-point')
260+
@pragma("aopd:inject", {
261+
"importUri": "package:example/main.dart",
262+
"clsName": "",
263+
"methodName": "+_test8",
264+
"isRegex": false
265+
})
266+
//必须是static,不然不起作用
267+
static dynamic _injectTest8(
268+
Object target,
269+
String functionName,
270+
List<dynamic> positionalParams,
271+
Map<dynamic, dynamic> namedParams,
272+
Function proceed) async {
273+
debugPrint("[Inject] $functionName start ${positionalParams[0]}");
274+
return proceed.call(positionalParams[0]);
275+
}
276+
277+
@pragma('vm:entry-point')
278+
@pragma("aopd:inject", {
279+
"importUri": "package:example/main.dart",
280+
"clsName": "",
281+
"methodName": "+_test9",
282+
"isRegex": false
283+
})
284+
//必须是static,不然不起作用
285+
static dynamic _injectTest9(
286+
Object target,
287+
String functionName,
288+
List<dynamic> positionalParams,
289+
Map<dynamic, dynamic> namedParams,
290+
Function proceed) async {
291+
debugPrint(
292+
"[Inject] $functionName start ${positionalParams[0]},p0.type:${positionalParams[0].runtimeType},func.type;${proceed.runtimeType}");
293+
294+
var r = proceed.call(positionalParams[0]);
295+
debugPrint("[Inject] $functionName end ${await r},r.type:${r.runtimeType}");
296+
return r;
297+
}
298+
299+
@pragma('vm:entry-point')
300+
@pragma("aopd:inject", {
301+
"importUri": "package:example/main.dart",
302+
"clsName": "G",
303+
"methodName": "-getT",
304+
"isRegex": false
305+
})
306+
//必须是static,不然不起作用
307+
static dynamic _injectGgetT(
308+
Object target,
309+
String functionName,
310+
List<dynamic> positionalParams,
311+
Map<dynamic, dynamic> namedParams,
312+
Function proceed) {
313+
debugPrint("[Inject] $functionName start func.type;${proceed.runtimeType}");
314+
315+
var r = proceed.call();
316+
debugPrint("[Inject] $functionName end ${r},r.type:${r.runtimeType}");
317+
return r;
318+
}
319+
320+
@pragma('vm:entry-point')
321+
@pragma("aopd:inject", {
322+
"importUri": "package:example/main.dart",
323+
"clsName": "G",
324+
"methodName": "-setT",
325+
"isRegex": false
326+
})
327+
//必须是static,不然不起作用
328+
static dynamic _injectGsetT(
329+
Object target,
330+
String functionName,
331+
List<dynamic> positionalParams,
332+
Map<dynamic, dynamic> namedParams,
333+
Function proceed) {
334+
debugPrint(
335+
"[Inject] $functionName start ${positionalParams[0]},p0.type:${positionalParams[0].runtimeType},func.type;${proceed.runtimeType}");
336+
337+
var r = proceed.call(positionalParams[0]);
338+
debugPrint("[Inject] $functionName end ${r},r.type:${r.runtimeType}");
339+
return r;
340+
}
341+
259342
@pragma('vm:entry-point')
260343
@pragma("aopd:inject", {
261344
"importUri": "package:example/main.dart",

example/lib/main.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:example/test_mixin.dart';
22
import 'package:flutter/material.dart';
3+
import 'dart:core';
34

45
//必须有,不然不起作用
56
// ignore: unused_import
@@ -122,6 +123,29 @@ mixin MixinHomePageState2<T extends StatefulWidget> on State<T> {
122123
}
123124
}
124125

126+
T _test8<T>(T t) {
127+
print("_test8 t.type is ${t.runtimeType}");
128+
return t;
129+
}
130+
131+
Future<T> _test9<T>(T t) async {
132+
print("_test9 t.type is ${t.runtimeType}");
133+
return t;
134+
}
135+
136+
class G<T> {
137+
T t;
138+
139+
G(this.t);
140+
T getT() {
141+
return t;
142+
}
143+
144+
void setT(T t) {
145+
this.t = t;
146+
}
147+
}
148+
125149
abstract class Repository {}
126150

127151
abstract class BaseRepository extends Repository with MixinUpgrade {
@@ -188,6 +212,30 @@ class _MyHomePageState extends State<MyHomePage>
188212
_test6(_counter, "positional6");
189213
_test7(_counter, "positional7");
190214

215+
_test8(1);
216+
_test8(1.1);
217+
_test8("aaa");
218+
219+
var t1 = await _test9(1);
220+
var t2 = await _test9("aaa");
221+
222+
var f = Future(() {
223+
return 1;
224+
});
225+
226+
var t3 = await _test9(f);
227+
print("${t1} t1.type ${t1.runtimeType}");
228+
print("${t2} t2.type ${t2.runtimeType}");
229+
print("${t3} t3.type ${t3.runtimeType}");
230+
231+
var g = G(1);
232+
var t4 = g.getT();
233+
print("${t4} t4.type ${t4.runtimeType}");
234+
235+
var g2 = G("aaa");
236+
var t5 = g2.getT();
237+
print("${t5} t5.type ${t5.runtimeType}");
238+
191239
repository.getAppVersion(packageName: "packageName");
192240
repository.getAppVersion2(packageName: "packageName2");
193241
repository.p1 = 1;
-16 Bytes
Binary file not shown.
-16 Bytes
Binary file not shown.
288 Bytes
Binary file not shown.

lib/method_transformer.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'dart:io';
55
import 'package:frontend_server/frontend_server.dart' as frontend;
66

77
import 'package:kernel/ast.dart';
8+
import 'package:kernel/core_types.dart';
89
import 'utils.dart';
910

1011
class MethodItem {
@@ -573,10 +574,29 @@ class _MethodExecuteVisitor extends RecursiveVisitor {
573574
final List<MapLiteralEntry> entries = <MapLiteralEntry>[];
574575
for (NamedExpression namedExpression in originArguments.named) {
575576
//这里用SymbolLiteral貌似无效,退而求其次用StringLiteral
577+
576578
entries.add(MapLiteralEntry(
577579
StringLiteral(namedExpression.name), namedExpression.value));
578580
}
579581
redirectArguments.positional.add(MapLiteral(entries));
582+
583+
//如果返回类型是 Future 或者FutureOrType,强制转换成 dynamic
584+
if (shouldReturn && functionNode.returnType is FutureOrType ||
585+
(functionNode.returnType is InterfaceType &&
586+
(functionNode.returnType as InterfaceType)
587+
.classNode
588+
.enclosingLibrary
589+
.importUri
590+
.toString() ==
591+
'dart:async' &&
592+
(functionNode.returnType as InterfaceType).classNode.name ==
593+
'Future')) {
594+
stdout.writeln(
595+
"${originalProcedure.name.toString()} return type is FutureOrType ${functionNode.returnType.toStringInternal()}");
596+
//这里还有第二种做法,强制返回 Future<dynamic>
597+
functionNode.returnType = DynamicType();
598+
functionNode.emittedValueType = DynamicType();
599+
}
580600
//proceed
581601
final FunctionNode newFunctionNode = FunctionNode(bodyStatements,
582602
typeParameters: AopUtils.deepCopyASTNodes<TypeParameter>(

0 commit comments

Comments
 (0)