Skip to content

Commit 4aac629

Browse files
authored
Merge pull request #365 from wuba/f-provider
fair provider adapt
2 parents 093a1f6 + 8fa8a1d commit 4aac629

File tree

108 files changed

+6373
-17
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+6373
-17
lines changed

dart2dsl/lib/fairdsl/fair_ast_gen.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ class CustomAstVisitor extends SimpleAstVisitor<Map> {
385385
return _buildArgumentList(_visitNodeList(node.arguments));
386386
}
387387

388+
@override
389+
Map visitTypeArgumentList(TypeArgumentList node) {
390+
return _buildTypeArgumentList(_visitNodeList(node.arguments));
391+
}
392+
388393
@override
389394
Map? visitLabel(Label node) {
390395
return _visitNode(node.label);
@@ -543,6 +548,9 @@ class CustomAstVisitor extends SimpleAstVisitor<Map> {
543548
'body': body,
544549
};
545550

551+
Map _buildTypeArgumentList(List<Map> typeArgumentList) =>
552+
{'type': 'TypeArgumentList', 'typeArgumentList': typeArgumentList};
553+
546554
Map _buildArgumentList(List<Map> argumentList) => {'type': 'ArgumentList', 'argumentList': argumentList};
547555

548556
Map _buildStringLiteral(String value) => {'type': 'StringLiteral', 'value': value};

dart2dsl/lib/fairdsl/fair_ast_node.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,10 @@ class MethodInvocation extends AstNode {
432432
Expression? callee;
433433
List<Expression?>? argumentList;
434434
SelectAstClass? selectAstClass;
435+
List<Expression?>? typeArgumentList;
435436

436437
MethodInvocation(this.callee, this.argumentList, this.selectAstClass,
438+
this.typeArgumentList,
437439
{Map? ast})
438440
: super(ast: ast);
439441

@@ -444,6 +446,7 @@ class MethodInvocation extends AstNode {
444446
Expression.fromAst(ast['callee']),
445447
_parseArgumentList(ast['argumentList']),
446448
SelectAstClass.fromAst(ast['selectAstClass']),
449+
_parseTypeArgumentList(ast['typeArguments']),
447450
ast: ast);
448451
}
449452
return null;
@@ -1097,6 +1100,7 @@ class Expression extends AstNode {
10971100
bool? isVariableDeclaration;
10981101
bool? isVariableExpression;
10991102
bool? isFuncParam;
1103+
bool? isTypeName;
11001104

11011105
@override
11021106
Map? toAst() => _ast;
@@ -1137,6 +1141,7 @@ class Expression extends AstNode {
11371141
this.isVariableDeclaration = false,
11381142
this.isVariableExpression = false,
11391143
this.isFuncParam =false,
1144+
this.isTypeName = false,
11401145
Map? ast,
11411146
}) : super(ast: ast);
11421147

@@ -1237,6 +1242,8 @@ class Expression extends AstNode {
12371242
isInterpolationExpression: true, ast: ast);
12381243
} else if (astType == astNodeNameValue(AstNodeName.VariableExpression)) {
12391244
return Expression(VariableExpression.fromAst(ast), isVariableExpression: true, ast: ast);
1245+
} else if (astType == astNodeNameValue(AstNodeName.TypeName)) {
1246+
return Expression(TypeName.fromAst(ast), isTypeName: true, ast: ast);
12401247
}
12411248
return null;
12421249
}
@@ -1311,6 +1318,8 @@ class Expression extends AstNode {
13111318
_expression as InterpolationExpression;
13121319

13131320
VariableExpression get asVariableExpression => _expression as VariableExpression;
1321+
1322+
TypeName get asTypeNameExpression => _expression as TypeName;
13141323
}
13151324

13161325
class SelectAstClass {
@@ -1350,6 +1359,19 @@ List<Expression?> _parseArgumentList(Map? ast) {
13501359
return arguments;
13511360
}
13521361

1362+
///解析TypeArgumentList 字段
1363+
List<Expression?> _parseTypeArgumentList(Map? ast) {
1364+
var arguments = <Expression?>[];
1365+
if (ast != null) {
1366+
var astTypeArgumentList = ast['typeArgumentList'] as List?;
1367+
return astTypeArgumentList
1368+
?.map((arg) => Expression.fromAst(arg))
1369+
.toList() ??
1370+
arguments;
1371+
}
1372+
return arguments;
1373+
}
1374+
13531375
//num _parseNumericValue(Map ast) {
13541376
// num n = 0;
13551377
// if (ast['type'] == astNodeNameValue(AstNodeName.NumericLiteral)) {

dart2dsl/lib/fairdsl/fair_check_node_map.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,6 @@ final checkNode = {
5757
'ImplementsClauseImpl': 'visitImplementsClause',
5858
'WithClauseImpl': 'visitWithClause',
5959
'PropertyAccessImpl': 'visitPropertyAccess',
60-
'PrefixExpressionImpl': 'visitPrefixExpression'
60+
'PrefixExpressionImpl': 'visitPrefixExpression',
61+
'TypeArgumentListImpl':'visitTypeArgumentList'
6162
};

dart2dsl/lib/fairdsl/fair_dsl_gen.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ dynamic _buildWidgetDsl(
219219
var dslMap = {};
220220
var paMap = [];
221221
var naMap = {};
222+
var taMap =[];
222223

223224
var methodInvocationExpression = widgetExpression?.asMethodInvocation;
224225
//普通类
@@ -309,6 +310,13 @@ dynamic _buildWidgetDsl(
309310
}
310311
}
311312

313+
//3.ta
314+
if (methodInvocationExpression.typeArgumentList?.isNotEmpty ?? false) {
315+
taMap.addAll(methodInvocationExpression.typeArgumentList
316+
?.map((ta) => ta?.asTypeNameExpression.name) ??
317+
[]);
318+
}
319+
312320
if (paMap.isNotEmpty) {
313321
dslMap.putIfAbsent('pa', () => paMap);
314322
}
@@ -317,6 +325,10 @@ dynamic _buildWidgetDsl(
317325
dslMap.putIfAbsent('na', () => naMap);
318326
}
319327

328+
if(taMap.isNotEmpty){
329+
dslMap.putIfAbsent('typeArgumentList', () => taMap);
330+
}
331+
320332
return dslMap;
321333
}
322334

fair/assets/fair_core/fair_core.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,28 @@ function _invokeMethod(par) {
5858
if (isNull(func)) {
5959
methodResult = '';
6060
} else {
61+
if (Array.isArray(args)) {
62+
for (let key in args) {
63+
if (args.hasOwnProperty(key)) {
64+
const value = args[key];
65+
if (typeof value === 'object') {
66+
invokeMethodArgsInterceptorManager.handle(value)
67+
//入参被压缩为数组时,确保数组内所有元素经拦截器处理
68+
const innerArgs = value;
69+
for (let innerKey in innerArgs) {
70+
if (innerArgs.hasOwnProperty(innerKey)) {
71+
const innerValue = innerArgs[innerKey];
72+
if (typeof innerValue === 'object') {
73+
invokeMethodArgsInterceptorManager.handle(innerValue)
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}
80+
} else {
81+
console.log('_invokeMethod intercept failed, args is not array');
82+
}
6183
methodResult = func.apply(mClass, args);
6284
}
6385
let result = {
@@ -183,4 +205,29 @@ const invokeFlutterCommonChannel = (invokeData, callback) => {
183205
});
184206
};
185207

208+
class InvokeMethodArgsInterceptorManager {
209+
constructor() {
210+
this.interceptors = [];
211+
}
212+
213+
// 注册拦截器
214+
use(interceptor) {
215+
if (typeof interceptor === 'function') {
216+
this.interceptors.push(interceptor);
217+
}
218+
}
219+
220+
// 处理对象
221+
handle(object) {
222+
for (const interceptor of this.interceptors) {
223+
// 如果有拦截器返回 true,则停止处理并返回结果
224+
if (interceptor(object) === true) {
225+
return object;
226+
}
227+
}
228+
return object;
229+
}
230+
}
186231

232+
// 创建一个拦截器管理器实例
233+
const invokeMethodArgsInterceptorManager = new InvokeMethodArgsInterceptorManager();

fair/lib/fair.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export 'src/experiment/sugar.dart';
1515
export 'src/module/fair_module.dart';
1616
export 'src/public_type.dart';
1717
export 'src/widget.dart';
18+
export 'src/adapter.dart';
19+
export 'src/internal/bind_data.dart';
20+
export 'src/render/builder.dart';
21+
export 'src/render/domain.dart';
22+
export 'src/render/proxy.dart';
1823
export 'src/runtime/plugin/fair_plugin.dart';
1924
export 'src/runtime/plugin/plugin_dispatcher.dart';
2025
export 'src/runtime/plugin/fair_common_plugin.dart';

fair/lib/src/adapter.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'package:fair/fair.dart';
2+
3+
//adapt third-party library
4+
abstract class IFairLibraryAdapter{
5+
//provide the generated module
6+
GeneratedModule? provideGeneratedModule();
7+
8+
//provide fair plugins
9+
Map<String, IFairPlugin>? provideFairPlugins();
10+
11+
//provide js plugins
12+
Map<String, String>? provideJSPlugins();
13+
14+
//provide dynamic widget builder
15+
DynamicWidgetBuilderFunction? provideDynamicWidgetBuilder();
16+
17+
//provide fair delegate
18+
Map<String, FairDelegateBuilder>? provideFairDelegate();
19+
20+
//provide fair module
21+
Map<String, FairModuleBuilder>? provideFairModule();
22+
}

fair/lib/src/app.dart

Lines changed: 65 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@
77
import 'dart:io';
88

99
import 'package:fair/fair.dart';
10-
import 'package:fair/src/internal/bind_data.dart';
11-
import 'package:fair/src/render/builder.dart';
12-
import 'package:fair/src/render/proxy.dart';
10+
import 'package:fair/src/internal/global_state.dart';
1311
import 'package:flutter/foundation.dart';
1412
import 'package:flutter/material.dart';
15-
import 'package:flutter/services.dart';
1613

1714
import 'internal/flexbuffer/fair_js_decoder_http_decoder.dart';
1815
import 'state.dart';
19-
import 'type.dart';
2016

2117
/// Application which can update the widget tree through bundle file.
2218
///
@@ -64,8 +60,7 @@ class FairApp extends InheritedWidget with AppState {
6460
final bool debugShowFairBanner;
6561

6662
/// Define a custom DynamicWidgetBuilder to solve special case
67-
final DynamicWidgetBuilder Function(ProxyMirror? proxyMirror, String? page, BindingData? bound,
68-
{String? bundle})? dynamicWidgetBuilder;
63+
List<DynamicWidgetBuilderFunction?>? dynamicWidgetBuilder;
6964

7065
static final WidgetBuilder _defaultHolder = (BuildContext context) {
7166
return Container(
@@ -119,12 +114,23 @@ class FairApp extends InheritedWidget with AppState {
119114
properties.add(DiagnosticsProperty<Map<String, String>>('bundle', bundleAlias));
120115
}
121116

122-
static void runApplication(Widget app, {
123-
Map<String, IFairPlugin>? plugins,
124-
Map<String, String>? jsPlugins,
125-
String? package,
126-
List<String>? baseJsSources,
117+
static void runApplication(
118+
Widget app, {
119+
Map<String, IFairPlugin>? plugins,
120+
Map<String, String>? jsPlugins,
121+
String? package,
122+
List<String>? baseJsSources,
123+
List<IFairLibraryAdapter>? adapters,
127124
}) {
125+
if (plugins == null) {
126+
plugins = {};
127+
}
128+
if (jsPlugins == null) {
129+
jsPlugins = {};
130+
}
131+
//init 3rd-library adapter
132+
initFairLibraryAdapter(app, plugins: plugins, jsPlugins: jsPlugins, adapters: adapters);
133+
128134
// WidgetsFlutterBinding.ensureInitialized();
129135
FairPluginDispatcher.registerPlugins(plugins);
130136

@@ -139,4 +145,51 @@ class FairApp extends InheritedWidget with AppState {
139145
Runtime().loadCoreJs(package: package, jsPlugins: jsPlugins, baseJsSources: baseJsSources).then((value) => runApp(app));
140146
}
141147
}
148+
149+
///[app] FairApp
150+
///[plugins] Fair plugin code with Dart
151+
///[jsPlugins] Fair plugin code with JavaScript
152+
///[adapters] 3rd-party libraries which adapted Fair
153+
static void initFairLibraryAdapter(
154+
Widget app, {
155+
Map<String, IFairPlugin>? plugins,
156+
Map<String, String>? jsPlugins,
157+
List<IFairLibraryAdapter>? adapters,
158+
}) {
159+
160+
if (adapters != null && adapters.isNotEmpty) {
161+
adapters.forEach((element) {
162+
163+
if (element.provideFairPlugins()?.isNotEmpty == true) {
164+
plugins?.addAll(element.provideFairPlugins()!);
165+
}
166+
167+
if (element.provideJSPlugins()?.isNotEmpty == true) {
168+
jsPlugins?.addAll(element.provideJSPlugins()!);
169+
}
170+
171+
if (app is FairApp) {
172+
if (element.provideFairModule() != null) {
173+
app.modules.addAll(element.provideFairModule());
174+
}
175+
176+
if (element.provideGeneratedModule() != null && app.proxy is ProxyMirror) {
177+
(app.proxy as ProxyMirror).addGeneratedBinding(element.provideGeneratedModule()!);
178+
}
179+
180+
if (element.provideFairDelegate() != null) {
181+
GlobalState.instance().addExtBuilder(element.provideFairDelegate());
182+
}
183+
184+
if (element.provideDynamicWidgetBuilder() != null) {
185+
if (app.dynamicWidgetBuilder == null) {
186+
app.dynamicWidgetBuilder = [element.provideDynamicWidgetBuilder()];
187+
} else {
188+
app.dynamicWidgetBuilder!.add(element.provideDynamicWidgetBuilder());
189+
}
190+
}
191+
}
192+
});
193+
}
194+
}
142195
}

fair/lib/src/internal/global_state.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ class GlobalState {
3939
_builder = builder;
4040
}
4141

42+
void addExtBuilder(Map<String, FairDelegateBuilder>? extBuilder) {
43+
if (extBuilder != null) {
44+
try {
45+
if (_builder != null) {
46+
_builder?.addAll(extBuilder);
47+
} else {
48+
//when _builder is uninitialized
49+
_builder = extBuilder;
50+
}
51+
} catch (e) {
52+
//caught when thrown “_builder is an unmodifiable map”
53+
extBuilder.addAll(_builder!);
54+
_builder = extBuilder;
55+
}
56+
}
57+
}
58+
4259
static String id(String? prefix) {
4360
return '$prefix#${GlobalState._counter++}';
4461
}

fair/lib/src/public_type.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ typedef FairDelegateBuilder = FairDelegate Function(
2020
typedef FairModuleBuilder = FairModule Function();
2121
typedef PropertyValue<T> = T Function();
2222

23+
typedef DynamicWidgetBuilderFunction = DynamicWidgetBuilder Function(ProxyMirror? proxyMirror, String? page, BindingData? bound, {String? bundle});
24+
2325
/// Interface of bundle loader
2426
abstract class BundleLoader {
2527
/// Load resource data into json object; The path can be either assets key or

0 commit comments

Comments
 (0)