select ResidentCompiler during FlutterDevice initialization (#28603)

This commit is contained in:
Jonah Williams 2019-03-07 11:02:42 -08:00 committed by GitHub
parent df465c7718
commit a2d349c4c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 176 additions and 76 deletions

3
.gitignore vendored
View file

@ -32,6 +32,9 @@
/packages/flutter/coverage/
version
# packages file containing multi-root paths
.packages.generated
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/

View file

@ -17,7 +17,7 @@ class ExampleWidget extends StatefulWidget {
}
class _ExampleWidgetState extends State<ExampleWidget> {
String _message = '';
bool _pressed = false;
@override
Widget build(BuildContext context) {
@ -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);
}
}

View file

@ -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.';

View file

@ -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);
});
}

View file

@ -24,4 +24,4 @@ void main() {
final String fullMessage = await driver.getText(find.text(message));
expect(fullMessage, message);
});
}
}

View file

@ -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;
@ -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',
@ -158,7 +151,7 @@ class FlutterKernelBuilder implements Builder {
}
final Uri mainUri = _PackageUriMapper.findUri(
absoluteMainPath,
packagesFile.path,
packagesFilePath,
_kMultirootScheme,
<String>[normalRoot, generatedRoot],
);
@ -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');
}

View file

@ -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.
///
@ -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,
@ -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
);
@ -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.
@ -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');
@ -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,
@ -210,7 +210,7 @@ class BuildRunner extends CodeGenerator {
}
@override
Future<CodegenDaemon> daemon({
Future<CodegenDaemon> daemon(FlutterProject flutterProject, {
String mainPath,
bool linkPlatformKernelIn = false,
bool targetProductVm = false,
@ -218,8 +218,8 @@ class BuildRunner extends CodeGenerator {
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
);
@ -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;

View file

@ -9,6 +9,7 @@ import 'base/context.dart';
import 'base/file_system.dart';
import 'base/platform.dart';
import 'compile.dart';
import 'dart/package_map.dart';
import 'globals.dart';
import 'project.dart';
@ -44,8 +45,9 @@ abstract class CodeGenerator {
const CodeGenerator();
/// Run a partial build include code generators but not kernel.
Future<void> generate({@required String mainPath}) async {
Future<void> generate(FlutterProject flutterProject, {@required String mainPath}) async {
await build(
flutterProject,
mainPath: mainPath,
aot: false,
linkPlatformKernelIn: false,
@ -59,7 +61,7 @@ abstract class CodeGenerator {
///
/// The defines of the build command are the arguments required in the
/// flutter_build kernel builder.
Future<CodeGenerationResult> build({
Future<CodeGenerationResult> build(FlutterProject flutterProject, {
@required String mainPath,
@required bool aot,
@required bool linkPlatformKernelIn,
@ -73,7 +75,7 @@ abstract class CodeGenerator {
///
/// The defines of the daemon command are the arguments required in the
/// flutter_build kernel builder.
Future<CodegenDaemon> daemon({
Future<CodegenDaemon> daemon(FlutterProject flutterProject, {
@required String mainPath,
bool linkPlatformKernelIn = false,
bool targetProductVm = false,
@ -83,14 +85,14 @@ abstract class CodeGenerator {
// Generates a synthetic package under .dart_tool/flutter_tool which is in turn
// used to generate a build script.
Future<void> generateBuildScript();
Future<void> generateBuildScript(FlutterProject flutterProject);
}
class UnsupportedCodeGenerator extends CodeGenerator {
const UnsupportedCodeGenerator();
@override
Future<CodeGenerationResult> build({
Future<CodeGenerationResult> build(FlutterProject flutterProject, {
String mainPath,
bool aot,
bool linkPlatformKernelIn,
@ -103,12 +105,12 @@ class UnsupportedCodeGenerator extends CodeGenerator {
}
@override
Future<void> generateBuildScript() {
Future<void> generateBuildScript(FlutterProject flutterProject) {
throw UnsupportedError('build_runner is not currently supported.');
}
@override
Future<CodegenDaemon> daemon({
Future<CodegenDaemon> daemon(FlutterProject flutterProject, {
String mainPath,
bool linkPlatformKernelIn = false,
bool targetProductVm = false,
@ -128,8 +130,6 @@ abstract class CodegenDaemon {
/// Starts a new build.
void startBuild();
File get packagesFile;
File get dillFile;
}
@ -137,9 +137,8 @@ abstract class CodegenDaemon {
///
/// If no dill or packages file is generated, they will be null.
class CodeGenerationResult {
const CodeGenerationResult(this.packagesFile, this.dillFile);
const CodeGenerationResult(this.dillFile);
final File packagesFile;
final File dillFile;
}
@ -176,8 +175,10 @@ class CodeGeneratingKernelCompiler implements KernelCompiler {
'sdkRoot, packagesPath are not supported when using the experimental '
'build* pipeline');
}
final FlutterProject flutterProject = await FlutterProject.current();
try {
final CodeGenerationResult buildResult = await codeGenerator.build(
flutterProject,
aot: aot,
linkPlatformKernelIn: linkPlatformKernelIn,
trackWidgetCreation: trackWidgetCreation,
@ -206,13 +207,16 @@ class CodeGeneratingResidentCompiler implements ResidentCompiler {
/// Creates a new [ResidentCompiler] and configures a [BuildDaemonClient] to
/// run builds.
static Future<CodeGeneratingResidentCompiler> create({
@required String mainPath,
@required FlutterProject flutterProject,
String mainPath,
bool trackWidgetCreation = false,
CompilerMessageConsumer compilerMessageConsumer = printError,
bool unsafePackageSerialization = false,
String outputPath,
String initializeFromDill,
}) async {
final FlutterProject flutterProject = await FlutterProject.current();
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(
flutterProject,
extraFrontEndOptions: <String>[],
linkPlatformKernelIn: false,
mainPath: mainPath,
@ -221,22 +225,23 @@ class CodeGeneratingResidentCompiler implements ResidentCompiler {
);
codegenDaemon.startBuild();
final CodegenStatus status = await codegenDaemon.buildResults.firstWhere((CodegenStatus status) {
return status ==CodegenStatus.Succeeded || status == CodegenStatus.Failed;
return status == CodegenStatus.Succeeded || status == CodegenStatus.Failed;
});
if (status == CodegenStatus.Failed) {
printError('Codegeneration failed, halting build.');
printError('Code generation failed, build may have compile errors');
}
final ResidentCompiler residentCompiler = ResidentCompiler(
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
trackWidgetCreation: trackWidgetCreation,
packagesPath: codegenDaemon.packagesFile.path,
packagesPath: PackageMap.globalGeneratedPackagesPath,
fileSystemRoots: <String>[
fs.path.join(flutterProject.generated.absolute.path, 'lib${platform.pathSeparator}'),
fs.path.join(flutterProject.generated.path, 'lib${platform.pathSeparator}'),
fs.path.join(flutterProject.directory.path, 'lib${platform.pathSeparator}'),
],
fileSystemScheme: _kMultiRootScheme,
targetModel: TargetModel.flutter,
unsafePackageSerialization: unsafePackageSerialization,
initializeFromDill: initializeFromDill,
);
return CodeGeneratingResidentCompiler._(residentCompiler, codegenDaemon);
}
@ -274,7 +279,7 @@ class CodeGeneratingResidentCompiler implements ResidentCompiler {
mainPath,
invalidatedFiles,
outputPath: outputPath,
packagesFilePath: _codegenDaemon.packagesFile.path,
packagesFilePath: PackageMap.globalGeneratedPackagesPath,
);
}

View file

@ -205,13 +205,14 @@ class AttachCommand extends FlutterCommand {
}
try {
final bool useHot = getBuildInfo().isDebug;
final FlutterDevice flutterDevice = FlutterDevice(
final FlutterDevice flutterDevice = await FlutterDevice.create(
device,
trackWidgetCreation: false,
dillOutputPath: argResults['output-dill'],
fileSystemRoots: argResults['filesystem-root'],
fileSystemScheme: argResults['filesystem-scheme'],
viewFilter: argResults['isolate-filter'],
target: argResults['target'],
targetModel: TargetModel(argResults['target-model']),
);
flutterDevice.observatoryUris = <Uri>[ observatoryUri ];

View file

@ -346,11 +346,12 @@ class AppDomain extends Domain {
final Directory cwd = fs.currentDirectory;
fs.currentDirectory = fs.directory(projectDirectory);
final FlutterDevice flutterDevice = FlutterDevice(
final FlutterDevice flutterDevice = await FlutterDevice.create(
device,
trackWidgetCreation: trackWidgetCreation,
dillOutputPath: dillOutputPath,
viewFilter: isolateFilter,
target: target,
);
ResidentRunner runner;

View file

@ -4,6 +4,7 @@
import '../base/common.dart';
import '../codegen.dart';
import '../project.dart';
import '../runner/flutter_command.dart';
class GenerateCommand extends FlutterCommand {
@ -24,7 +25,8 @@ class GenerateCommand extends FlutterCommand {
if (!experimentalBuildEnabled) {
throwToolExit('FLUTTER_EXPERIMENTAL_BUILD is not enabled, codegen is unsupported.');
}
await codeGenerator.generate(mainPath: argResults['target']);
final FlutterProject flutterProject = await FlutterProject.current();
await codeGenerator.generate(flutterProject, mainPath: argResults['target']);
return null;
}
}

View file

@ -10,8 +10,6 @@ import '../base/time.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../codegen.dart';
import '../compile.dart';
import '../device.dart';
import '../globals.dart';
import '../ios/mac.dart';
@ -346,13 +344,9 @@ class RunCommand extends RunCommandBase {
argResults[FlutterOptions.kEnableExperiment].isNotEmpty) {
expFlags = argResults[FlutterOptions.kEnableExperiment];
}
ResidentCompiler residentCompiler;
if (experimentalBuildEnabled) {
residentCompiler = await CodeGeneratingResidentCompiler.create(mainPath: argResults['target']);
}
final List<FlutterDevice> flutterDevices = devices.map<FlutterDevice>((Device device) {
return FlutterDevice(
final List<FlutterDevice> flutterDevices = <FlutterDevice>[];
for (Device device in devices) {
final FlutterDevice flutterDevice = await FlutterDevice.create(
device,
trackWidgetCreation: argResults['track-widget-creation'],
dillOutputPath: argResults['output-dill'],
@ -360,9 +354,10 @@ class RunCommand extends RunCommandBase {
fileSystemScheme: argResults['filesystem-scheme'],
viewFilter: argResults['isolate-filter'],
experimentalFlags: expFlags,
generator: residentCompiler,
target: argResults['target'],
);
}).toList();
flutterDevices.add(flutterDevice);
}
ResidentRunner runner;
final String applicationBinaryPath = argResults['use-application-binary'];

View file

@ -9,6 +9,7 @@ import '../base/common.dart';
import '../base/file_system.dart';
import '../base/platform.dart';
import '../cache.dart';
import '../project.dart';
import '../runner/flutter_command.dart';
import '../test/coverage_collector.dart';
import '../test/event_printer.dart';
@ -104,6 +105,7 @@ class TestCommand extends FlutterCommand {
Future<FlutterCommandResult> runCommand() async {
final List<String> names = argResults['name'];
final List<String> plainNames = argResults['plain-name'];
final FlutterProject flutterProject = await FlutterProject.current();
Iterable<String> files = argResults.rest.map<String>((String testPath) => fs.path.absolute(testPath)).toList();
@ -170,6 +172,7 @@ class TestCommand extends FlutterCommand {
trackWidgetCreation: argResults['track-widget-creation'],
updateGoldens: argResults['update-goldens'],
concurrency: jobs,
flutterProject: flutterProject,
);
if (collector != null) {

View file

@ -661,7 +661,11 @@ class ResidentCompiler {
return null;
}
Future<dynamic> shutdown() {
Future<dynamic> shutdown() async {
// Server was never sucessfully created.
if (_server == null) {
return 0;
}
_server.kill();
return _server.exitCode;
}

View file

@ -20,6 +20,8 @@ class PackageMap {
static String get globalPackagesPath => _globalPackagesPath ?? kPackagesFileName;
static String get globalGeneratedPackagesPath => fs.path.setExtension(globalPackagesPath, '.generated');
static set globalPackagesPath(String value) {
_globalPackagesPath = value;
}

View file

@ -113,6 +113,7 @@ class FlutterProject {
/// The directory containing the generated code for this project.
Directory get generated => directory
.absolute
.childDirectory('.dart_tool')
.childDirectory('build')
.childDirectory('generated')
@ -165,6 +166,12 @@ class FlutterProject {
final YamlMap pubspec = loadYaml(await pubspecFile.readAsString());
return pubspec['builders'];
}
/// Whether there are any builders used by this package.
Future<bool> get hasBuilders async {
final YamlMap result = await builders;
return result != null && result.isNotEmpty;
}
}
/// Represents the iOS sub-project of a Flutter project.

View file

@ -49,6 +49,45 @@ class FlutterDevice {
experimentalFlags: experimentalFlags,
);
/// Create a [FlutterDevice] with optional code generation enabled.
static Future<FlutterDevice> create(Device device, {
@required bool trackWidgetCreation,
String dillOutputPath,
List<String> fileSystemRoots,
String fileSystemScheme,
String viewFilter,
@required String target,
TargetModel targetModel = TargetModel.flutter,
List<String> experimentalFlags,
ResidentCompiler generator,
}) async {
ResidentCompiler generator;
final FlutterProject flutterProject = await FlutterProject.current();
if (experimentalBuildEnabled && await flutterProject.hasBuilders) {
generator = await CodeGeneratingResidentCompiler.create(flutterProject: flutterProject, mainPath: target);
} else {
generator = ResidentCompiler(
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
trackWidgetCreation: trackWidgetCreation,
fileSystemRoots: fileSystemRoots,
fileSystemScheme: fileSystemScheme,
targetModel: targetModel,
experimentalFlags: experimentalFlags,
);
}
return FlutterDevice(
device,
trackWidgetCreation: trackWidgetCreation,
dillOutputPath: dillOutputPath,
fileSystemRoots: fileSystemRoots,
fileSystemScheme:fileSystemScheme,
viewFilter: viewFilter,
experimentalFlags: experimentalFlags,
targetModel: targetModel,
generator: generator,
);
}
final Device device;
final ResidentCompiler generator;
List<Uri> observatoryUris;

View file

@ -24,10 +24,12 @@ import '../base/process_manager.dart';
import '../base/terminal.dart';
import '../build_info.dart';
import '../bundle.dart';
import '../codegen.dart';
import '../compile.dart';
import '../convert.dart';
import '../dart/package_map.dart';
import '../globals.dart';
import '../project.dart';
import '../vmservice.dart';
import 'watcher.dart';
@ -89,6 +91,7 @@ void installHook({
int observatoryPort,
InternetAddressType serverType = InternetAddressType.IPv4,
Uri projectRootDirectory,
FlutterProject flutterProject,
}) {
assert(enableObservatory || (!startPaused && observatoryPort == null));
hack.registerPlatformPlugin(
@ -107,6 +110,7 @@ void installHook({
trackWidgetCreation: trackWidgetCreation,
updateGoldens: updateGoldens,
projectRootDirectory: projectRootDirectory,
flutterProject: flutterProject,
),
);
}
@ -232,7 +236,7 @@ class _CompilationRequest {
// This class is a wrapper around compiler that allows multiple isolates to
// enqueue compilation requests, but ensures only one compilation at a time.
class _Compiler {
_Compiler(bool trackWidgetCreation, Uri projectRootDirectory) {
_Compiler(bool trackWidgetCreation, Uri projectRootDirectory, FlutterProject flutterProject) {
// Compiler maintains and updates single incremental dill file.
// Incremental compilation requests done for each test copy that file away
// for independent execution.
@ -265,7 +269,16 @@ class _Compiler {
trackWidgetCreation: trackWidgetCreation,
);
ResidentCompiler createCompiler() {
Future<ResidentCompiler> createCompiler() async {
if (experimentalBuildEnabled && await flutterProject.hasBuilders) {
return CodeGeneratingResidentCompiler.create(
flutterProject: flutterProject,
trackWidgetCreation: trackWidgetCreation,
initializeFromDill: null, // TODO(jonahwilliams): investigate multi-root support in init from dill.
unsafePackageSerialization: false,
compilerMessageConsumer: reportCompilerMessage,
);
}
return ResidentCompiler(
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
packagesPath: PackageMap.globalPackagesPath,
@ -290,7 +303,7 @@ class _Compiler {
final Stopwatch compilerTime = Stopwatch()..start();
bool firstCompile = false;
if (compiler == null) {
compiler = createCompiler();
compiler = await createCompiler();
firstCompile = true;
}
suppressOutput = false;
@ -374,6 +387,7 @@ class _FlutterPlatform extends PlatformPlugin {
this.trackWidgetCreation,
this.updateGoldens,
this.projectRootDirectory,
this.flutterProject,
}) : assert(shellPath != null);
final String shellPath;
@ -389,6 +403,7 @@ class _FlutterPlatform extends PlatformPlugin {
final bool trackWidgetCreation;
final bool updateGoldens;
final Uri projectRootDirectory;
final FlutterProject flutterProject;
Directory fontsDirectory;
_Compiler compiler;
@ -545,7 +560,7 @@ class _FlutterPlatform extends PlatformPlugin {
if (precompiledDillPath == null && precompiledDillFiles == null) {
// Lazily instantiate compiler so it is built only if it is actually used.
compiler ??= _Compiler(trackWidgetCreation, projectRootDirectory);
compiler ??= _Compiler(trackWidgetCreation, projectRootDirectory, flutterProject);
mainDart = await compiler.compile(mainDart);
if (mainDart == null) {

View file

@ -15,6 +15,7 @@ import '../base/process_manager.dart';
import '../base/terminal.dart';
import '../dart/package_map.dart';
import '../globals.dart';
import '../project.dart';
import 'flutter_platform.dart' as loader;
import 'watcher.dart';
@ -34,6 +35,7 @@ Future<int> runTests(
bool updateGoldens = false,
TestWatcher watcher,
@required int concurrency,
FlutterProject flutterProject,
}) async {
// Compute the command-line arguments for package:test.
final List<String> testArgs = <String>[];
@ -80,6 +82,7 @@ Future<int> runTests(
trackWidgetCreation: trackWidgetCreation,
updateGoldens: updateGoldens,
projectRootDirectory: fs.currentDirectory.uri,
flutterProject: flutterProject,
);
// Make the global packages path absolute.

View file

@ -30,6 +30,7 @@ void main() {
testUsingContext('delegates to build_runner', () async {
const CodeGeneratingKernelCompiler kernelCompiler = CodeGeneratingKernelCompiler();
when(mockBuildRunner.build(
any,
aot: anyNamed('aot'),
extraFrontEndOptions: anyNamed('extraFrontEndOptions'),
linkPlatformKernelIn: anyNamed('linkPlatformKernelIn'),
@ -37,7 +38,7 @@ void main() {
targetProductVm: anyNamed('targetProductVm'),
trackWidgetCreation: anyNamed('trackWidgetCreation'),
)).thenAnswer((Invocation invocation) async {
return CodeGenerationResult(fs.file('.packages'), fs.file('main.app.dill'));
return CodeGenerationResult(fs.file('main.app.dill'));
});
final CompilerOutput buildResult = await kernelCompiler.compile(
outputFilePath: 'output.app.dill',