[go: nahoru, domu]

Skip to content

Commit

Permalink
select ResidentCompiler during FlutterDevice initialization (flutter#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams committed Mar 7, 2019
1 parent df465c7 commit a2d349c
Show file tree
Hide file tree
Showing 20 changed files with 176 additions and 76 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
/packages/flutter/coverage/
version

# packages file containing multi-root paths
.packages.generated

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
Expand Down
13 changes: 10 additions & 3 deletions dev/integration_tests/codegen/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ExampleWidget extends StatefulWidget {
}

class _ExampleWidgetState extends State<ExampleWidget> {
String _message = '';
bool _pressed = false;

@override
Widget build(BuildContext context) {
Expand All @@ -30,14 +30,21 @@ class _ExampleWidgetState extends State<ExampleWidget> {
child: const Text('Press Button, Get Coffee'),
onPressed: () async {
setState(() {
_message = generated.message;
_pressed = true;
});
},
),
Text(_message),
_pressed ? GeneratedWidget() : const SizedBox(),
],
),
),
);
}
}

class GeneratedWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text(generated.message);
}
}
2 changes: 1 addition & 1 deletion dev/integration_tests/codegen/lib/message.spec
Original file line number Diff line number Diff line change
@@ -1 +1 @@
final String message = 'Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.';
String get message => 'Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.';
11 changes: 11 additions & 0 deletions dev/integration_tests/codegen/test/example_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:codegen/main.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
testWidgets('can reference generated code', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(home: GeneratedWidget()));

expect(find.text('Thanks for using PourOverSupremeFiesta by Coffee by Flutter Inc.'), findsOneWidget);
});
}
2 changes: 1 addition & 1 deletion dev/integration_tests/codegen/test_driver/main_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ void main() {
final String fullMessage = await driver.getText(find.text(message));
expect(fullMessage, message);
});
}
}
18 changes: 5 additions & 13 deletions packages/flutter_build/lib/src/kernel_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,18 @@ class FlutterKernelBuilder implements Builder {
return;
}
final AssetId outputId = buildStep.inputId.changeExtension(_kFlutterDillOutputExtension);
final AssetId packagesOutputId = buildStep.inputId.changeExtension(_kPackagesExtension);

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

final Directory projectDir = File(packagesPath).parent;
final String packageName = buildStep.inputId.package;
final String oldPackagesContents = await File(packagesPath).readAsString();
// Note: currently we only replace the root package with a multiroot
// scheme. To support codegen on arbitrary packages we will need to do
// this for each dependency.
final String newPackagesContents = oldPackagesContents.replaceFirst('$packageName:lib/', '$packageName:$_kMultirootScheme:/');
await packagesFile.writeAsString(newPackagesContents);

String absoluteMainPath;
if (path.isAbsolute(mainPath)) {
absoluteMainPath = mainPath;
Expand Down Expand Up @@ -143,7 +136,7 @@ class FlutterKernelBuilder implements Builder {
final String normalRoot = path.join(projectDir.absolute.path, 'lib${Platform.pathSeparator}');
arguments.addAll(<String>[
'--packages',
Uri.file(packagesFile.path).toString(),
packagesFilePath,
'--output-dill',
outputFile.path,
'--filesystem-root',
Expand All @@ -158,7 +151,7 @@ class FlutterKernelBuilder implements Builder {
}
final Uri mainUri = _PackageUriMapper.findUri(
absoluteMainPath,
packagesFile.path,
packagesFilePath,
_kMultirootScheme,
<String>[normalRoot, generatedRoot],
);
Expand All @@ -178,7 +171,6 @@ class FlutterKernelBuilder implements Builder {
await server.exitCode;
await _stdoutHandler.compilerOutput.future;
await buildStep.writeAsBytes(outputId, await outputFile.readAsBytes());
await buildStep.writeAsBytes(packagesOutputId, await packagesFile.readAsBytes());
} catch (err, stackTrace) {
log.shout('frontend server failed to start: $err, $stackTrace');
}
Expand Down
49 changes: 29 additions & 20 deletions packages/flutter_tools/lib/src/build_runner/build_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ import '../base/logger.dart';
import '../base/process_manager.dart';
import '../codegen.dart';
import '../convert.dart';
import '../dart/package_map.dart';
import '../dart/pub.dart';
import '../globals.dart';
import '../project.dart';
import '../resident_runner.dart';
import 'build_script_generator.dart';

// Arbitrarily choosen multi-root file scheme. This is used to configure the
// frontend_server to resolve a package uri to multiple filesystem directories.
// In this case, the source directory and a generated directory.
const String _kMultirootScheme = 'org-dartlang-app';

/// A wrapper for a build_runner process which delegates to a generated
/// build script.
///
Expand All @@ -37,7 +43,7 @@ class BuildRunner extends CodeGenerator {
const BuildRunner();

@override
Future<CodeGenerationResult> build({
Future<CodeGenerationResult> build(FlutterProject flutterProject, {
@required String mainPath,
@required bool aot,
@required bool linkPlatformKernelIn,
Expand All @@ -46,8 +52,7 @@ class BuildRunner extends CodeGenerator {
List<String> extraFrontEndOptions = const <String>[],
bool disableKernelGeneration = false,
}) async {
await generateBuildScript();
final FlutterProject flutterProject = await FlutterProject.current();
await generateBuildScript(flutterProject);
final String frontendServerPath = artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk
);
Expand Down Expand Up @@ -99,7 +104,7 @@ class BuildRunner extends CodeGenerator {
status.stop();
}
if (disableKernelGeneration) {
return const CodeGenerationResult(null, null);
return const CodeGenerationResult(null);
}
/// We don't check for this above because it might be generated for the
/// first time by invoking the build.
Expand All @@ -114,21 +119,17 @@ class BuildRunner extends CodeGenerator {
throw Exception('build_runner cannot find generated directory');
}
final String relativeMain = fs.path.relative(mainPath, from: flutterProject.directory.path);
final File packagesFile = fs.file(
fs.path.join(generatedDirectory.path, fs.path.setExtension(relativeMain, '.packages'))
);
final File dillFile = fs.file(
fs.path.join(generatedDirectory.path, fs.path.setExtension(relativeMain, '.app.dill'))
);
if (!packagesFile.existsSync() || !dillFile.existsSync()) {
if (!dillFile.existsSync()) {
throw Exception('build_runner did not produce output at expected location: ${dillFile.path} missing');
}
return CodeGenerationResult(packagesFile, dillFile);
return CodeGenerationResult(dillFile);
}

@override
Future<void> generateBuildScript() async {
final FlutterProject flutterProject = await FlutterProject.current();
Future<void> generateBuildScript(FlutterProject flutterProject) async {
final Directory entrypointDirectory = fs.directory(fs.path.join(flutterProject.dartTool.path, 'build', 'entrypoint'));
final Directory generatedDirectory = fs.directory(fs.path.join(flutterProject.dartTool.path, 'flutter_tool'));
final File buildScript = entrypointDirectory.childFile('build.dart');
Expand Down Expand Up @@ -180,7 +181,6 @@ class BuildRunner extends CodeGenerator {
stringBuffer.writeln(' flutter_build:');
stringBuffer.writeln(' sdk: flutter');
syntheticPubspec.writeAsStringSync(stringBuffer.toString());

await pubGet(
context: PubContext.pubGet,
directory: generatedDirectory.path,
Expand Down Expand Up @@ -210,16 +210,16 @@ class BuildRunner extends CodeGenerator {
}

@override
Future<CodegenDaemon> daemon({
Future<CodegenDaemon> daemon(FlutterProject flutterProject, {
String mainPath,
bool linkPlatformKernelIn = false,
bool targetProductVm = false,
bool trackWidgetCreation = false,
List<String> extraFrontEndOptions = const <String> [],
}) async {
mainPath ??= findMainDartFile();
await generateBuildScript();
final FlutterProject flutterProject = await FlutterProject.current();
await generateBuildScript(flutterProject);
_generatePackages(flutterProject);
final String frontendServerPath = artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk
);
Expand Down Expand Up @@ -265,19 +265,28 @@ class BuildRunner extends CodeGenerator {
builder.target = flutterProject.manifest.appName;
}));
final String relativeMain = fs.path.relative(mainPath, from: flutterProject.directory.path);
final File generatedPackagesFile = fs.file(fs.path.join(flutterProject.generated.path, fs.path.setExtension(relativeMain, '.packages')));
final File generatedDillFile = fs.file(fs.path.join(flutterProject.generated.path, fs.path.setExtension(relativeMain, '.app.dill')));
return _BuildRunnerCodegenDaemon(buildDaemonClient, generatedPackagesFile, generatedDillFile);
return _BuildRunnerCodegenDaemon(buildDaemonClient, generatedDillFile);
}

// Create generated packages file which adds a multi-root scheme to the user's
// project directory. Currently we only replace the root package with a multiroot
// scheme. To support codegen on arbitrary packages we would need to do
// this for each dependency.
void _generatePackages(FlutterProject flutterProject) {
final String oldPackagesContents = fs.file(PackageMap.globalPackagesPath).readAsStringSync();
final String appName = flutterProject.manifest.appName;
final String newPackagesContents = oldPackagesContents.replaceFirst('$appName:lib/', '$appName:$_kMultirootScheme:/');
final String generatedPackagesPath = fs.path.setExtension(PackageMap.globalPackagesPath, '.generated');
fs.file(generatedPackagesPath).writeAsStringSync(newPackagesContents);
}
}

class _BuildRunnerCodegenDaemon implements CodegenDaemon {
_BuildRunnerCodegenDaemon(this.buildDaemonClient, this.packagesFile, this.dillFile);
_BuildRunnerCodegenDaemon(this.buildDaemonClient, this.dillFile);

final BuildDaemonClient buildDaemonClient;
@override
final File packagesFile;
@override
final File dillFile;
@override
CodegenStatus get lastStatus => _lastStatus;
Expand Down
Loading

0 comments on commit a2d349c

Please sign in to comment.