5
5
6
6
// @dart = 2.8
7
7
8
+ import 'package:analyzer/dart/analysis/analysis_context.dart' ;
9
+ import 'package:analyzer/dart/analysis/analysis_context_collection.dart' ;
10
+ import 'package:analyzer/dart/analysis/results.dart' ;
11
+ import 'package:analyzer/dart/ast/ast.dart' ;
8
12
import 'package:file/file.dart' ;
9
13
import 'package:flutter_tools/src/base/file_system.dart' ;
10
14
import 'package:flutter_tools/src/base/terminal.dart' ;
@@ -114,6 +118,38 @@ mixin DartPluginRegistry on FlutterCommand {
114
118
String get targetFile => _entrypoint ?? super .targetFile;
115
119
}
116
120
121
+ /// Finds entry point functions annotated with `@pragma('vm:entry-point')`
122
+ /// from [dartFile] and returns their names.
123
+ List <String > _findDartEntrypoints (File dartFile) {
124
+ final String path = dartFile.absolute.path;
125
+ final AnalysisContextCollection collection =
126
+ AnalysisContextCollection (includedPaths: < String > [path]);
127
+ final AnalysisContext context = collection.contextFor (path);
128
+ final SomeParsedUnitResult parsed =
129
+ context.currentSession.getParsedUnit2 (path);
130
+ final List <String > names = < String > ['main' ];
131
+ if (parsed is ParsedUnitResult ) {
132
+ for (final FunctionDeclaration function
133
+ in parsed.unit.declarations.whereType <FunctionDeclaration >()) {
134
+ if (function.name.name == 'main' ) {
135
+ continue ;
136
+ }
137
+ for (final Annotation annotation in function.metadata) {
138
+ if (annotation.name.name != 'pragma' ) {
139
+ continue ;
140
+ }
141
+ final ArgumentList arguments = annotation.arguments;
142
+ if (arguments != null &&
143
+ arguments.arguments.isNotEmpty &&
144
+ arguments.arguments.first.toSource ().contains ('vm:entry-point' )) {
145
+ names.add (function.name.name);
146
+ }
147
+ }
148
+ }
149
+ }
150
+ return names;
151
+ }
152
+
117
153
/// Creates an entrypoint wrapper of [targetFile] and returns its path.
118
154
/// This effectively adds support for Dart plugins.
119
155
///
@@ -137,31 +173,44 @@ Future<String> _createEntrypoint(
137
173
project.directory.childFile ('.packages' ),
138
174
logger: globals.logger,
139
175
);
140
- final FlutterProject flutterProject = FlutterProject .current ();
176
+ final File mainFile = globals.fs.file (targetFile);
177
+ final Uri mainUri = mainFile.absolute.uri;
141
178
final LanguageVersion languageVersion = determineLanguageVersion (
142
- globals.fs. file (targetFile) ,
143
- packageConfig[flutterProject.manifest.appName] ,
179
+ mainFile ,
180
+ packageConfig. packageOf (mainUri) ,
144
181
Cache .flutterRoot,
145
182
);
146
-
147
- final Uri mainUri = globals.fs.file (targetFile).absolute.uri;
148
183
final String mainImport =
149
184
packageConfig.toPackageUri (mainUri)? .toString () ?? mainUri.toString ();
185
+ final List <String > dartEntrypoints = _findDartEntrypoints (mainFile);
150
186
151
- entrypoint.writeAsStringSync ('''
187
+ final Map <String , dynamic > context = < String , dynamic > {
188
+ 'mainImport' : mainImport,
189
+ 'dartLanguageVersion' : languageVersion.toString (),
190
+ 'dartEntrypoints' :
191
+ dartEntrypoints.map ((String name) => < String , String > {'name' : name}),
192
+ };
193
+ _renderTemplateToFile (
194
+ '''
152
195
//
153
196
// Generated file. Do not edit.
154
197
//
155
- // @dart=${ languageVersion . major }.${ languageVersion . minor }
198
+ // @dart = {{dartLanguageVersion} }
156
199
157
- import '$ mainImport ' as entrypoint;
200
+ import '{{ mainImport}} ' as entrypoint;
158
201
import 'generated_plugin_registrant.dart';
159
202
160
- Future<void> main() async {
203
+ {{#dartEntrypoints}}
204
+ @pragma('vm:entry-point')
205
+ void {{name}}() {
161
206
registerPlugins();
162
- entrypoint.main ();
207
+ entrypoint.{{name}} ();
163
208
}
164
- ''' );
209
+ {{/dartEntrypoints}}
210
+ ''' ,
211
+ context,
212
+ entrypoint.path,
213
+ );
165
214
return entrypoint.path;
166
215
}
167
216
0 commit comments