Skip to content

Instantly share code, notes, and snippets.

@soloxiao
Created May 27, 2022 09:33
Show Gist options
  • Save soloxiao/9efc4aac89d8db84692af3e798d9b584 to your computer and use it in GitHub Desktop.
Save soloxiao/9efc4aac89d8db84692af3e798d9b584 to your computer and use it in GitHub Desktop.
flutter 3.0.0 tools patch
From f92f50450ad1ff501f8773ffcc2c9a2acca9476d Mon Sep 17 00:00:00 2001
From: xiaopeng015 <xiaopeng015@ke.com>
Date: Fri, 27 May 2022 17:30:02 +0800
Subject: [PATCH] 1
---
lib/src/aop/aop_manager.dart | 197 +++++++++++++++++++
lib/src/aop/aspectd.dart | 219 +++++++++++++++++++++
lib/src/aop/hook_factory.dart | 95 +++++++++
lib/src/build_system/targets/common.dart | 192 +++++++++++--------
lib/src/build_system/targets/web.dart | 234 +++++++++++++----------
lib/src/commands/build_bundle.dart | 33 ++--
lib/src/compile.dart | 184 ++++++++++--------
7 files changed, 874 insertions(+), 280 deletions(-)
create mode 100644 lib/src/aop/aop_manager.dart
create mode 100644 lib/src/aop/aspectd.dart
create mode 100644 lib/src/aop/hook_factory.dart
diff --git a/lib/src/aop/aop_manager.dart b/lib/src/aop/aop_manager.dart
new file mode 100644
index 0000000..ef49db8
--- /dev/null
+++ b/lib/src/aop/aop_manager.dart
@@ -0,0 +1,197 @@
+// @dart = 2.8
+
+import 'package:flutter_tools/src/aop/hook_factory.dart';
+import 'package:flutter_tools/src/dart/package_map.dart';
+import 'package:package_config/package_config.dart';
+import 'package:yaml/yaml.dart';
+import 'package:file/file.dart' as f;
+import '../globals.dart' as globals;
+import '../artifacts.dart';
+
+import '../build_info.dart';
+import '../globals.dart';
+
+/// 创建时间:2020-03-28
+/// 作者:liujingguang
+/// 描述:AopManager管理类
+///
+/// aop_config.yaml文件配置需要处理app.dill文件的工程, 在根项目下进行配置.
+/// project_name为项目名称
+/// exec_path为生成的snapshot的路径
+///
+/// 配置样例如下:
+///
+/// flutter_tools_hook:
+/// - project_name: 'beike_aspectd'
+/// exec_path: 'bin/starter.snapshot'
+///
+/// - project_name: 'flutter_aop_data_parse'
+/// exec_path: 'bin/starter.snapshot'
+class AopManager {
+ static const String sYamlConfigName = 'aop_config.yaml';
+ static const String key_flutter_tools_hook = 'flutter_tools_hook';
+ static const String key_project_name = 'project_name';
+ static const String key_exec_path = 'exec_path';
+
+ static Future<void> hookBuildBundleCommand(
+ String productDirPath,
+ BuildMode buildMode,
+ ) async {
+ await _handleHook(productDirPath, buildMode, CommandType4Aop.Bundle);
+ }
+
+ static Future<void> hookBuildAotCommand(
+ String productDirPath,
+ BuildMode buildMode,
+ ) async {
+ await _handleHook(productDirPath, buildMode, CommandType4Aop.Aot);
+ }
+
+ static Future<void> hookSnapshotCommand(
+ String productDirPath,
+ BuildMode buildMode,
+ ) async {
+ await _handleHook(productDirPath, buildMode, CommandType4Aop.Snapshot);
+ }
+
+ static Future<List<String>> aopArgs(BuildMode buildMode) async {
+ final String dart_path = globals.artifacts
+ .getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
+
+ final List proceduresList = await _aopProcedures();
+
+ final List<String> args = [
+ '--build-mode',
+ buildMode.name,
+ '--dart-path',
+ dart_path
+ ];
+
+ if (proceduresList != null && proceduresList.isNotEmpty) {
+ final String produces = proceduresList.join(',');
+ args.add('--aop-packages');
+ args.add(produces);
+ }
+
+ return args;
+ }
+
+ static Future<List<String>> _aopProcedures() async {
+ List<String> procedures = List<String>();
+
+ final String configYamlPath =
+ fs.path.join(fs.currentDirectory.path, sYamlConfigName);
+
+ if (fs.file(configYamlPath).existsSync()) {
+ final dynamic yamlInfo =
+ loadYaml(fs.file(configYamlPath).readAsStringSync());
+
+ if (yamlInfo == null) {
+ return null;
+ }
+
+ if (yamlInfo[key_flutter_tools_hook] is! YamlList) {
+ return null;
+ }
+
+ final YamlList yamlNodes = yamlInfo[key_flutter_tools_hook] as YamlList;
+ for (dynamic v in yamlNodes) {
+ if (v == null) {
+ continue;
+ }
+
+ final String projectName = v[key_project_name] as String;
+ final String execPath = v[key_exec_path] as String;
+
+ if (projectName == null || execPath == null) {
+ continue;
+ }
+
+ final String packagePath = await _findAopPackagePath(projectName);
+ if (packagePath == null) {
+ continue;
+ }
+
+ procedures.add(fs.path.join(packagePath, execPath));
+ }
+ }
+
+ return procedures;
+ }
+
+ static Future<void> _handleHook(
+ String productDirPath, BuildMode buildMode, CommandType4Aop type) async {
+// return Future.value();
+ try {
+ final String configYamlPath =
+ fs.path.join(fs.currentDirectory.path, sYamlConfigName);
+
+ print(configYamlPath);
+
+ if (fs.file(configYamlPath).existsSync()) {
+ final dynamic yamlInfo =
+ loadYaml(fs.file(configYamlPath).readAsStringSync());
+
+ if (yamlInfo == null) {
+ return;
+ }
+
+ if (yamlInfo[key_flutter_tools_hook] is! YamlList) {
+ return;
+ }
+
+ final YamlList yamlNodes = yamlInfo[key_flutter_tools_hook] as YamlList;
+ for (dynamic v in yamlNodes) {
+ if (v == null) {
+ return;
+ }
+
+ final String projectName = v[key_project_name] as String;
+ final String execPath = v[key_exec_path] as String;
+
+ if (projectName == null || execPath == null) {
+ return;
+ }
+ final String packagePath = await _findAopPackagePath(projectName);
+ if (packagePath == null) {
+ return;
+ }
+
+ await HookFactory.hook(productDirPath,
+ fs.path.join(packagePath, execPath), buildMode, type);
+ }
+ }
+ // ignore: avoid_catches_without_on_clauses
+ } catch (e) {
+ printTrace('error in _handleHook of $type : ${e.toString()}');
+ }
+ }
+
+ /// 获取项目中引用flutter_aop_data_parse的路径
+ static Future<String> _findAopPackagePath(String projectName) async {
+ Map<String, dynamic> packages;
+ try {
+ final String packagesFilePath =
+ fs.path.join(fs.currentDirectory.path, '.packages');
+
+ final f.File packageFile = fs.file(packagesFilePath);
+ final PackageConfig packageConfig =
+ await loadPackageConfigWithLogging(packageFile);
+ packages = PackageConfig.toJson(packageConfig);
+
+ for (Package package in packageConfig.packages) {
+ if (package.name == projectName) {
+ final Uri uri = package.packageUriRoot;
+ final String uriString = uri.path;
+ return uriString;
+ }
+ }
+ // ignore: avoid_catches_without_on_clauses
+ } catch (e) {
+ printTrace('Invalid .packages file: $e');
+ return null;
+ }
+
+ return null;
+ }
+}
diff --git a/lib/src/aop/aspectd.dart b/lib/src/aop/aspectd.dart
new file mode 100644
index 0000000..b05fe75
--- /dev/null
+++ b/lib/src/aop/aspectd.dart
@@ -0,0 +1,219 @@
+// Copyright 2018 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.
+
+// @dart = 2.8
+
+import 'dart:io';
+
+import 'package:crypto/crypto.dart';
+import 'package:yaml/yaml.dart';
+import 'package:package_config/package_config.dart';
+
+import '../artifacts.dart';
+import '../base/common.dart';
+import '../build_info.dart';
+import '../base/file_system.dart';
+import '../build_system/build_system.dart';
+import '../build_system/targets/common.dart';
+import '../cache.dart';
+import '../compile.dart';
+import '../dart/package_map.dart';
+import '../globals.dart' as globals;
+
+const String aspectdImplPackageRelPath = '..';
+const String frontendServerDartSnapshot = 'frontend_server.dart.snapshot';
+const String sYamlConfigName = 'aop_config.yaml';
+const String key_flutter_tools_hook = 'flutter_tools_hook';
+const String key_project_name = 'project_name';
+const String key_exec_path = 'exec_path';
+const String beike_aspectd = 'beike_aspectd';
+const String inner_path = 'inner';
+const String globalPackagesPath = '.packages';
+
+class AspectdHook {
+ static Future<Directory> getPackagePathFromConfig(
+ String packageConfigPath, String packageName) async {
+ final PackageConfig packageConfig = await loadPackageConfigWithLogging(
+ globals.fs.file(packageConfigPath),
+ logger: globals.logger,
+ );
+ if ((packageConfig?.packages?.length ?? 0) > 0) {
+ final Package aspectdPackage = packageConfig.packages.toList().firstWhere(
+ (Package element) => element.name == packageName,
+ orElse: () => null);
+
+ if (aspectdPackage == null) {
+ return null;
+ }
+ return globals.fs.directory(aspectdPackage.root.toFilePath());
+ }
+ return null;
+ }
+
+ static Future<Directory> getFlutterFrontendServerDirectory(
+ String packagesPath) async {
+ final Directory directory =
+ await getPackagePathFromConfig(packagesPath, beike_aspectd);
+
+ if (directory == null) {
+ return null;
+ }
+
+ return globals.fs.directory(globals.fs.path
+ .join(directory.absolute.path, inner_path, 'flutter_frontend_server'));
+ }
+
+ static bool configFileExists() {
+ final String configYamlPath =
+ globals.fs.path.join(globals.fs.currentDirectory.path, sYamlConfigName);
+
+ if (globals.fs.file(configYamlPath).existsSync()) {
+ final dynamic yamlInfo =
+ loadYaml(globals.fs.file(configYamlPath).readAsStringSync());
+
+ if (yamlInfo == null) {
+ return false;
+ }
+
+ if (yamlInfo[key_flutter_tools_hook] is! YamlList) {
+ return false;
+ }
+
+ final YamlList yamlNodes = yamlInfo[key_flutter_tools_hook] as YamlList;
+
+ if (yamlNodes.nodes.isNotEmpty) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static Directory getAspectdDirectory(Directory rootProjectDir) {
+ return globals.fs.directory(globals.fs.path.normalize(globals.fs.path
+ .join(rootProjectDir.path, aspectdImplPackageRelPath, beike_aspectd)));
+ }
+
+ static Future<void> enableAspectd() async {
+ final Directory currentDirectory = globals.fs.currentDirectory;
+
+ final String packagesPath = globals.fs.path
+ .join(currentDirectory.absolute.path, globalPackagesPath);
+
+ final Directory beikeAspectdDirectory =
+ await getPackagePathFromConfig(packagesPath, beike_aspectd);
+
+ final Directory flutterFrontendServerDirectory =
+ await getFlutterFrontendServerDirectory(packagesPath);
+
+ if (beikeAspectdDirectory == null ||
+ flutterFrontendServerDirectory == null) {
+ return;
+ }
+
+ final String aspectdPackagesPath = globals.fs.path.join(
+ beikeAspectdDirectory.absolute.path, inner_path, globalPackagesPath);
+
+ await checkAspectdFlutterFrontendServerSnapshot(
+ aspectdPackagesPath, flutterFrontendServerDirectory);
+ }
+
+ static Future<void> checkAspectdFlutterFrontendServerSnapshot(
+ String packagesPath, Directory flutterFrontendServerDirectory) async {
+ final String aspectdFlutterFrontendServerSnapshot = globals.fs.path.join(
+ flutterFrontendServerDirectory.absolute.path,
+ frontendServerDartSnapshot);
+ final String defaultFlutterFrontendServerSnapshot = globals.artifacts
+ .getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
+ final File defaultServerFile =
+ globals.fs.file(defaultFlutterFrontendServerSnapshot);
+ final File aspectdServerFile =
+ globals.fs.file(aspectdFlutterFrontendServerSnapshot);
+
+ if (defaultServerFile.existsSync()) {
+ if (md5.convert(defaultServerFile.readAsBytesSync()) ==
+ md5.convert(aspectdServerFile.readAsBytesSync())) {
+ return true;
+ }
+
+ globals.fs.file(defaultFlutterFrontendServerSnapshot).deleteSync();
+ }
+
+ aspectdServerFile.copySync(defaultFlutterFrontendServerSnapshot);
+ }
+
+ static Future<String> getDartSdkDependency(String aspectdDir) async {
+ final ProcessResult processResult = await globals.processManager.run(
+ <String>[
+ globals.fs.path.join(
+ globals.artifacts.getArtifactPath(
+ Artifact.frontendServerSnapshotForEngineDartSdk),
+ 'bin',
+ 'pub'),
+ 'get',
+ '--verbosity=warning'
+ ],
+ workingDirectory: aspectdDir,
+ environment: <String, String>{'FLUTTER_ROOT': Cache.flutterRoot});
+ if (processResult.exitCode != 0) {
+ throwToolExit(
+ 'Aspectd unexpected error: ${processResult.stderr.toString()}');
+ }
+ final Directory kernelDir = await getPackagePathFromConfig(
+ globals.fs.path.join(aspectdDir, globalPackagesPath), 'kernel');
+ return kernelDir.parent.parent.path;
+ }
+
+ Future<void> runBuildDillCommand(Environment environment) async {
+ print('aop front end compiling');
+
+ final Directory mainDirectory = globals.fs.currentDirectory;
+
+ String relativeDir = environment.outputDir.absolute.path
+ .substring(environment.projectDir.absolute.path.length + 1);
+ final String outputDir =
+ globals.fs.path.join(mainDirectory.path, relativeDir);
+
+ final String buildDir =
+ globals.fs.path.join(mainDirectory.path, '.dart_tool', 'flutter_build');
+
+ final Map<String, String> defines = environment.defines;
+ relativeDir = defines[kTargetFile]
+ .substring(environment.projectDir.absolute.path.length + 1);
+
+ String targetFile = environment.defines[kTargetFile];
+ targetFile ??= globals.fs.path.join(mainDirectory.path, 'lib', 'main.dart');
+
+ defines[kTargetFile] = targetFile;
+
+ final Environment auxEnvironment = Environment(
+ projectDir: mainDirectory,
+ outputDir: globals.fs.directory(outputDir),
+ cacheDir: environment.cacheDir,
+ flutterRootDir: environment.flutterRootDir,
+ fileSystem: environment.fileSystem,
+ logger: environment.logger,
+ artifacts: environment.artifacts,
+ processManager: environment.processManager,
+ engineVersion: environment.engineVersion,
+ buildDir: globals.fs.directory(buildDir),
+ defines: defines,
+ inputs: environment.inputs);
+ const KernelSnapshot auxKernelSnapshot = KernelSnapshot();
+ final CompilerOutput compilerOutput =
+ await auxKernelSnapshot.buildImpl(auxEnvironment);
+
+ final String aspectdDill = compilerOutput.outputFilename;
+
+ print('Aspectdill path : ' + aspectdDill);
+ final File originalDillFile = globals.fs.file(
+ globals.fs.path.join(environment.buildDir.absolute.path, 'app.dill'));
+
+ print('originalDillFile path : ' + originalDillFile.path);
+ if (originalDillFile.existsSync()) {
+ await originalDillFile.copy(originalDillFile.absolute.path + '.bak');
+ }
+ globals.fs.file(aspectdDill).copySync(originalDillFile.absolute.path);
+ }
+}
diff --git a/lib/src/aop/hook_factory.dart b/lib/src/aop/hook_factory.dart
new file mode 100644
index 0000000..4d1d337
--- /dev/null
+++ b/lib/src/aop/hook_factory.dart
@@ -0,0 +1,95 @@
+// @dart = 2.8
+
+import 'dart:io';
+
+import 'package:flutter_tools/src/artifacts.dart';
+import 'package:flutter_tools/src/base/common.dart';
+import 'package:flutter_tools/src/base/file_system.dart';
+import 'package:flutter_tools/src/build_info.dart';
+import 'package:flutter_tools/src/globals.dart';
+
+/// 创建时间:2020-03-28
+/// 作者:liujingguang
+/// 描述:Hook处理工厂
+enum CommandType4Aop { Bundle, Aot, Snapshot }
+
+class HookFactory {
+ static Future<void> hook(String productDirPath, String executorPath,
+ BuildMode buildMode, CommandType4Aop type) async {
+ if (productDirPath == null ||
+ executorPath == null ||
+ !fs.file(executorPath).existsSync()) {
+ return;
+ }
+
+ String inputPath;
+ switch (type) {
+ case CommandType4Aop.Bundle:
+ inputPath = _getBundleInputPath(productDirPath);
+ break;
+ case CommandType4Aop.Aot:
+ inputPath = _getAotInputPath(productDirPath);
+ break;
+ case CommandType4Aop.Snapshot:
+ inputPath = _getSnapShotInputPath(productDirPath);
+ break;
+ }
+ if (!inputPath.startsWith(fs.currentDirectory.path)) {
+ inputPath = fs.path.join(fs.currentDirectory.path, inputPath);
+ }
+ if (!fs.file(inputPath).existsSync()) {
+ return;
+ }
+
+ final String outputPath =
+ inputPath + '.${type.toString().toLowerCase()}.result.dill';
+
+ /// 执行hook命令
+ final List<String> command = <String>[
+ artifacts
+ .getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
+ executorPath,
+ '--input',
+ inputPath,
+ '--output',
+ outputPath,
+ if (buildMode != BuildMode.release) ...<String>[
+ '--sdk-root',
+ fs
+ .file(artifacts.getArtifactPath(Artifact.platformKernelDill))
+ .parent
+ .path +
+ fs.path.separator
+ ],
+ ];
+
+ print(command.toString());
+ final ProcessResult result = await processManager.run(command);
+ if (result.exitCode != 0) {
+ print(result.stderr);
+ throwToolExit(
+ 'hook by aop terminated unexpectedly in ${type.toString()}.');
+ return;
+ }
+
+ print('aop hook succeed');
+
+ /// 删除input输入文件
+ final File inputFile = fs.file(inputPath);
+ if (inputFile.existsSync()) {
+// inputFile.copySync(inputPath + '.old'); //调试时可以打开查看信息
+ inputFile.deleteSync();
+ }
+
+ /// 将Aop处理生成后的output文件重命名为input文件名
+ fs.file(outputPath).renameSync(inputPath);
+ }
+
+ static String _getBundleInputPath(String assetsDir) =>
+ fs.path.join(assetsDir, 'kernel_blob.bin');
+
+ static String _getAotInputPath(String path) =>
+ fs.path.join(path ?? getAotBuildDirectory(), 'app.dill');
+
+ static String _getSnapShotInputPath(String path) => path;
+}
diff --git a/lib/src/build_system/targets/common.dart b/lib/src/build_system/targets/common.dart
index 6b0ac8d..97d5379 100644
--- a/lib/src/build_system/targets/common.dart
+++ b/lib/src/build_system/targets/common.dart
@@ -4,6 +4,7 @@
import 'package:package_config/package_config.dart';
+import '../../aop/aspectd.dart';
import '../../artifacts.dart';
import '../../base/build.dart';
import '../../base/file_system.dart';
@@ -29,23 +30,21 @@ class CopyFlutterBundle extends Target {
@override
List<Source> get inputs => const <Source>[
- Source.artifact(Artifact.vmSnapshotData, mode: BuildMode.debug),
- Source.artifact(Artifact.isolateSnapshotData, mode: BuildMode.debug),
- Source.pattern('{BUILD_DIR}/app.dill'),
- ...IconTreeShaker.inputs,
- ];
+ Source.artifact(Artifact.vmSnapshotData, mode: BuildMode.debug),
+ Source.artifact(Artifact.isolateSnapshotData, mode: BuildMode.debug),
+ Source.pattern('{BUILD_DIR}/app.dill'),
+ ...IconTreeShaker.inputs,
+ ];
@override
List<Source> get outputs => const <Source>[
- Source.pattern('{OUTPUT_DIR}/vm_snapshot_data'),
- Source.pattern('{OUTPUT_DIR}/isolate_snapshot_data'),
- Source.pattern('{OUTPUT_DIR}/kernel_blob.bin'),
- ];
+ Source.pattern('{OUTPUT_DIR}/vm_snapshot_data'),
+ Source.pattern('{OUTPUT_DIR}/isolate_snapshot_data'),
+ Source.pattern('{OUTPUT_DIR}/kernel_blob.bin'),
+ ];
@override
- List<String> get depfiles => <String>[
- 'flutter_assets.d'
- ];
+ List<String> get depfiles => <String>['flutter_assets.d'];
@override
Future<void> build(Environment environment) async {
@@ -58,14 +57,18 @@ class CopyFlutterBundle extends Target {
// Only copy the prebuilt runtimes and kernel blob in debug mode.
if (buildMode == BuildMode.debug) {
- final String vmSnapshotData = environment.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
- final String isolateSnapshotData = environment.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
- environment.buildDir.childFile('app.dill')
+ final String vmSnapshotData = environment.artifacts
+ .getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
+ final String isolateSnapshotData = environment.artifacts
+ .getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
+ environment.buildDir
+ .childFile('app.dill')
.copySync(environment.outputDir.childFile('kernel_blob.bin').path);
- environment.fileSystem.file(vmSnapshotData)
+ environment.fileSystem
+ .file(vmSnapshotData)
.copySync(environment.outputDir.childFile('vm_snapshot_data').path);
- environment.fileSystem.file(isolateSnapshotData)
- .copySync(environment.outputDir.childFile('isolate_snapshot_data').path);
+ environment.fileSystem.file(isolateSnapshotData).copySync(
+ environment.outputDir.childFile('isolate_snapshot_data').path);
}
final Depfile assetDepfile = await copyAssets(
environment,
@@ -85,8 +88,8 @@ class CopyFlutterBundle extends Target {
@override
List<Target> get dependencies => const <Target>[
- KernelSnapshot(),
- ];
+ KernelSnapshot(),
+ ];
}
/// Copies the pre-built flutter bundle for release mode.
@@ -104,8 +107,8 @@ class ReleaseCopyFlutterBundle extends CopyFlutterBundle {
@override
List<String> get depfiles => const <String>[
- 'flutter_assets.d',
- ];
+ 'flutter_assets.d',
+ ];
@override
List<Target> get dependencies => const <Target>[];
@@ -125,29 +128,35 @@ class KernelSnapshot extends Target {
@override
List<Source> get inputs => const <Source>[
- Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
- Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
- Source.artifact(Artifact.platformKernelDill),
- Source.hostArtifact(HostArtifact.engineDartBinary),
- Source.artifact(Artifact.frontendServerSnapshotForEngineDartSdk),
- ];
+ Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
+ Source.pattern(
+ '{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
+ Source.artifact(Artifact.platformKernelDill),
+ Source.hostArtifact(HostArtifact.engineDartBinary),
+ Source.artifact(Artifact.frontendServerSnapshotForEngineDartSdk),
+ ];
@override
List<Source> get outputs => const <Source>[];
@override
List<String> get depfiles => <String>[
- 'kernel_snapshot.d',
- ];
+ 'kernel_snapshot.d',
+ ];
@override
List<Target> get dependencies => const <Target>[
- GenerateLocalizationsTarget(),
- DartPluginRegistrantTarget(),
- ];
+ GenerateLocalizationsTarget(),
+ DartPluginRegistrantTarget(),
+ ];
@override
Future<void> build(Environment environment) async {
+ await AspectdHook.enableAspectd();
+ await buildImpl(environment);
+ }
+
+ Future<CompilerOutput> buildImpl(Environment environment) async {
final KernelCompiler compiler = KernelCompiler(
fileSystem: environment.fileSystem,
logger: environment.logger,
@@ -159,23 +168,30 @@ class KernelSnapshot extends Target {
if (buildModeEnvironment == null) {
throw MissingDefineException(kBuildMode, 'kernel_snapshot');
}
- final String? targetPlatformEnvironment = environment.defines[kTargetPlatform];
+ final String? targetPlatformEnvironment =
+ environment.defines[kTargetPlatform];
if (targetPlatformEnvironment == null) {
throw MissingDefineException(kTargetPlatform, 'kernel_snapshot');
}
final BuildMode buildMode = getBuildModeForName(buildModeEnvironment);
- final String targetFile = environment.defines[kTargetFile] ?? environment.fileSystem.path.join('lib', 'main.dart');
+ final String targetFile = environment.defines[kTargetFile] ??
+ environment.fileSystem.path.join('lib', 'main.dart');
final File packagesFile = environment.projectDir
- .childDirectory('.dart_tool')
- .childFile('package_config.json');
- final String targetFileAbsolute = environment.fileSystem.file(targetFile).absolute.path;
+ .childDirectory('.dart_tool')
+ .childFile('package_config.json');
+ final String targetFileAbsolute =
+ environment.fileSystem.file(targetFile).absolute.path;
// everything besides 'false' is considered to be enabled.
- final bool trackWidgetCreation = environment.defines[kTrackWidgetCreation] != 'false';
- final TargetPlatform targetPlatform = getTargetPlatformForName(targetPlatformEnvironment);
+ final bool trackWidgetCreation =
+ environment.defines[kTrackWidgetCreation] != 'false';
+ final TargetPlatform targetPlatform =
+ getTargetPlatformForName(targetPlatformEnvironment);
// This configuration is all optional.
- final List<String> extraFrontEndOptions = decodeCommaSeparated(environment.defines, kExtraFrontEndOptions);
- final List<String>? fileSystemRoots = environment.defines[kFileSystemRoots]?.split(',');
+ final List<String> extraFrontEndOptions =
+ decodeCommaSeparated(environment.defines, kExtraFrontEndOptions);
+ final List<String>? fileSystemRoots =
+ environment.defines[kFileSystemRoots]?.split(',');
final String? fileSystemScheme = environment.defines[kFileSystemScheme];
TargetModel targetModel = TargetModel.flutter;
@@ -240,6 +256,8 @@ class KernelSnapshot extends Target {
if (output == null || output.errorCount != 0) {
throw Exception();
}
+
+ return output;
}
}
@@ -264,26 +282,32 @@ abstract class AotElfBase extends Target {
if (buildModeEnvironment == null) {
throw MissingDefineException(kBuildMode, 'aot_elf');
}
- final String? targetPlatformEnvironment = environment.defines[kTargetPlatform];
+ final String? targetPlatformEnvironment =
+ environment.defines[kTargetPlatform];
if (targetPlatformEnvironment == null) {
throw MissingDefineException(kTargetPlatform, 'aot_elf');
}
- final List<String> extraGenSnapshotOptions = decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
+ final List<String> extraGenSnapshotOptions =
+ decodeCommaSeparated(environment.defines, kExtraGenSnapshotOptions);
final BuildMode buildMode = getBuildModeForName(buildModeEnvironment);
- final TargetPlatform targetPlatform = getTargetPlatformForName(targetPlatformEnvironment);
+ final TargetPlatform targetPlatform =
+ getTargetPlatformForName(targetPlatformEnvironment);
final String? splitDebugInfo = environment.defines[kSplitDebugInfo];
- final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
+ final bool dartObfuscation =
+ environment.defines[kDartObfuscation] == 'true';
final String? codeSizeDirectory = environment.defines[kCodeSizeDirectory];
if (codeSizeDirectory != null) {
final File codeSizeFile = environment.fileSystem
- .directory(codeSizeDirectory)
- .childFile('snapshot.${environment.defines[kTargetPlatform]}.json');
+ .directory(codeSizeDirectory)
+ .childFile('snapshot.${environment.defines[kTargetPlatform]}.json');
final File precompilerTraceFile = environment.fileSystem
- .directory(codeSizeDirectory)
- .childFile('trace.${environment.defines[kTargetPlatform]}.json');
- extraGenSnapshotOptions.add('--write-v8-snapshot-profile-to=${codeSizeFile.path}');
- extraGenSnapshotOptions.add('--trace-precompiler-to=${precompilerTraceFile.path}');
+ .directory(codeSizeDirectory)
+ .childFile('trace.${environment.defines[kTargetPlatform]}.json');
+ extraGenSnapshotOptions
+ .add('--write-v8-snapshot-profile-to=${codeSizeFile.path}');
+ extraGenSnapshotOptions
+ .add('--trace-precompiler-to=${precompilerTraceFile.path}');
}
final int snapshotExitCode = await snapshotter.build(
@@ -311,25 +335,27 @@ class AotElfProfile extends AotElfBase {
@override
List<Source> get inputs => <Source>[
- const Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
- const Source.pattern('{BUILD_DIR}/app.dill'),
- const Source.hostArtifact(HostArtifact.engineDartBinary),
- const Source.artifact(Artifact.skyEnginePath),
- Source.artifact(Artifact.genSnapshot,
- platform: targetPlatform,
- mode: BuildMode.profile,
- ),
- ];
+ const Source.pattern(
+ '{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
+ const Source.pattern('{BUILD_DIR}/app.dill'),
+ const Source.hostArtifact(HostArtifact.engineDartBinary),
+ const Source.artifact(Artifact.skyEnginePath),
+ Source.artifact(
+ Artifact.genSnapshot,
+ platform: targetPlatform,
+ mode: BuildMode.profile,
+ ),
+ ];
@override
List<Source> get outputs => const <Source>[
- Source.pattern('{BUILD_DIR}/app.so'),
- ];
+ Source.pattern('{BUILD_DIR}/app.so'),
+ ];
@override
List<Target> get dependencies => const <Target>[
- KernelSnapshot(),
- ];
+ KernelSnapshot(),
+ ];
final TargetPlatform targetPlatform;
}
@@ -343,25 +369,27 @@ class AotElfRelease extends AotElfBase {
@override
List<Source> get inputs => <Source>[
- const Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
- const Source.pattern('{BUILD_DIR}/app.dill'),
- const Source.hostArtifact(HostArtifact.engineDartBinary),
- const Source.artifact(Artifact.skyEnginePath),
- Source.artifact(Artifact.genSnapshot,
- platform: targetPlatform,
- mode: BuildMode.release,
- ),
- ];
+ const Source.pattern(
+ '{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/common.dart'),
+ const Source.pattern('{BUILD_DIR}/app.dill'),
+ const Source.hostArtifact(HostArtifact.engineDartBinary),
+ const Source.artifact(Artifact.skyEnginePath),
+ Source.artifact(
+ Artifact.genSnapshot,
+ platform: targetPlatform,
+ mode: BuildMode.release,
+ ),
+ ];
@override
List<Source> get outputs => const <Source>[
- Source.pattern('{BUILD_DIR}/app.so'),
- ];
+ Source.pattern('{BUILD_DIR}/app.so'),
+ ];
@override
List<Target> get dependencies => const <Target>[
- KernelSnapshot(),
- ];
+ KernelSnapshot(),
+ ];
final TargetPlatform targetPlatform;
}
@@ -373,13 +401,13 @@ abstract class CopyFlutterAotBundle extends Target {
@override
List<Source> get inputs => const <Source>[
- Source.pattern('{BUILD_DIR}/app.so'),
- ];
+ Source.pattern('{BUILD_DIR}/app.so'),
+ ];
@override
List<Source> get outputs => const <Source>[
- Source.pattern('{OUTPUT_DIR}/app.so'),
- ];
+ Source.pattern('{OUTPUT_DIR}/app.so'),
+ ];
@override
Future<void> build(Environment environment) async {
diff --git a/lib/src/build_system/targets/web.dart b/lib/src/build_system/targets/web.dart
index 462c22f..1d4109e 100644
--- a/lib/src/build_system/targets/web.dart
+++ b/lib/src/build_system/targets/web.dart
@@ -22,6 +22,7 @@ import '../depfile.dart';
import '../exceptions.dart';
import 'assets.dart';
import 'localizations.dart';
+import '../../aop/aop_manager.dart';
/// Whether the application has web plugins.
const String kHasWebPlugins = 'HasWebPlugins';
@@ -54,6 +55,7 @@ enum ServiceWorkerStrategy {
/// Download the app shell eagerly and all other assets lazily.
/// Prefer the offline cached version.
offlineFirst,
+
/// Do not generate a service worker,
none,
}
@@ -85,13 +87,14 @@ class WebEntrypointTarget extends Target {
@override
List<Source> get inputs => const <Source>[
- Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/web.dart'),
- ];
+ Source.pattern(
+ '{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/web.dart'),
+ ];
@override
List<Source> get outputs => const <Source>[
- Source.pattern('{BUILD_DIR}/main.dart'),
- ];
+ Source.pattern('{BUILD_DIR}/main.dart'),
+ ];
@override
Future<void> build(Environment environment) async {
@@ -120,18 +123,20 @@ class WebEntrypointTarget extends Target {
// By construction, this will only be null if the .packages file does not
// have an entry for the user's application or if the main file is
// outside of the lib/ directory.
- final String mainImport = packageConfig.toPackageUri(importUri)?.toString()
- ?? importUri.toString();
+ final String mainImport =
+ packageConfig.toPackageUri(importUri)?.toString() ??
+ importUri.toString();
String contents;
if (hasPlugins) {
final Uri generatedUri = environment.projectDir
- .childDirectory('lib')
- .childFile('generated_plugin_registrant.dart')
- .absolute
- .uri;
- final String generatedImport = packageConfig.toPackageUri(generatedUri)?.toString()
- ?? generatedUri.toString();
+ .childDirectory('lib')
+ .childFile('generated_plugin_registrant.dart')
+ .absolute
+ .uri;
+ final String generatedImport =
+ packageConfig.toPackageUri(generatedUri)?.toString() ??
+ generatedUri.toString();
contents = '''
// @dart=${languageVersion.major}.${languageVersion.minor}
@@ -162,8 +167,7 @@ Future<void> main() async {
}
''';
}
- environment.buildDir.childFile('main.dart')
- .writeAsStringSync(contents);
+ environment.buildDir.childFile('main.dart').writeAsStringSync(contents);
}
}
@@ -176,26 +180,26 @@ class Dart2JSTarget extends Target {
@override
List<Target> get dependencies => const <Target>[
- WebEntrypointTarget(),
- GenerateLocalizationsTarget(),
- ];
+ WebEntrypointTarget(),
+ GenerateLocalizationsTarget(),
+ ];
@override
List<Source> get inputs => const <Source>[
- Source.hostArtifact(HostArtifact.flutterWebSdk),
- Source.hostArtifact(HostArtifact.dart2jsSnapshot),
- Source.hostArtifact(HostArtifact.engineDartBinary),
- Source.pattern('{BUILD_DIR}/main.dart'),
- Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
- ];
+ Source.hostArtifact(HostArtifact.flutterWebSdk),
+ Source.hostArtifact(HostArtifact.dart2jsSnapshot),
+ Source.hostArtifact(HostArtifact.engineDartBinary),
+ Source.pattern('{BUILD_DIR}/main.dart'),
+ Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
+ ];
@override
List<Source> get outputs => const <Source>[];
@override
List<String> get depfiles => const <String>[
- 'dart2js.d',
- ];
+ 'dart2js.d',
+ ];
String _collectOutput(ProcessResult result) {
final String stdout = result.stdout is List<int>
@@ -214,31 +218,36 @@ class Dart2JSTarget extends Target {
throw MissingDefineException(kBuildMode, name);
}
final BuildMode buildMode = getBuildModeForName(buildModeEnvironment);
- final bool sourceMapsEnabled = environment.defines[kSourceMapsEnabled] == 'true';
- final bool nativeNullAssertions = environment.defines[kNativeNullAssertions] == 'true';
+ final bool sourceMapsEnabled =
+ environment.defines[kSourceMapsEnabled] == 'true';
+ final bool nativeNullAssertions =
+ environment.defines[kNativeNullAssertions] == 'true';
final Artifacts artifacts = globals.artifacts!;
- final String librariesSpec = (artifacts.getHostArtifact(HostArtifact.flutterWebSdk) as Directory).childFile('libraries.json').path;
+ final String librariesSpec =
+ (artifacts.getHostArtifact(HostArtifact.flutterWebSdk) as Directory)
+ .childFile('libraries.json')
+ .path;
final List<String> sharedCommandOptions = <String>[
artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
'--disable-dart-dev',
artifacts.getHostArtifact(HostArtifact.dart2jsSnapshot).path,
'--libraries-spec=$librariesSpec',
...decodeCommaSeparated(environment.defines, kExtraFrontEndOptions),
- if (nativeNullAssertions)
- '--native-null-assertions',
+ if (nativeNullAssertions) '--native-null-assertions',
if (buildMode == BuildMode.profile)
'-Ddart.vm.profile=true'
else
'-Ddart.vm.product=true',
- for (final String dartDefine in decodeDartDefines(environment.defines, kDartDefines))
+ for (final String dartDefine
+ in decodeDartDefines(environment.defines, kDartDefines))
'-D$dartDefine',
- if (!sourceMapsEnabled)
- '--no-source-maps',
+ if (!sourceMapsEnabled) '--no-source-maps',
];
// Run the dart2js compilation in two stages, so that icon tree shaking can
// parse the kernel file for web builds.
- final ProcessResult kernelResult = await globals.processManager.run(<String>[
+ final ProcessResult kernelResult =
+ await globals.processManager.run(<String>[
...sharedCommandOptions,
'-o',
environment.buildDir.childFile('app.dill').path,
@@ -250,11 +259,16 @@ class Dart2JSTarget extends Target {
throw Exception(_collectOutput(kernelResult));
}
- final String? dart2jsOptimization = environment.defines[kDart2jsOptimization];
+ await AopManager.hookSnapshotCommand(
+ environment.buildDir.childFile('app.dill').path, buildMode);
+
+ final String? dart2jsOptimization =
+ environment.defines[kDart2jsOptimization];
final File outputJSFile = environment.buildDir.childFile('main.dart.js');
final bool csp = environment.defines[kCspMode] == 'true';
- final ProcessResult javaScriptResult = await environment.processManager.run(<String>[
+ final ProcessResult javaScriptResult =
+ await environment.processManager.run(<String>[
...sharedCommandOptions,
if (dart2jsOptimization != null) '-$dart2jsOptimization' else '-O4',
if (buildMode == BuildMode.profile) '--no-minify',
@@ -266,11 +280,11 @@ class Dart2JSTarget extends Target {
if (javaScriptResult.exitCode != 0) {
throw Exception(_collectOutput(javaScriptResult));
}
- final File dart2jsDeps = environment.buildDir
- .childFile('app.dill.deps');
+ final File dart2jsDeps = environment.buildDir.childFile('app.dill.deps');
if (!dart2jsDeps.existsSync()) {
- globals.printWarning('Warning: dart2js did not produced expected deps list at '
- '${dart2jsDeps.path}');
+ globals.printWarning(
+ 'Warning: dart2js did not produced expected deps list at '
+ '${dart2jsDeps.path}');
return;
}
final DepfileService depfileService = DepfileService(
@@ -297,30 +311,31 @@ class WebReleaseBundle extends Target {
@override
List<Target> get dependencies => const <Target>[
- Dart2JSTarget(),
- ];
+ Dart2JSTarget(),
+ ];
@override
List<Source> get inputs => const <Source>[
- Source.pattern('{BUILD_DIR}/main.dart.js'),
- Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
- ];
+ Source.pattern('{BUILD_DIR}/main.dart.js'),
+ Source.pattern('{PROJECT_DIR}/pubspec.yaml'),
+ ];
@override
List<Source> get outputs => const <Source>[
- Source.pattern('{OUTPUT_DIR}/main.dart.js'),
- ];
+ Source.pattern('{OUTPUT_DIR}/main.dart.js'),
+ ];
@override
List<String> get depfiles => const <String>[
- 'dart2js.d',
- 'flutter_assets.d',
- 'web_resources.d',
- ];
+ 'dart2js.d',
+ 'flutter_assets.d',
+ 'web_resources.d',
+ ];
@override
Future<void> build(Environment environment) async {
- for (final File outputFile in environment.buildDir.listSync(recursive: true).whereType<File>()) {
+ for (final File outputFile
+ in environment.buildDir.listSync(recursive: true).whereType<File>()) {
final String basename = globals.fs.path.basename(outputFile.path);
if (!basename.contains('main.dart.js')) {
continue;
@@ -329,16 +344,17 @@ class WebReleaseBundle extends Target {
if (basename.endsWith('.deps')) {
continue;
}
- outputFile.copySync(
- environment.outputDir.childFile(globals.fs.path.basename(outputFile.path)).path
- );
+ outputFile.copySync(environment.outputDir
+ .childFile(globals.fs.path.basename(outputFile.path))
+ .path);
}
final String versionInfo = FlutterProject.current().getVersionInfo();
environment.outputDir
.childFile('version.json')
.writeAsStringSync(versionInfo);
- final Directory outputDirectory = environment.outputDir.childDirectory('assets');
+ final Directory outputDirectory =
+ environment.outputDir.childDirectory('assets');
outputDirectory.createSync(recursive: true);
final Depfile depfile = await copyAssets(
environment,
@@ -354,19 +370,16 @@ class WebReleaseBundle extends Target {
environment.buildDir.childFile('flutter_assets.d'),
);
- final Directory webResources = environment.projectDir
- .childDirectory('web');
- final List<File> inputResourceFiles = webResources
- .listSync(recursive: true)
- .whereType<File>()
- .toList();
+ final Directory webResources = environment.projectDir.childDirectory('web');
+ final List<File> inputResourceFiles =
+ webResources.listSync(recursive: true).whereType<File>().toList();
// Copy other resource files out of web/ directory.
final List<File> outputResourcesFiles = <File>[];
for (final File inputFile in inputResourceFiles) {
final File outputFile = globals.fs.file(globals.fs.path.join(
- environment.outputDir.path,
- globals.fs.path.relative(inputFile.path, from: webResources.path)));
+ environment.outputDir.path,
+ globals.fs.path.relative(inputFile.path, from: webResources.path)));
if (!outputFile.parent.existsSync()) {
outputFile.parent.createSync(recursive: true);
}
@@ -374,31 +387,36 @@ class WebReleaseBundle extends Target {
// insert a random hash into the requests for service_worker.js. This is not a content hash,
// because it would need to be the hash for the entire bundle and not just the resource
// in question.
- if (environment.fileSystem.path.basename(inputFile.path) == 'index.html') {
+ if (environment.fileSystem.path.basename(inputFile.path) ==
+ 'index.html') {
final String randomHash = Random().nextInt(4294967296).toString();
- String resultString = inputFile.readAsStringSync()
- .replaceFirst(
- 'var serviceWorkerVersion = null',
- "var serviceWorkerVersion = '$randomHash'",
- )
- // This is for legacy index.html that still use the old service
- // worker loading mechanism.
- .replaceFirst(
- "navigator.serviceWorker.register('flutter_service_worker.js')",
- "navigator.serviceWorker.register('flutter_service_worker.js?v=$randomHash')",
- );
+ String resultString = inputFile
+ .readAsStringSync()
+ .replaceFirst(
+ 'var serviceWorkerVersion = null',
+ "var serviceWorkerVersion = '$randomHash'",
+ )
+ // This is for legacy index.html that still use the old service
+ // worker loading mechanism.
+ .replaceFirst(
+ "navigator.serviceWorker.register('flutter_service_worker.js')",
+ "navigator.serviceWorker.register('flutter_service_worker.js?v=$randomHash')",
+ );
final String? baseHref = environment.defines[kBaseHref];
if (resultString.contains(kBaseHrefPlaceholder) && baseHref == null) {
resultString = resultString.replaceAll(kBaseHrefPlaceholder, '/');
- } else if (resultString.contains(kBaseHrefPlaceholder) && baseHref != null) {
- resultString = resultString.replaceAll(kBaseHrefPlaceholder, baseHref);
+ } else if (resultString.contains(kBaseHrefPlaceholder) &&
+ baseHref != null) {
+ resultString =
+ resultString.replaceAll(kBaseHrefPlaceholder, baseHref);
}
outputFile.writeAsStringSync(resultString);
continue;
}
inputFile.copySync(outputFile.path);
}
- final Depfile resourceFile = Depfile(inputResourceFiles, outputResourcesFiles);
+ final Depfile resourceFile =
+ Depfile(inputResourceFiles, outputResourcesFiles);
depfileService.writeToFile(
resourceFile,
environment.buildDir.childFile('web_resources.d'),
@@ -443,10 +461,14 @@ class WebBuiltInAssets extends Target {
// built as part of the engine, but fetched from CIPD, and so it won't be
// found in ENGINE/src/out.
final Directory flutterWebSdk = cache.getWebSdkDirectory();
- final Directory canvasKitDirectory = flutterWebSdk.childDirectory('canvaskit');
- for (final File file in canvasKitDirectory.listSync(recursive: true).whereType<File>()) {
- final String relativePath = fileSystem.path.relative(file.path, from: canvasKitDirectory.path);
- final String targetPath = fileSystem.path.join(environment.outputDir.path, 'canvaskit', relativePath);
+ final Directory canvasKitDirectory =
+ flutterWebSdk.childDirectory('canvaskit');
+ for (final File file
+ in canvasKitDirectory.listSync(recursive: true).whereType<File>()) {
+ final String relativePath =
+ fileSystem.path.relative(file.path, from: canvasKitDirectory.path);
+ final String targetPath = fileSystem.path
+ .join(environment.outputDir.path, 'canvaskit', relativePath);
file.copySync(targetPath);
}
}
@@ -464,15 +486,15 @@ class WebServiceWorker extends Target {
@override
List<Target> get dependencies => <Target>[
- const Dart2JSTarget(),
- const WebReleaseBundle(),
- WebBuiltInAssets(fileSystem, cache),
- ];
+ const Dart2JSTarget(),
+ const WebReleaseBundle(),
+ WebBuiltInAssets(fileSystem, cache),
+ ];
@override
List<String> get depfiles => const <String>[
- 'service_worker.d',
- ];
+ 'service_worker.d',
+ ];
@override
List<Source> get inputs => const <Source>[];
@@ -483,24 +505,26 @@ class WebServiceWorker extends Target {
@override
Future<void> build(Environment environment) async {
final List<File> contents = environment.outputDir
- .listSync(recursive: true)
- .whereType<File>()
- .where((File file) => !file.path.endsWith('flutter_service_worker.js')
- && !globals.fs.path.basename(file.path).startsWith('.'))
- .toList();
+ .listSync(recursive: true)
+ .whereType<File>()
+ .where((File file) =>
+ !file.path.endsWith('flutter_service_worker.js') &&
+ !globals.fs.path.basename(file.path).startsWith('.'))
+ .toList();
final Map<String, String> urlToHash = <String, String>{};
for (final File file in contents) {
// Do not force caching of source maps.
if (file.path.endsWith('main.dart.js.map') ||
- file.path.endsWith('.part.js.map')) {
+ file.path.endsWith('.part.js.map')) {
continue;
}
- final String url = globals.fs.path.toUri(
- globals.fs.path.relative(
- file.path,
- from: environment.outputDir.path),
- ).toString();
+ final String url = globals.fs.path
+ .toUri(
+ globals.fs.path
+ .relative(file.path, from: environment.outputDir.path),
+ )
+ .toString();
final String hash = md5.convert(await file.readAsBytes()).toString();
urlToHash[url] = hash;
// Add an additional entry for the base URL.
@@ -509,10 +533,11 @@ class WebServiceWorker extends Target {
}
}
- final File serviceWorkerFile = environment.outputDir
- .childFile('flutter_service_worker.js');
+ final File serviceWorkerFile =
+ environment.outputDir.childFile('flutter_service_worker.js');
final Depfile depfile = Depfile(contents, <File>[serviceWorkerFile]);
- final ServiceWorkerStrategy serviceWorkerStrategy = _serviceWorkerStrategyFromString(
+ final ServiceWorkerStrategy serviceWorkerStrategy =
+ _serviceWorkerStrategyFromString(
environment.defines[kServiceWorkerStrategy],
);
final String serviceWorker = generateServiceWorker(
@@ -529,8 +554,7 @@ class WebServiceWorker extends Target {
],
serviceWorkerStrategy: serviceWorkerStrategy,
);
- serviceWorkerFile
- .writeAsStringSync(serviceWorker);
+ serviceWorkerFile.writeAsStringSync(serviceWorker);
final DepfileService depfileService = DepfileService(
fileSystem: globals.fs,
logger: globals.logger,
diff --git a/lib/src/commands/build_bundle.dart b/lib/src/commands/build_bundle.dart
index 56465a8..23b6b13 100644
--- a/lib/src/commands/build_bundle.dart
+++ b/lib/src/commands/build_bundle.dart
@@ -14,6 +14,7 @@ import '../project.dart';
import '../reporting/reporting.dart';
import '../runner/flutter_command.dart';
import 'build.dart';
+import '../aop/aspectd.dart';
class BuildBundleCommand extends BuildSubCommand {
BuildBundleCommand({
@@ -28,11 +29,11 @@ class BuildBundleCommand extends BuildSubCommand {
usesExtraDartFlagOptions(verboseHelp: verboseHelp);
argParser
..addOption('depfile',
- defaultsTo: defaultDepfilePath,
- help: 'A file path where a depfile will be written. '
- 'This contains all build inputs and outputs in a Make-style syntax.'
- )
- ..addOption('target-platform',
+ defaultsTo: defaultDepfilePath,
+ help: 'A file path where a depfile will be written. '
+ 'This contains all build inputs and outputs in a Make-style syntax.')
+ ..addOption(
+ 'target-platform',
defaultsTo: 'android-arm',
allowed: const <String>[
'android-arm',
@@ -47,17 +48,20 @@ class BuildBundleCommand extends BuildSubCommand {
],
help: 'The architecture for which to build the application.',
)
- ..addOption('asset-dir',
+ ..addOption(
+ 'asset-dir',
defaultsTo: getAssetBuildDirectory(),
- help: 'The output directory for the kernel_blob.bin file, the native snapshot, the assets, etc. '
- 'Can be used to redirect the output when driving the Flutter toolchain from another build system.',
+ help:
+ 'The output directory for the kernel_blob.bin file, the native snapshot, the assets, etc. '
+ 'Can be used to redirect the output when driving the Flutter toolchain from another build system.',
)
..addFlag(
'tree-shake-icons',
negatable: true,
defaultsTo: false,
hide: !verboseHelp,
- help: '(deprecated) Icon font tree shaking is not supported by this command.',
+ help:
+ '(deprecated) Icon font tree shaking is not supported by this command.',
);
usesPubOption();
usesTrackWidgetCreation(verboseHelp: verboseHelp);
@@ -71,7 +75,8 @@ class BuildBundleCommand extends BuildSubCommand {
final String name = 'bundle';
@override
- final String description = 'Build the Flutter assets directory from your app.';
+ final String description =
+ 'Build the Flutter assets directory from your app.';
@override
final String usageFooter = 'The Flutter assets directory contains your '
@@ -81,7 +86,8 @@ class BuildBundleCommand extends BuildSubCommand {
@override
Future<CustomDimensions> get usageValues async {
final String projectDir = globals.fs.file(targetFile).parent.parent.path;
- final FlutterProject flutterProject = FlutterProject.fromDirectory(globals.fs.directory(projectDir));
+ final FlutterProject flutterProject =
+ FlutterProject.fromDirectory(globals.fs.directory(projectDir));
if (flutterProject == null) {
return const CustomDimensions();
}
@@ -94,13 +100,16 @@ class BuildBundleCommand extends BuildSubCommand {
@override
Future<void> validateCommand() async {
if (argResults['tree-shake-icons'] as bool) {
- throwToolExit('The "--tree-shake-icons" flag is deprecated for "build bundle" and will be removed in a future version of Flutter.');
+ throwToolExit(
+ 'The "--tree-shake-icons" flag is deprecated for "build bundle" and will be removed in a future version of Flutter.');
}
return super.validateCommand();
}
@override
Future<FlutterCommandResult> runCommand() async {
+ await AspectdHook.enableAspectd();
+
final String targetPlatform = stringArg('target-platform');
final TargetPlatform platform = getTargetPlatformForName(targetPlatform);
if (platform == null) {
diff --git a/lib/src/compile.dart b/lib/src/compile.dart
index f09cce3..dd6aa2b 100644
--- a/lib/src/compile.dart
+++ b/lib/src/compile.dart
@@ -18,6 +18,7 @@ import 'base/logger.dart';
import 'base/platform.dart';
import 'build_info.dart';
import 'convert.dart';
+import 'aop/aspectd.dart';
/// The target model describes the set of core libraries that are available within
/// the SDK.
@@ -61,7 +62,8 @@ class TargetModel {
}
class CompilerOutput {
- const CompilerOutput(this.outputFilename, this.errorCount, this.sources, {this.expressionData});
+ const CompilerOutput(this.outputFilename, this.errorCount, this.sources,
+ {this.expressionData});
final String outputFilename;
final int errorCount;
@@ -78,8 +80,8 @@ class StdoutHandler {
StdoutHandler({
required Logger logger,
required FileSystem fileSystem,
- }) : _logger = logger,
- _fileSystem = fileSystem {
+ }) : _logger = logger,
+ _fileSystem = fileSystem {
reset();
}
@@ -114,8 +116,10 @@ class StdoutHandler {
return;
}
final int spaceDelimiter = message.lastIndexOf(' ');
- final String fileName = message.substring(messageBoundaryKey.length + 1, spaceDelimiter);
- final int errorCount = int.parse(message.substring(spaceDelimiter + 1).trim());
+ final String fileName =
+ message.substring(messageBoundaryKey.length + 1, spaceDelimiter);
+ final int errorCount =
+ int.parse(message.substring(spaceDelimiter + 1).trim());
Uint8List? expressionData;
if (_readFile) {
expressionData = _fileSystem.file(fileName).readAsBytesSync();
@@ -152,7 +156,10 @@ class StdoutHandler {
// This is needed to get ready to process next compilation result output,
// with its own boundary key and new completer.
- void reset({ bool suppressCompilerMessages = false, bool expectSources = true, bool readFile = false }) {
+ void reset(
+ {bool suppressCompilerMessages = false,
+ bool expectSources = true,
+ bool readFile = false}) {
boundaryKey = null;
compilerOutput = Completer<CompilerOutput?>();
_suppressCompilerMessages = suppressCompilerMessages;
@@ -170,7 +177,8 @@ List<String> buildModeOptions(BuildMode mode, List<String> dartDefines) {
'-Ddart.vm.profile=false',
// This allows the CLI to override the value of this define for unit
// testing the framework.
- if (!dartDefines.any((String define) => define.startsWith('dart.vm.product')))
+ if (!dartDefines
+ .any((String define) => define.startsWith('dart.vm.product')))
'-Ddart.vm.product=false',
'--enable-asserts',
];
@@ -198,13 +206,14 @@ class KernelCompiler {
required List<String> fileSystemRoots,
String? fileSystemScheme,
@visibleForTesting StdoutHandler? stdoutHandler,
- }) : _logger = logger,
- _fileSystem = fileSystem,
- _artifacts = artifacts,
- _processManager = processManager,
- _fileSystemScheme = fileSystemScheme,
- _fileSystemRoots = fileSystemRoots,
- _stdoutHandler = stdoutHandler ?? StdoutHandler(logger: logger, fileSystem: fileSystem);
+ }) : _logger = logger,
+ _fileSystem = fileSystem,
+ _artifacts = artifacts,
+ _processManager = processManager,
+ _fileSystemScheme = fileSystemScheme,
+ _fileSystemRoots = fileSystemRoots,
+ _stdoutHandler = stdoutHandler ??
+ StdoutHandler(logger: logger, fileSystem: fileSystem);
final FileSystem _fileSystem;
final Artifacts _artifacts;
@@ -235,14 +244,14 @@ class KernelCompiler {
required List<String> dartDefines,
required PackageConfig packageConfig,
}) async {
- final String frontendServer = _artifacts.getArtifactPath(
- Artifact.frontendServerSnapshotForEngineDartSdk
- );
+ final String frontendServer = _artifacts
+ .getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
// This is a URI, not a file path, so the forward slash is correct even on Windows.
if (!sdkRoot.endsWith('/')) {
sdkRoot = '$sdkRoot/';
}
- final String engineDartPath = _artifacts.getHostArtifact(HostArtifact.engineDartBinary).path;
+ final String engineDartPath =
+ _artifacts.getHostArtifact(HostArtifact.engineDartBinary).path;
if (!_processManager.canRun(engineDartPath)) {
throwToolExit('Unable to find Dart binary at $engineDartPath');
}
@@ -252,7 +261,8 @@ class KernelCompiler {
if (packagesPath != null) {
mainUri = packageConfig.toPackageUri(mainFileUri)?.toString();
}
- mainUri ??= toMultiRootPath(mainFileUri, _fileSystemScheme, _fileSystemRoots, _fileSystem.path.separator == r'\');
+ mainUri ??= toMultiRootPath(mainFileUri, _fileSystemScheme,
+ _fileSystemRoots, _fileSystem.path.separator == r'\');
if (outputFilePath != null && !_fileSystem.isFileSync(outputFilePath)) {
_fileSystem.file(outputFilePath).createSync(recursive: true);
}
@@ -273,8 +283,7 @@ class KernelCompiler {
sdkRoot,
'--target=$targetModel',
'--no-print-incremental-dependencies',
- for (final Object dartDefine in dartDefines)
- '-D$dartDefine',
+ for (final Object dartDefine in dartDefines) '-D$dartDefine',
...buildModeOptions(buildMode, dartDefines),
if (trackWidgetCreation) '--track-widget-creation',
if (!linkPlatformKernelIn) '--no-link-platform',
@@ -290,7 +299,8 @@ class KernelCompiler {
'--output-dill',
outputFilePath,
],
- if (depFilePath != null && (fileSystemRoots == null || fileSystemRoots.isEmpty)) ...<String>[
+ if (depFilePath != null &&
+ (fileSystemRoots == null || fileSystemRoots.isEmpty)) ...<String>[
'--depfile',
depFilePath,
],
@@ -318,13 +328,11 @@ class KernelCompiler {
_logger.printTrace(command.join(' '));
final Process server = await _processManager.start(command);
- server.stderr
- .transform<String>(utf8.decoder)
- .listen(_logger.printError);
+ server.stderr.transform<String>(utf8.decoder).listen(_logger.printError);
server.stdout
- .transform<String>(utf8.decoder)
- .transform<String>(const LineSplitter())
- .listen(_stdoutHandler.handler);
+ .transform<String>(utf8.decoder)
+ .transform<String>(const LineSplitter())
+ .listen(_stdoutHandler.handler);
final int exitCode = await server.exitCode;
if (exitCode == 0) {
return _stdoutHandler.compilerOutput?.future;
@@ -429,7 +437,8 @@ class _RejectRequest extends _CompilationRequest {
/// The wrapper is intended to stay resident in memory as user changes, reloads,
/// restarts the Flutter app.
abstract class ResidentCompiler {
- factory ResidentCompiler(String sdkRoot, {
+ factory ResidentCompiler(
+ String sdkRoot, {
required BuildMode buildMode,
required Logger logger,
required ProcessManager processManager,
@@ -557,17 +566,18 @@ class DefaultResidentCompiler implements ResidentCompiler {
List<String>? dartDefines,
this.librariesSpec,
@visibleForTesting StdoutHandler? stdoutHandler,
- }) : assert(sdkRoot != null),
- _logger = logger,
- _processManager = processManager,
- _artifacts = artifacts,
- _stdoutHandler = stdoutHandler ?? StdoutHandler(logger: logger, fileSystem: fileSystem),
- _platform = platform,
- dartDefines = dartDefines ?? const <String>[],
- // This is a URI, not a file path, so the forward slash is correct even on Windows.
- sdkRoot = sdkRoot.endsWith('/') ? sdkRoot : '$sdkRoot/',
- // Make a copy, we might need to modify it later.
- fileSystemRoots = List<String>.from(fileSystemRoots);
+ }) : assert(sdkRoot != null),
+ _logger = logger,
+ _processManager = processManager,
+ _artifacts = artifacts,
+ _stdoutHandler = stdoutHandler ??
+ StdoutHandler(logger: logger, fileSystem: fileSystem),
+ _platform = platform,
+ dartDefines = dartDefines ?? const <String>[],
+ // This is a URI, not a file path, so the forward slash is correct even on Windows.
+ sdkRoot = sdkRoot.endsWith('/') ? sdkRoot : '$sdkRoot/',
+ // Make a copy, we might need to modify it later.
+ fileSystemRoots = List<String>.from(fileSystemRoots);
final Logger _logger;
final ProcessManager _processManager;
@@ -606,7 +616,8 @@ class DefaultResidentCompiler implements ResidentCompiler {
final StdoutHandler _stdoutHandler;
bool _compileRequestNeedsConfirmation = false;
- final StreamController<_CompilationRequest> _controller = StreamController<_CompilationRequest>();
+ final StreamController<_CompilationRequest> _controller =
+ StreamController<_CompilationRequest>();
@override
Future<CompilerOutput?> recompile(
@@ -638,9 +649,8 @@ class DefaultResidentCompiler implements ResidentCompiler {
}
}
final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
- _controller.add(
- _RecompileRequest(completer, mainUri, invalidatedFiles, outputPath, packageConfig, suppressErrors)
- );
+ _controller.add(_RecompileRequest(completer, mainUri, invalidatedFiles,
+ outputPath, packageConfig, suppressErrors));
return completer.future;
}
@@ -649,8 +659,10 @@ class DefaultResidentCompiler implements ResidentCompiler {
_compileRequestNeedsConfirmation = true;
_stdoutHandler._suppressCompilerMessages = request.suppressErrors;
- final String mainUri = request.packageConfig.toPackageUri(request.mainUri)?.toString() ??
- toMultiRootPath(request.mainUri, fileSystemScheme, fileSystemRoots, _platform.isWindows);
+ final String mainUri =
+ request.packageConfig.toPackageUri(request.mainUri)?.toString() ??
+ toMultiRootPath(request.mainUri, fileSystemScheme, fileSystemRoots,
+ _platform.isWindows);
final Process? server = _server;
if (server == null) {
@@ -668,7 +680,8 @@ class DefaultResidentCompiler implements ResidentCompiler {
message = fileUri.toString();
} else {
message = request.packageConfig.toPackageUri(fileUri)?.toString() ??
- toMultiRootPath(fileUri, fileSystemScheme, fileSystemRoots, _platform.isWindows);
+ toMultiRootPath(fileUri, fileSystemScheme, fileSystemRoots,
+ _platform.isWindows);
}
server.stdin.writeln(message);
_logger.printTrace(message);
@@ -701,9 +714,10 @@ class DefaultResidentCompiler implements ResidentCompiler {
String scriptUri,
String? outputPath,
) async {
- final String frontendServer = _artifacts.getArtifactPath(
- Artifact.frontendServerSnapshotForEngineDartSdk
- );
+ await AspectdHook.enableAspectd();
+
+ final String frontendServer = _artifacts
+ .getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk);
final List<String> command = <String>[
_artifacts.getHostArtifact(HostArtifact.engineDartBinary).path,
'--disable-dart-dev',
@@ -711,8 +725,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
'--sdk-root',
sdkRoot,
'--incremental',
- if (testCompilation)
- '--no-print-incremental-dependencies',
+ if (testCompilation) '--no-print-incremental-dependencies',
'--target=$targetModel',
// TODO(zanderso): remove once this becomes the default behavior
// in the frontend_server.
@@ -722,8 +735,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
// in the frontend_server.
// https://github.com/flutter/flutter/issues/59902
'--experimental-emit-debug-metadata',
- for (final Object dartDefine in dartDefines)
- '-D$dartDefine',
+ for (final Object dartDefine in dartDefines) '-D$dartDefine',
if (outputPath != null) ...<String>[
'--output-dill',
outputPath,
@@ -761,23 +773,21 @@ class DefaultResidentCompiler implements ResidentCompiler {
_logger.printTrace(command.join(' '));
_server = await _processManager.start(command);
_server?.stdout
- .transform<String>(utf8.decoder)
- .transform<String>(const LineSplitter())
- .listen(
- _stdoutHandler.handler,
- onDone: () {
- // when outputFilename future is not completed, but stdout is closed
- // process has died unexpectedly.
- if (_stdoutHandler.compilerOutput?.isCompleted == false) {
- _stdoutHandler.compilerOutput?.complete(null);
- throwToolExit('the Dart compiler exited unexpectedly.');
- }
- });
+ .transform<String>(utf8.decoder)
+ .transform<String>(const LineSplitter())
+ .listen(_stdoutHandler.handler, onDone: () {
+ // when outputFilename future is not completed, but stdout is closed
+ // process has died unexpectedly.
+ if (_stdoutHandler.compilerOutput?.isCompleted == false) {
+ _stdoutHandler.compilerOutput?.complete(null);
+ throwToolExit('the Dart compiler exited unexpectedly.');
+ }
+ });
_server?.stderr
- .transform<String>(utf8.decoder)
- .transform<String>(const LineSplitter())
- .listen(_logger.printError);
+ .transform<String>(utf8.decoder)
+ .transform<String>(const LineSplitter())
+ .listen(_logger.printError);
unawaited(_server?.exitCode.then((int code) {
if (code != 0) {
@@ -805,14 +815,22 @@ class DefaultResidentCompiler implements ResidentCompiler {
}
final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
- final _CompileExpressionRequest request = _CompileExpressionRequest(
- completer, expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
+ final _CompileExpressionRequest request = _CompileExpressionRequest(
+ completer,
+ expression,
+ definitions,
+ typeDefinitions,
+ libraryUri,
+ klass,
+ isStatic);
_controller.add(request);
return completer.future;
}
- Future<CompilerOutput?> _compileExpression(_CompileExpressionRequest request) async {
- _stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false, readFile: true);
+ Future<CompilerOutput?> _compileExpression(
+ _CompileExpressionRequest request) async {
+ _stdoutHandler.reset(
+ suppressCompilerMessages: true, expectSources: false, readFile: true);
// 'compile-expression' should be invoked after compiler has been started,
// program was compiled.
@@ -852,14 +870,13 @@ class DefaultResidentCompiler implements ResidentCompiler {
}
final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
- _controller.add(
- _CompileExpressionToJsRequest(
- completer, libraryUri, line, column, jsModules, jsFrameValues, moduleName, expression)
- );
+ _controller.add(_CompileExpressionToJsRequest(completer, libraryUri, line,
+ column, jsModules, jsFrameValues, moduleName, expression));
return completer.future;
}
- Future<CompilerOutput?> _compileExpressionToJs(_CompileExpressionToJsRequest request) async {
+ Future<CompilerOutput?> _compileExpressionToJs(
+ _CompileExpressionToJsRequest request) async {
_stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false);
// 'compile-expression-to-js' should be invoked after compiler has been started,
@@ -875,9 +892,13 @@ class DefaultResidentCompiler implements ResidentCompiler {
..writeln(request.libraryUri ?? '')
..writeln(request.line)
..writeln(request.column);
- request.jsModules?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
+ request.jsModules?.forEach((String k, String v) {
+ server.stdin.writeln('$k:$v');
+ });
server.stdin.writeln(inputKey);
- request.jsFrameValues?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
+ request.jsFrameValues?.forEach((String k, String v) {
+ server.stdin.writeln('$k:$v');
+ });
server.stdin
..writeln(inputKey)
..writeln(request.moduleName ?? '')
@@ -939,7 +960,8 @@ class DefaultResidentCompiler implements ResidentCompiler {
/// Convert a file URI into a multi-root scheme URI if provided, otherwise
/// return unmodified.
@visibleForTesting
-String toMultiRootPath(Uri fileUri, String? scheme, List<String> fileSystemRoots, bool windows) {
+String toMultiRootPath(
+ Uri fileUri, String? scheme, List<String> fileSystemRoots, bool windows) {
if (scheme == null || fileSystemRoots.isEmpty || fileUri.scheme != 'file') {
return fileUri.toString();
}
--
2.30.1 (Apple Git-130)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment