mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[dart2js] Apply mixin transform globally.
This cl applies the mixin transform only on the full dill. In addition, this cl also adds a concatenate dills step to more closely match modular builds in production. Change-Id: Icb37c5e2180c9e8246334143a6f772a203f80bf9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238320 Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
parent
d7935c209d
commit
0ad7f27990
|
@ -70,8 +70,10 @@ class Dart2jsTarget extends Target {
|
|||
final String name;
|
||||
|
||||
final CompilerOptions? options;
|
||||
final bool canPerformGlobalTransforms;
|
||||
|
||||
Dart2jsTarget(this.name, this.flags, {this.options});
|
||||
Dart2jsTarget(this.name, this.flags,
|
||||
{this.options, this.canPerformGlobalTransforms = true});
|
||||
|
||||
@override
|
||||
bool get enableNoSuchMethodForwarders => true;
|
||||
|
@ -157,8 +159,10 @@ class Dart2jsTarget extends Target {
|
|||
}
|
||||
lowering.transformLibraries(libraries, coreTypes, hierarchy, options);
|
||||
logger?.call("Lowering transformations performed");
|
||||
transformMixins.transformLibraries(libraries);
|
||||
logger?.call("Mixin transformations performed");
|
||||
if (canPerformGlobalTransforms) {
|
||||
transformMixins.transformLibraries(libraries);
|
||||
logger?.call("Mixin transformations performed");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -170,9 +170,7 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
|
||||
bool get fromDill {
|
||||
var targetPath = compilationTarget!.path;
|
||||
return targetPath.endsWith('.dill') ||
|
||||
targetPath.endsWith('.gdill') ||
|
||||
targetPath.endsWith('.mdill');
|
||||
return targetPath.endsWith('.dill');
|
||||
}
|
||||
|
||||
/// Location of the package configuration file.
|
||||
|
|
|
@ -17,6 +17,8 @@ import '../commandline_options.dart';
|
|||
import '../common.dart';
|
||||
import '../kernel/front_end_adapter.dart';
|
||||
import '../kernel/dart2js_target.dart' show Dart2jsTarget;
|
||||
import '../kernel/transformations/clone_mixin_methods_with_super.dart'
|
||||
as transformMixins show transformLibraries;
|
||||
import '../options.dart';
|
||||
|
||||
class Input {
|
||||
|
@ -121,6 +123,10 @@ class _LoadFromKernelResult {
|
|||
this.component, this.entryLibrary, this.moduleLibraries);
|
||||
}
|
||||
|
||||
void _doGlobalTransforms(Component component) {
|
||||
transformMixins.transformLibraries(component.libraries);
|
||||
}
|
||||
|
||||
Future<_LoadFromKernelResult> _loadFromKernel(CompilerOptions options,
|
||||
api.CompilerInput compilerInput, String targetName) async {
|
||||
Library entryLibrary;
|
||||
|
@ -178,6 +184,11 @@ Future<_LoadFromKernelResult> _loadFromKernel(CompilerOptions options,
|
|||
var mainMethod = _findMainMethod(entryLibrary);
|
||||
component.setMainMethodAndMode(mainMethod, true, component.mode);
|
||||
}
|
||||
|
||||
// We apply global transforms when running phase 0.
|
||||
if (options.cfeOnly) {
|
||||
_doGlobalTransforms(component);
|
||||
}
|
||||
return _LoadFromKernelResult(component, entryLibrary, moduleLibraries);
|
||||
}
|
||||
|
||||
|
@ -195,7 +206,8 @@ Future<_LoadFromSourceResult> _loadFromSource(
|
|||
fe.InitializedCompilerState initializedCompilerState,
|
||||
String targetName) async {
|
||||
bool verbose = false;
|
||||
Target target = Dart2jsTarget(targetName, TargetFlags(), options: options);
|
||||
Target target = Dart2jsTarget(targetName, TargetFlags(),
|
||||
options: options, canPerformGlobalTransforms: true);
|
||||
fe.FileSystem fileSystem = CompilerFileSystem(compilerInput);
|
||||
fe.Verbosity verbosity = options.verbosity;
|
||||
fe.DiagnosticMessageHandler onDiagnostic = (fe.DiagnosticMessage message) {
|
||||
|
|
|
@ -23,6 +23,7 @@ main(List<String> args) async {
|
|||
OutlineDillCompilationStep(),
|
||||
FullDillCompilationStep(),
|
||||
ModularAnalysisStep(),
|
||||
ConcatenateDillsStep(useModularAnalysis: true),
|
||||
ComputeClosedWorldStep(useModularAnalysis: true),
|
||||
GlobalAnalysisStep(),
|
||||
Dart2jsCodegenStep(codeId0),
|
||||
|
|
|
@ -25,13 +25,14 @@ Options _options;
|
|||
String _dart2jsScript;
|
||||
String _kernelWorkerScript;
|
||||
|
||||
const dillSummaryId = DataId("sdill");
|
||||
const dillId = DataId("dill");
|
||||
const modularUpdatedDillId = DataId("mdill");
|
||||
const modularDataId = DataId("mdata");
|
||||
const dillSummaryId = DataId("summary.dill");
|
||||
const dillId = DataId("full.dill");
|
||||
const fullDillId = DataId("concatenate.dill");
|
||||
const modularUpdatedDillId = DataId("modular.dill");
|
||||
const modularDataId = DataId("modular.data");
|
||||
const closedWorldId = DataId("world");
|
||||
const globalUpdatedDillId = DataId("gdill");
|
||||
const globalDataId = DataId("gdata");
|
||||
const globalUpdatedDillId = DataId("global.dill");
|
||||
const globalDataId = DataId("global.data");
|
||||
const codeId = ShardsDataId("code", 2);
|
||||
const codeId0 = ShardDataId(codeId, 0);
|
||||
const codeId1 = ShardDataId(codeId, 1);
|
||||
|
@ -305,44 +306,36 @@ class ModularAnalysisStep implements IOModularStep {
|
|||
}
|
||||
}
|
||||
|
||||
DataId idForDill({bool useModularAnalysis}) =>
|
||||
useModularAnalysis ? modularUpdatedDillId : dillId;
|
||||
|
||||
List<DataId> inputFromAnalysis({bool useModularAnalysis = false}) => [
|
||||
idForDill(useModularAnalysis: useModularAnalysis),
|
||||
if (useModularAnalysis) modularDataId,
|
||||
];
|
||||
|
||||
// Step that invokes the dart2js closed world computation.
|
||||
class ComputeClosedWorldStep implements IOModularStep {
|
||||
class ConcatenateDillsStep implements IOModularStep {
|
||||
final bool useModularAnalysis;
|
||||
|
||||
ComputeClosedWorldStep({this.useModularAnalysis});
|
||||
DataId get idForDill => useModularAnalysis ? modularUpdatedDillId : dillId;
|
||||
|
||||
List<DataId> get dependencies => [idForDill];
|
||||
|
||||
@override
|
||||
List<DataId> get resultData => const [closedWorldId, globalUpdatedDillId];
|
||||
List<DataId> get resultData => const [fullDillId];
|
||||
|
||||
@override
|
||||
bool get needsSources => false;
|
||||
|
||||
@override
|
||||
List<DataId> get dependencyDataNeeded =>
|
||||
inputFromAnalysis(useModularAnalysis: useModularAnalysis);
|
||||
List<DataId> get dependencyDataNeeded => dependencies;
|
||||
|
||||
@override
|
||||
List<DataId> get moduleDataNeeded =>
|
||||
inputFromAnalysis(useModularAnalysis: useModularAnalysis);
|
||||
List<DataId> get moduleDataNeeded => dependencies;
|
||||
|
||||
@override
|
||||
bool get onlyOnMain => true;
|
||||
|
||||
ConcatenateDillsStep({this.useModularAnalysis});
|
||||
|
||||
@override
|
||||
Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
|
||||
List<String> flags) async {
|
||||
if (_options.verbose)
|
||||
print("\nstep: dart2js compute closed world on $module");
|
||||
if (_options.verbose) print("\nstep: dart2js concatenate dills on $module");
|
||||
Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
|
||||
DataId dillId = idForDill(useModularAnalysis: useModularAnalysis);
|
||||
DataId dillId = idForDill;
|
||||
Iterable<String> dillDependencies =
|
||||
transitiveDependencies.map((m) => '${toUri(m, dillId)}');
|
||||
List<String> dataDependencies = transitiveDependencies
|
||||
|
@ -358,8 +351,66 @@ class ComputeClosedWorldStep implements IOModularStep {
|
|||
'${Flags.inputDill}=${toUri(module, dillId)}',
|
||||
for (String flag in flags) '--enable-experiment=$flag',
|
||||
'${Flags.dillDependencies}=${dillDependencies.join(',')}',
|
||||
if (useModularAnalysis)
|
||||
'${Flags.readModularAnalysis}=${dataDependencies.join(',')}',
|
||||
'${Flags.cfeOnly}',
|
||||
'--out=${toUri(module, fullDillId)}',
|
||||
];
|
||||
var result =
|
||||
await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
|
||||
|
||||
_checkExitCode(result, this, module);
|
||||
}
|
||||
|
||||
@override
|
||||
void notifyCached(Module module) {
|
||||
if (_options.verbose)
|
||||
print("\ncached step: dart2js concatenate dills on $module");
|
||||
}
|
||||
}
|
||||
|
||||
// Step that invokes the dart2js closed world computation.
|
||||
class ComputeClosedWorldStep implements IOModularStep {
|
||||
final bool useModularAnalysis;
|
||||
|
||||
ComputeClosedWorldStep({this.useModularAnalysis});
|
||||
|
||||
List<DataId> get dependencies => [
|
||||
fullDillId,
|
||||
if (useModularAnalysis) modularDataId,
|
||||
];
|
||||
|
||||
@override
|
||||
List<DataId> get resultData => const [closedWorldId, globalUpdatedDillId];
|
||||
|
||||
@override
|
||||
bool get needsSources => false;
|
||||
|
||||
@override
|
||||
List<DataId> get dependencyDataNeeded => dependencies;
|
||||
|
||||
@override
|
||||
List<DataId> get moduleDataNeeded => dependencies;
|
||||
|
||||
@override
|
||||
bool get onlyOnMain => true;
|
||||
|
||||
@override
|
||||
Future<void> execute(Module module, Uri root, ModuleDataToRelativeUri toUri,
|
||||
List<String> flags) async {
|
||||
if (_options.verbose)
|
||||
print("\nstep: dart2js compute closed world on $module");
|
||||
Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
|
||||
List<String> dataDependencies = transitiveDependencies
|
||||
.map((m) => '${toUri(m, modularDataId)}')
|
||||
.toList();
|
||||
dataDependencies.add('${toUri(module, modularDataId)}');
|
||||
List<String> args = [
|
||||
'--packages=${sdkRoot.toFilePath()}/.packages',
|
||||
_dart2jsScript,
|
||||
// TODO(sigmund): remove this dependency on libraries.json
|
||||
if (_options.useSdk) '--libraries-spec=$_librarySpecForSnapshot',
|
||||
'${Flags.entryUri}=$fakeRoot${module.mainSource}',
|
||||
'${Flags.inputDill}=${toUri(module, fullDillId)}',
|
||||
for (String flag in flags) '--enable-experiment=$flag',
|
||||
'${Flags.writeClosedWorld}=${toUri(module, closedWorldId)}',
|
||||
Flags.noClosedWorldInData,
|
||||
'--out=${toUri(module, globalUpdatedDillId)}',
|
||||
|
|
|
@ -22,6 +22,7 @@ main(List<String> args) async {
|
|||
IOPipeline([
|
||||
OutlineDillCompilationStep(),
|
||||
FullDillCompilationStep(),
|
||||
ConcatenateDillsStep(useModularAnalysis: false),
|
||||
ComputeClosedWorldStep(useModularAnalysis: false),
|
||||
GlobalAnalysisStep(),
|
||||
Dart2jsCodegenStep(codeId0),
|
||||
|
|
9
tests/modular/issue226161959/b.dart
Normal file
9
tests/modular/issue226161959/b.dart
Normal file
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'm.dart';
|
||||
|
||||
class B extends A {}
|
||||
|
||||
class C extends B with M {}
|
12
tests/modular/issue226161959/m.dart
Normal file
12
tests/modular/issue226161959/m.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
class A {
|
||||
String foo() => 'A';
|
||||
}
|
||||
|
||||
mixin M on A {
|
||||
@override
|
||||
String foo() => 'M' + super.foo();
|
||||
}
|
12
tests/modular/issue226161959/main.dart
Normal file
12
tests/modular/issue226161959/main.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. 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:expect/expect.dart';
|
||||
|
||||
import 'b.dart';
|
||||
|
||||
main() {
|
||||
C c = C();
|
||||
Expect.equals('MA', c.foo());
|
||||
}
|
8
tests/modular/issue226161959/modules.yaml
Normal file
8
tests/modular/issue226161959/modules.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
# for details. All rights reserved. Use of this source code is governed by a
|
||||
# BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
dependencies:
|
||||
main: [b, m, expect]
|
||||
b: [m]
|
||||
m: []
|
Loading…
Reference in a new issue