Unverified Commit 469a859c authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Enable code generation features in tool (#29399)

parent e8e60a8d
...@@ -82,7 +82,6 @@ tasks: ...@@ -82,7 +82,6 @@ tasks:
correctly. correctly.
stage: devicelab_win stage: devicelab_win
required_agent_capabilities: ["windows/android"] required_agent_capabilities: ["windows/android"]
flaky: true
codegen_integration_mac: codegen_integration_mac:
description: > description: >
...@@ -90,7 +89,6 @@ tasks: ...@@ -90,7 +89,6 @@ tasks:
correctly. correctly.
stage: devicelab_ios stage: devicelab_ios
required_agent_capabilities: ["mac/ios"] required_agent_capabilities: ["mac/ios"]
flaky: true
codegen_integration_linux: codegen_integration_linux:
description: > description: >
...@@ -98,7 +96,6 @@ tasks: ...@@ -98,7 +96,6 @@ tasks:
correctly. correctly.
stage: devicelab stage: devicelab
required_agent_capabilities: ["linux/android"] required_agent_capabilities: ["linux/android"]
flaky: true
flutter_gallery_android__compile: flutter_gallery_android__compile:
description: > description: >
......
...@@ -95,6 +95,6 @@ Future<void> main(List<String> args) async { ...@@ -95,6 +95,6 @@ Future<void> main(List<String> args) async {
overrides: <Type, Generator>{ overrides: <Type, Generator>{
// The build runner instance is not supported in google3 because // The build runner instance is not supported in google3 because
// the build runner packages are not synced internally. // the build runner packages are not synced internally.
CodeGenerator: () => experimentalBuildEnabled ? const BuildRunner() : const UnsupportedCodeGenerator(), CodeGenerator: () => const BuildRunner(),
}); });
} }
...@@ -188,7 +188,7 @@ class AOTSnapshotter { ...@@ -188,7 +188,7 @@ class AOTSnapshotter {
'sharedLib': buildSharedLibrary.toString(), 'sharedLib': buildSharedLibrary.toString(),
'extraGenSnapshotOptions': extraGenSnapshotOptions.join(' '), 'extraGenSnapshotOptions': extraGenSnapshotOptions.join(' '),
'engineHash': engine.version, 'engineHash': engine.version,
'buildersUsed': '${flutterProject != null ? await flutterProject.hasBuilders : false}', 'buildersUsed': '${flutterProject != null ? flutterProject.hasBuilders : false}',
}, },
depfilePaths: <String>[], depfilePaths: <String>[],
); );
...@@ -299,6 +299,7 @@ class AOTSnapshotter { ...@@ -299,6 +299,7 @@ class AOTSnapshotter {
@required bool trackWidgetCreation, @required bool trackWidgetCreation,
List<String> extraFrontEndOptions = const <String>[], List<String> extraFrontEndOptions = const <String>[],
}) async { }) async {
final FlutterProject flutterProject = await FlutterProject.current();
final Directory outputDir = fs.directory(outputPath); final Directory outputDir = fs.directory(outputPath);
outputDir.createSync(recursive: true); outputDir.createSync(recursive: true);
...@@ -308,6 +309,7 @@ class AOTSnapshotter { ...@@ -308,6 +309,7 @@ class AOTSnapshotter {
printTrace('Extra front-end options: $extraFrontEndOptions'); printTrace('Extra front-end options: $extraFrontEndOptions');
final String depfilePath = fs.path.join(outputPath, 'kernel_compile.d'); final String depfilePath = fs.path.join(outputPath, 'kernel_compile.d');
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
final CompilerOutput compilerOutput = await kernelCompiler.compile( final CompilerOutput compilerOutput = await kernelCompiler.compile(
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath), sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
mainPath: mainPath, mainPath: mainPath,
......
...@@ -48,7 +48,7 @@ class BuildRunner extends CodeGenerator { ...@@ -48,7 +48,7 @@ class BuildRunner extends CodeGenerator {
// Check if contents of builders changed. If so, invalidate build script // Check if contents of builders changed. If so, invalidate build script
// and regnerate. // and regnerate.
final YamlMap builders = await flutterProject.builders; final YamlMap builders = flutterProject.builders;
final List<int> appliedBuilderDigest = _produceScriptId(builders); final List<int> appliedBuilderDigest = _produceScriptId(builders);
if (scriptIdFile.existsSync() && buildSnapshot.existsSync()) { if (scriptIdFile.existsSync() && buildSnapshot.existsSync()) {
final List<int> previousAppliedBuilderDigest = scriptIdFile.readAsBytesSync(); final List<int> previousAppliedBuilderDigest = scriptIdFile.readAsBytesSync();
...@@ -79,7 +79,7 @@ class BuildRunner extends CodeGenerator { ...@@ -79,7 +79,7 @@ class BuildRunner extends CodeGenerator {
stringBuffer.writeln('name: flutter_tool'); stringBuffer.writeln('name: flutter_tool');
stringBuffer.writeln('dependencies:'); stringBuffer.writeln('dependencies:');
final YamlMap builders = await flutterProject.builders; final YamlMap builders = flutterProject.builders;
if (builders != null) { if (builders != null) {
for (String name in builders.keys) { for (String name in builders.keys) {
final Object node = builders[name]; final Object node = builders[name];
...@@ -147,6 +147,7 @@ class BuildRunner extends CodeGenerator { ...@@ -147,6 +147,7 @@ class BuildRunner extends CodeGenerator {
buildSnapshot.path, buildSnapshot.path,
'daemon', 'daemon',
'--skip-build-script-check', '--skip-build-script-check',
'--delete-conflicting-outputs'
]; ];
buildDaemonClient = await BuildDaemonClient.connect(flutterProject.directory.path, command, logHandler: (ServerLog log) => printTrace(log.toString())); buildDaemonClient = await BuildDaemonClient.connect(flutterProject.directory.path, command, logHandler: (ServerLog log) => printTrace(log.toString()));
} finally { } finally {
......
...@@ -138,7 +138,11 @@ class BuildScriptGenerator { ...@@ -138,7 +138,11 @@ class BuildScriptGenerator {
if (definition.isOptional) { if (definition.isOptional) {
namedArgs['isOptional'] = literalTrue; namedArgs['isOptional'] = literalTrue;
} }
namedArgs['hideOutput'] = literalTrue; if (definition.buildTo == BuildTo.cache) {
namedArgs['hideOutput'] = literalTrue;
} else {
namedArgs['hideOutput'] = literalFalse;
}
if (!identical(definition.defaults?.generateFor, InputSet.anything)) { if (!identical(definition.defaults?.generateFor, InputSet.anything)) {
final Map<String, Expression> inputSetArgs = <String, Expression>{}; final Map<String, Expression> inputSetArgs = <String, Expression>{};
if (definition.defaults.generateFor.include != null) { if (definition.defaults.generateFor.include != null) {
......
...@@ -16,6 +16,7 @@ import 'compile.dart'; ...@@ -16,6 +16,7 @@ import 'compile.dart';
import 'dart/package_map.dart'; import 'dart/package_map.dart';
import 'devfs.dart'; import 'devfs.dart';
import 'globals.dart'; import 'globals.dart';
import 'project.dart';
const String defaultMainPath = 'lib/main.dart'; const String defaultMainPath = 'lib/main.dart';
const String defaultAssetBasePath = '.'; const String defaultAssetBasePath = '.';
...@@ -72,6 +73,7 @@ Future<void> build({ ...@@ -72,6 +73,7 @@ Future<void> build({
assetDirPath ??= getAssetBuildDirectory(); assetDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath); packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation); applicationKernelFilePath ??= getDefaultApplicationKernelPath(trackWidgetCreation: trackWidgetCreation);
final FlutterProject flutterProject = await FlutterProject.current();
if (compilationTraceFilePath != null) { if (compilationTraceFilePath != null) {
if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) { if (buildMode != BuildMode.dynamicProfile && buildMode != BuildMode.dynamicRelease) {
...@@ -99,6 +101,7 @@ Future<void> build({ ...@@ -99,6 +101,7 @@ Future<void> build({
if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty) if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
printTrace('Extra front-end options: $extraFrontEndOptions'); printTrace('Extra front-end options: $extraFrontEndOptions');
ensureDirectoryExists(applicationKernelFilePath); ensureDirectoryExists(applicationKernelFilePath);
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(flutterProject);
final CompilerOutput compilerOutput = await kernelCompiler.compile( final CompilerOutput compilerOutput = await kernelCompiler.compile(
sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath), sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null : incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null :
......
...@@ -25,21 +25,6 @@ const String kMultiRootScheme = 'org-dartlang-app'; ...@@ -25,21 +25,6 @@ const String kMultiRootScheme = 'org-dartlang-app';
/// implementation. /// implementation.
CodeGenerator get codeGenerator => context[CodeGenerator]; CodeGenerator get codeGenerator => context[CodeGenerator];
/// Whether to attempt to build a flutter project using build* libraries.
///
/// This requires both an experimental opt in via the environment variable
/// 'FLUTTER_EXPERIMENTAL_BUILD' and that the project itself has a
/// dependency on the package 'flutter_build' and 'build_runner.'
bool get experimentalBuildEnabled {
return _experimentalBuildEnabled ??= platform.environment['FLUTTER_EXPERIMENTAL_BUILD']?.toLowerCase() == 'true';
}
bool _experimentalBuildEnabled;
@visibleForTesting
set experimentalBuildEnabled(bool value) {
_experimentalBuildEnabled = value;
}
/// A wrapper for a build_runner process which delegates to a generated /// A wrapper for a build_runner process which delegates to a generated
/// build script. /// build script.
/// ///
......
...@@ -24,9 +24,6 @@ class GenerateCommand extends FlutterCommand { ...@@ -24,9 +24,6 @@ class GenerateCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
if (!experimentalBuildEnabled) {
throwToolExit('FLUTTER_EXPERIMENTAL_BUILD is not enabled, codegen is unsupported.');
}
final FlutterProject flutterProject = await FlutterProject.current(); final FlutterProject flutterProject = await FlutterProject.current();
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject); final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject);
codegenDaemon.startBuild(); codegenDaemon.startBuild();
......
...@@ -160,7 +160,7 @@ class TestCommand extends FastFlutterCommand { ...@@ -160,7 +160,7 @@ class TestCommand extends FastFlutterCommand {
Cache.releaseLockEarly(); Cache.releaseLockEarly();
// Run builders once before all tests. // Run builders once before all tests.
if (experimentalBuildEnabled && await flutterProject.hasBuilders) { if (flutterProject.hasBuilders) {
final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject); final CodegenDaemon codegenDaemon = await codeGenerator.daemon(flutterProject);
codegenDaemon.startBuild(); codegenDaemon.startBuild();
await for (CodegenStatus status in codegenDaemon.buildResults) { await for (CodegenStatus status in codegenDaemon.buildResults) {
......
...@@ -17,12 +17,24 @@ import 'base/platform.dart'; ...@@ -17,12 +17,24 @@ import 'base/platform.dart';
import 'base/process_manager.dart'; import 'base/process_manager.dart';
import 'base/terminal.dart'; import 'base/terminal.dart';
import 'cache.dart'; import 'cache.dart';
import 'codegen.dart';
import 'convert.dart'; import 'convert.dart';
import 'dart/package_map.dart'; import 'dart/package_map.dart';
import 'globals.dart'; import 'globals.dart';
import 'project.dart'; import 'project.dart';
KernelCompiler get kernelCompiler => context[KernelCompiler]; KernelCompilerFactory get kernelCompilerFactory => context[KernelCompilerFactory];
class KernelCompilerFactory {
const KernelCompilerFactory();
Future<KernelCompiler> create(FlutterProject flutterProject) async {
if (flutterProject == null || !flutterProject.hasBuilders) {
return const KernelCompiler();
}
return const CodeGeneratingKernelCompiler();
}
}
typedef CompilerMessageConsumer = void Function(String message, { bool emphasis, TerminalColor color }); typedef CompilerMessageConsumer = void Function(String message, { bool emphasis, TerminalColor color });
...@@ -235,7 +247,7 @@ class KernelCompiler { ...@@ -235,7 +247,7 @@ class KernelCompiler {
'trackWidgetCreation': trackWidgetCreation.toString(), 'trackWidgetCreation': trackWidgetCreation.toString(),
'linkPlatformKernelIn': linkPlatformKernelIn.toString(), 'linkPlatformKernelIn': linkPlatformKernelIn.toString(),
'engineHash': engine.version, 'engineHash': engine.version,
'buildersUsed': '${flutterProject != null ? await flutterProject.hasBuilders : false}', 'buildersUsed': '${flutterProject != null ? flutterProject.hasBuilders : false}',
}, },
depfilePaths: <String>[depFilePath], depfilePaths: <String>[depFilePath],
pathFilter: (String path) => !path.startsWith('/b/build/slave/'), pathFilter: (String path) => !path.startsWith('/b/build/slave/'),
......
...@@ -22,7 +22,6 @@ import 'base/time.dart'; ...@@ -22,7 +22,6 @@ import 'base/time.dart';
import 'base/user_messages.dart'; import 'base/user_messages.dart';
import 'base/utils.dart'; import 'base/utils.dart';
import 'cache.dart'; import 'cache.dart';
import 'codegen.dart';
import 'compile.dart'; import 'compile.dart';
import 'devfs.dart'; import 'devfs.dart';
import 'device.dart'; import 'device.dart';
...@@ -83,7 +82,7 @@ Future<T> runInContext<T>( ...@@ -83,7 +82,7 @@ Future<T> runInContext<T>(
IOSSimulatorUtils: () => IOSSimulatorUtils(), IOSSimulatorUtils: () => IOSSimulatorUtils(),
IOSWorkflow: () => const IOSWorkflow(), IOSWorkflow: () => const IOSWorkflow(),
IOSValidator: () => const IOSValidator(), IOSValidator: () => const IOSValidator(),
KernelCompiler: () => experimentalBuildEnabled ? const CodeGeneratingKernelCompiler() : const KernelCompiler(), KernelCompilerFactory: () => const KernelCompilerFactory(),
LinuxWorkflow: () => const LinuxWorkflow(), LinuxWorkflow: () => const LinuxWorkflow(),
Logger: () => platform.isWindows ? WindowsStdoutLogger() : StdoutLogger(), Logger: () => platform.isWindows ? WindowsStdoutLogger() : StdoutLogger(),
MacOSWorkflow: () => const MacOSWorkflow(), MacOSWorkflow: () => const MacOSWorkflow(),
......
...@@ -162,14 +162,17 @@ class FlutterProject { ...@@ -162,14 +162,17 @@ class FlutterProject {
} }
/// Return the set of builders used by this package. /// Return the set of builders used by this package.
Future<YamlMap> get builders async { YamlMap get builders {
final YamlMap pubspec = loadYaml(await pubspecFile.readAsString()); if (!pubspecFile.existsSync()) {
return null;
}
final YamlMap pubspec = loadYaml(pubspecFile.readAsStringSync());
return pubspec['builders']; return pubspec['builders'];
} }
/// Whether there are any builders used by this package. /// Whether there are any builders used by this package.
Future<bool> get hasBuilders async { bool get hasBuilders {
final YamlMap result = await builders; final YamlMap result = builders;
return result != null && result.isNotEmpty; return result != null && result.isNotEmpty;
} }
} }
......
...@@ -61,7 +61,7 @@ class FlutterDevice { ...@@ -61,7 +61,7 @@ class FlutterDevice {
}) async { }) async {
ResidentCompiler generator; ResidentCompiler generator;
final FlutterProject flutterProject = await FlutterProject.current(); final FlutterProject flutterProject = await FlutterProject.current();
if (experimentalBuildEnabled && await flutterProject.hasBuilders) { if (flutterProject.hasBuilders) {
generator = await CodeGeneratingResidentCompiler.create( generator = await CodeGeneratingResidentCompiler.create(
flutterProject: flutterProject, flutterProject: flutterProject,
); );
......
...@@ -270,7 +270,7 @@ class _Compiler { ...@@ -270,7 +270,7 @@ class _Compiler {
); );
Future<ResidentCompiler> createCompiler() async { Future<ResidentCompiler> createCompiler() async {
if (experimentalBuildEnabled && await flutterProject.hasBuilders) { if (flutterProject.hasBuilders) {
return CodeGeneratingResidentCompiler.create( return CodeGeneratingResidentCompiler.create(
flutterProject: flutterProject, flutterProject: flutterProject,
trackWidgetCreation: trackWidgetCreation, trackWidgetCreation: trackWidgetCreation,
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/codegen.dart';
import 'package:mockito/mockito.dart';
import '../src/common.dart';
import '../src/context.dart';
void main() {
group('experimentalBuildEnabled', () {
final MockPlatform mockPlatform = MockPlatform();
setUp(() {
experimentalBuildEnabled = null;
});
testUsingContext('is enabled if environment variable is enabled', () async {
when(mockPlatform.environment).thenReturn(<String, String>{'FLUTTER_EXPERIMENTAL_BUILD': 'true'});
expect(experimentalBuildEnabled, true);
}, overrides: <Type, Generator>{
Platform: () => mockPlatform,
});
testUsingContext('is not enabed if environment varable is not enabled', () async {
when(mockPlatform.environment).thenReturn(<String, String>{});
expect(experimentalBuildEnabled, false);
}, overrides: <Type, Generator>{
Platform: () => mockPlatform,
});
});
}
class MockPlatform extends Mock implements Platform {}
...@@ -121,6 +121,7 @@ example:org-dartlang-app:/ ...@@ -121,6 +121,7 @@ example:org-dartlang-app:/
'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0' 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'
)) ))
)); ));
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -144,6 +145,7 @@ example:org-dartlang-app:/ ...@@ -144,6 +145,7 @@ example:org-dartlang-app:/
'result abc\nline1\nline2\nabc\nabc' 'result abc\nline1\nline2\nabc\nabc'
)) ))
)); ));
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -169,6 +171,7 @@ example:org-dartlang-app:/ ...@@ -169,6 +171,7 @@ example:org-dartlang-app:/
'result abc\nline1\nline2\nabc\nabc' 'result abc\nline1\nline2\nabc\nabc'
)) ))
)); ));
final KernelCompiler kernelCompiler = await kernelCompilerFactory.create(null);
final CompilerOutput output = await kernelCompiler.compile( final CompilerOutput output = await kernelCompiler.compile(
sdkRoot: '/path/to/sdkroot', sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
......
...@@ -12,6 +12,7 @@ import 'package:flutter_tools/src/build_info.dart'; ...@@ -12,6 +12,7 @@ import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/compile.dart'; import 'package:flutter_tools/src/compile.dart';
import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/tester/flutter_tester.dart'; import 'package:flutter_tools/src/tester/flutter_tester.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:process/process.dart'; import 'package:process/process.dart';
...@@ -109,7 +110,7 @@ void main() { ...@@ -109,7 +110,7 @@ void main() {
FileSystem: () => fs, FileSystem: () => fs,
Cache: () => Cache(rootOverride: fs.directory(flutterRoot)), Cache: () => Cache(rootOverride: fs.directory(flutterRoot)),
ProcessManager: () => mockProcessManager, ProcessManager: () => mockProcessManager,
KernelCompiler: () => mockKernelCompiler, KernelCompilerFactory: () => FakeKernelCompilerFactory(mockKernelCompiler),
Artifacts: () => mockArtifacts, Artifacts: () => mockArtifacts,
}; };
...@@ -185,7 +186,6 @@ Hello! ...@@ -185,7 +186,6 @@ Hello!
debuggingOptions: DebuggingOptions.enabled(const BuildInfo(BuildMode.debug, null))); debuggingOptions: DebuggingOptions.enabled(const BuildInfo(BuildMode.debug, null)));
expect(result.started, isTrue); expect(result.started, isTrue);
expect(result.observatoryUri, observatoryUri); expect(result.observatoryUri, observatoryUri);
expect(logLines.last, 'Hello!'); expect(logLines.last, 'Hello!');
}, overrides: startOverrides); }, overrides: startOverrides);
}); });
...@@ -194,3 +194,13 @@ Hello! ...@@ -194,3 +194,13 @@ Hello!
class MockArtifacts extends Mock implements Artifacts {} class MockArtifacts extends Mock implements Artifacts {}
class MockKernelCompiler extends Mock implements KernelCompiler {} class MockKernelCompiler extends Mock implements KernelCompiler {}
class FakeKernelCompilerFactory implements KernelCompilerFactory {
FakeKernelCompilerFactory(this.kernelCompiler);
final KernelCompiler kernelCompiler;
@override
Future<KernelCompiler> create(FlutterProject flutterProject) async {
return kernelCompiler;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment