Skip to content

Commit a2d349c

Browse files
author
Jonah Williams
authored
select ResidentCompiler during FlutterDevice initialization (flutter#28603)
1 parent df465c7 commit a2d349c

File tree

20 files changed

+176
-76
lines changed

20 files changed

+176
-76
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
/packages/flutter/coverage/
3333
version
3434

35+
# packages file containing multi-root paths
36+
.packages.generated
37+
3538
# Flutter/Dart/Pub related
3639
**/doc/api/
3740
.dart_tool/

dev/integration_tests/codegen/lib/main.dart

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ExampleWidget extends StatefulWidget {
1717
}
1818

1919
class _ExampleWidgetState extends State<ExampleWidget> {
20-
String _message = '';
20+
bool _pressed = false;
2121

2222
@override
2323
Widget build(BuildContext context) {
@@ -30,14 +30,21 @@ class _ExampleWidgetState extends State<ExampleWidget> {
3030
child: const Text('Press Button, Get Coffee'),
3131
onPressed: () async {
3232
setState(() {
33-
_message = generated.message;
33+
_pressed = true;
3434
});
3535
},
3636
),
37-
Text(_message),
37+
_pressed ? GeneratedWidget() : const SizedBox(),
3838
],
3939
),
4040
),
4141
);
4242
}
4343
}
44+
45+
class GeneratedWidget extends StatelessWidget {
46+
@override
47+
Widget build(BuildContext context) {
48+
return Text(generated.message);
49+
}
50+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
final String message = 'Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.';
1+
String get message => 'Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import 'package:codegen/main.dart';
2+
import 'package:flutter/material.dart';
3+
import 'package:flutter_test/flutter_test.dart';
4+
5+
void main() {
6+
testWidgets('can reference generated code', (WidgetTester tester) async {
7+
await tester.pumpWidget(MaterialApp(home: GeneratedWidget()));
8+
9+
expect(find.text('Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.'), findsOneWidget);
10+
});
11+
}

dev/integration_tests/codegen/test_driver/main_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ void main() {
2424
final String fullMessage = await driver.getText(find.text(message));
2525
expect(fullMessage, message);
2626
});
27-
}
27+
}

packages/flutter_build/lib/src/kernel_builder.dart

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,25 +89,18 @@ class FlutterKernelBuilder implements Builder {
8989
return;
9090
}
9191
final AssetId outputId = buildStep.inputId.changeExtension(_kFlutterDillOutputExtension);
92-
final AssetId packagesOutputId = buildStep.inputId.changeExtension(_kPackagesExtension);
9392

9493
// Create a scratch space file that can be read/written by the frontend server.
9594
// It is okay to hard-code these file names because we will copy them back
9695
// from the temp directory at the end of the build step.
9796
final Directory tempDirecory = await Directory.systemTemp.createTemp('_flutter_build');
98-
final File packagesFile = File(path.join(tempDirecory.path, _kPackagesExtension));
97+
final Directory projectDir = File(packagesPath).parent;
98+
final String packagesFilePath = path.join(projectDir.path, '.packages.generated');
9999
final File outputFile = File(path.join(tempDirecory.path, 'main.app.dill'));
100100
await outputFile.create();
101-
await packagesFile.create();
102101

103-
final Directory projectDir = File(packagesPath).parent;
104102
final String packageName = buildStep.inputId.package;
105-
final String oldPackagesContents = await File(packagesPath).readAsString();
106-
// Note: currently we only replace the root package with a multiroot
107-
// scheme. To support codegen on arbitrary packages we will need to do
108-
// this for each dependency.
109-
final String newPackagesContents = oldPackagesContents.replaceFirst('$packageName:lib/', '$packageName:$_kMultirootScheme:/');
110-
await packagesFile.writeAsString(newPackagesContents);
103+
111104
String absoluteMainPath;
112105
if (path.isAbsolute(mainPath)) {
113106
absoluteMainPath = mainPath;
@@ -143,7 +136,7 @@ class FlutterKernelBuilder implements Builder {
143136
final String normalRoot = path.join(projectDir.absolute.path, 'lib${Platform.pathSeparator}');
144137
arguments.addAll(<String>[
145138
'--packages',
146-
Uri.file(packagesFile.path).toString(),
139+
packagesFilePath,
147140
'--output-dill',
148141
outputFile.path,
149142
'--filesystem-root',
@@ -158,7 +151,7 @@ class FlutterKernelBuilder implements Builder {
158151
}
159152
final Uri mainUri = _PackageUriMapper.findUri(
160153
absoluteMainPath,
161-
packagesFile.path,
154+
packagesFilePath,
162155
_kMultirootScheme,
163156
<String>[normalRoot, generatedRoot],
164157
);
@@ -178,7 +171,6 @@ class FlutterKernelBuilder implements Builder {
178171
await server.exitCode;
179172
await _stdoutHandler.compilerOutput.future;
180173
await buildStep.writeAsBytes(outputId, await outputFile.readAsBytes());
181-
await buildStep.writeAsBytes(packagesOutputId, await packagesFile.readAsBytes());
182174
} catch (err, stackTrace) {
183175
log.shout('frontend server failed to start: $err, $stackTrace');
184176
}

packages/flutter_tools/lib/src/build_runner/build_runner.dart

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,18 @@ import '../base/logger.dart';
2222
import '../base/process_manager.dart';
2323
import '../codegen.dart';
2424
import '../convert.dart';
25+
import '../dart/package_map.dart';
2526
import '../dart/pub.dart';
2627
import '../globals.dart';
2728
import '../project.dart';
2829
import '../resident_runner.dart';
2930
import 'build_script_generator.dart';
3031

32+
// Arbitrarily choosen multi-root file scheme. This is used to configure the
33+
// frontend_server to resolve a package uri to multiple filesystem directories.
34+
// In this case, the source directory and a generated directory.
35+
const String _kMultirootScheme = 'org-dartlang-app';
36+
3137
/// A wrapper for a build_runner process which delegates to a generated
3238
/// build script.
3339
///
@@ -37,7 +43,7 @@ class BuildRunner extends CodeGenerator {
3743
const BuildRunner();
3844

3945
@override
40-
Future<CodeGenerationResult> build({
46+
Future<CodeGenerationResult> build(FlutterProject flutterProject, {
4147
@required String mainPath,
4248
@required bool aot,
4349
@required bool linkPlatformKernelIn,
@@ -46,8 +52,7 @@ class BuildRunner extends CodeGenerator {
4652
List<String> extraFrontEndOptions = const <String>[],
4753
bool disableKernelGeneration = false,
4854
}) async {
49-
await generateBuildScript();
50-
final FlutterProject flutterProject = await FlutterProject.current();
55+
await generateBuildScript(flutterProject);
5156
final String frontendServerPath = artifacts.getArtifactPath(
5257
Artifact.frontendServerSnapshotForEngineDartSdk
5358
);
@@ -99,7 +104,7 @@ class BuildRunner extends CodeGenerator {
99104
status.stop();
100105
}
101106
if (disableKernelGeneration) {
102-
return const CodeGenerationResult(null, null);
107+
return const CodeGenerationResult(null);
103108
}
104109
/// We don't check for this above because it might be generated for the
105110
/// first time by invoking the build.
@@ -114,21 +119,17 @@ class BuildRunner extends CodeGenerator {
114119
throw Exception('build_runner cannot find generated directory');
115120
}
116121
final String relativeMain = fs.path.relative(mainPath, from: flutterProject.directory.path);
117-
final File packagesFile = fs.file(
118-
fs.path.join(generatedDirectory.path, fs.path.setExtension(relativeMain, '.packages'))
119-
);
120122
final File dillFile = fs.file(
121123
fs.path.join(generatedDirectory.path, fs.path.setExtension(relativeMain, '.app.dill'))
122124
);
123-
if (!packagesFile.existsSync() || !dillFile.existsSync()) {
125+
if (!dillFile.existsSync()) {
124126
throw Exception('build_runner did not produce output at expected location: ${dillFile.path} missing');
125127
}
126-
return CodeGenerationResult(packagesFile, dillFile);
128+
return CodeGenerationResult(dillFile);
127129
}
128130

129131
@override
130-
Future<void> generateBuildScript() async {
131-
final FlutterProject flutterProject = await FlutterProject.current();
132+
Future<void> generateBuildScript(FlutterProject flutterProject) async {
132133
final Directory entrypointDirectory = fs.directory(fs.path.join(flutterProject.dartTool.path, 'build', 'entrypoint'));
133134
final Directory generatedDirectory = fs.directory(fs.path.join(flutterProject.dartTool.path, 'flutter_tool'));
134135
final File buildScript = entrypointDirectory.childFile('build.dart');
@@ -180,7 +181,6 @@ class BuildRunner extends CodeGenerator {
180181
stringBuffer.writeln(' flutter_build:');
181182
stringBuffer.writeln(' sdk: flutter');
182183
syntheticPubspec.writeAsStringSync(stringBuffer.toString());
183-
184184
await pubGet(
185185
context: PubContext.pubGet,
186186
directory: generatedDirectory.path,
@@ -210,16 +210,16 @@ class BuildRunner extends CodeGenerator {
210210
}
211211

212212
@override
213-
Future<CodegenDaemon> daemon({
213+
Future<CodegenDaemon> daemon(FlutterProject flutterProject, {
214214
String mainPath,
215215
bool linkPlatformKernelIn = false,
216216
bool targetProductVm = false,
217217
bool trackWidgetCreation = false,
218218
List<String> extraFrontEndOptions = const <String> [],
219219
}) async {
220220
mainPath ??= findMainDartFile();
221-
await generateBuildScript();
222-
final FlutterProject flutterProject = await FlutterProject.current();
221+
await generateBuildScript(flutterProject);
222+
_generatePackages(flutterProject);
223223
final String frontendServerPath = artifacts.getArtifactPath(
224224
Artifact.frontendServerSnapshotForEngineDartSdk
225225
);
@@ -265,19 +265,28 @@ class BuildRunner extends CodeGenerator {
265265
builder.target = flutterProject.manifest.appName;
266266
}));
267267
final String relativeMain = fs.path.relative(mainPath, from: flutterProject.directory.path);
268-
final File generatedPackagesFile = fs.file(fs.path.join(flutterProject.generated.path, fs.path.setExtension(relativeMain, '.packages')));
269268
final File generatedDillFile = fs.file(fs.path.join(flutterProject.generated.path, fs.path.setExtension(relativeMain, '.app.dill')));
270-
return _BuildRunnerCodegenDaemon(buildDaemonClient, generatedPackagesFile, generatedDillFile);
269+
return _BuildRunnerCodegenDaemon(buildDaemonClient, generatedDillFile);
270+
}
271+
272+
// Create generated packages file which adds a multi-root scheme to the user's
273+
// project directory. Currently we only replace the root package with a multiroot
274+
// scheme. To support codegen on arbitrary packages we would need to do
275+
// this for each dependency.
276+
void _generatePackages(FlutterProject flutterProject) {
277+
final String oldPackagesContents = fs.file(PackageMap.globalPackagesPath).readAsStringSync();
278+
final String appName = flutterProject.manifest.appName;
279+
final String newPackagesContents = oldPackagesContents.replaceFirst('$appName:lib/', '$appName:$_kMultirootScheme:/');
280+
final String generatedPackagesPath = fs.path.setExtension(PackageMap.globalPackagesPath, '.generated');
281+
fs.file(generatedPackagesPath).writeAsStringSync(newPackagesContents);
271282
}
272283
}
273284

274285
class _BuildRunnerCodegenDaemon implements CodegenDaemon {
275-
_BuildRunnerCodegenDaemon(this.buildDaemonClient, this.packagesFile, this.dillFile);
286+
_BuildRunnerCodegenDaemon(this.buildDaemonClient, this.dillFile);
276287

277288
final BuildDaemonClient buildDaemonClient;
278289
@override
279-
final File packagesFile;
280-
@override
281290
final File dillFile;
282291
@override
283292
CodegenStatus get lastStatus => _lastStatus;

0 commit comments

Comments
 (0)