[CFE] Run widget transformer before constant evaluation.

Change-Id: I51ded35ecb95cb5cfbac5ecf8967e0918a48269a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101987
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Jacob Richman <jacobr@google.com>
This commit is contained in:
Aske Simon Christensen 2019-05-10 11:02:49 +00:00 committed by commit-bot@chromium.org
parent 1179467a5e
commit 8754351283
7 changed files with 69 additions and 34 deletions

View file

@ -13,7 +13,6 @@ import 'package:front_end/src/api_unstable/ddc.dart' as fe;
import 'package:kernel/kernel.dart' hide MapEntry;
import 'package:kernel/text/ast_to_text.dart' as kernel show Printer;
import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
import 'package:kernel/transformations/track_widget_constructor_locations.dart';
import 'package:path/path.dart' as path;
import 'package:source_maps/source_maps.dart' show SourceMapBuilder;
@ -213,6 +212,9 @@ Future<CompilerResult> _compile(List<String> args,
}
}
bool trackWidgetCreation =
argResults['track-widget-creation'] as bool ?? false;
var oldCompilerState = compilerState;
List<Component> doneInputSummaries;
fe.IncrementalCompiler incrementalCompiler;
@ -224,7 +226,7 @@ Future<CompilerResult> _compile(List<String> args,
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
summaryModules.keys.toList(),
DevCompilerTarget(),
DevCompilerTarget(trackWidgetCreation: trackWidgetCreation),
fileSystem: fileSystem,
experiments: experiments);
} else {
@ -236,7 +238,7 @@ Future<CompilerResult> _compile(List<String> args,
sourcePathToUri(packageFile),
sourcePathToUri(librarySpecPath),
summaryModules.keys.toList(),
DevCompilerTarget(),
DevCompilerTarget(trackWidgetCreation: trackWidgetCreation),
fileSystem: fileSystem,
experiments: experiments);
incrementalCompiler = compilerState.incrementalCompiler;
@ -320,13 +322,6 @@ Future<CompilerResult> _compile(List<String> args,
hierarchy = target.hierarchy;
}
// TODO(jmesserly): remove this hack once Flutter SDK has a `dartdevc` with
// support for the widget inspector.
if (argResults['track-widget-creation'] as bool) {
component.computeCanonicalNames();
WidgetCreatorTracker().transform(component);
}
var compiler =
ProgramCompiler(component, hierarchy, options, declaredVariables);

View file

@ -8,11 +8,16 @@ import 'package:kernel/kernel.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/transformations/track_widget_constructor_locations.dart';
import 'constants.dart' show DevCompilerConstantsBackend;
import 'kernel_helpers.dart';
/// A kernel [Target] to configure the Dart Front End for dartdevc.
class DevCompilerTarget extends Target {
DevCompilerTarget({this.trackWidgetCreation = false});
final bool trackWidgetCreation;
ClassHierarchy hierarchy;
bool get legacyMode => false;
@ -87,6 +92,18 @@ class DevCompilerTarget extends Target {
}
}
@override
void performPreConstantEvaluationTransformations(
Component component,
CoreTypes coreTypes,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {
if (trackWidgetCreation) {
WidgetCreatorTracker().transform(component, libraries);
}
}
@override
Expression instantiateInvocation(CoreTypes coreTypes, Expression receiver,
String name, Arguments arguments, int offset, bool isSuper) {

View file

@ -774,6 +774,12 @@ class KernelTarget extends TargetImplementation {
/// Run all transformations that are needed when building a bundle of
/// libraries for the first time.
void runBuildTransformations() {
backendTarget.performPreConstantEvaluationTransformations(
component,
loader.coreTypes,
loader.libraries,
new KernelDiagnosticReporter(loader),
logger: (String msg) => ticker.logMs(msg));
if (loader.target.enableConstantUpdate2018) {
TypeEnvironment environment =
new TypeEnvironment(loader.coreTypes, loader.hierarchy);

View file

@ -115,6 +115,15 @@ abstract class Target {
/// slowing down compilation.
void performOutlineTransformations(Component component) {}
/// Perform target-specific transformations on the given libraries that must
/// run before constant evaluation.
void performPreConstantEvaluationTransformations(
Component component,
CoreTypes coreTypes,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {}
/// Perform target-specific modular transformations on the given libraries.
void performModularTransformationsOnLibraries(
Component component,

View file

@ -414,15 +414,13 @@ class WidgetCreatorTracker {
clazz.constructors.forEach(handleConstructor);
}
/// Transform the given [module].
void transform(Component module) {
final List<Library> libraries = module.libraries;
/// Transform the given [libraries].
void transform(Component module, List<Library> libraries) {
if (libraries.isEmpty) {
return;
}
_resolveFlutterClasses(libraries);
_resolveFlutterClasses(module.libraries);
if (_widgetClass == null) {
// This application doesn't actually use the package:flutter library.
@ -431,9 +429,9 @@ class WidgetCreatorTracker {
final Set<Class> transformedClasses = new Set<Class>.identity();
final Set<Library> librariesToTransform = new Set<Library>.identity()
..addAll(module.libraries);
..addAll(libraries);
for (Library library in module.libraries) {
for (Library library in libraries) {
if (library.isExternal) {
continue;
}
@ -453,7 +451,7 @@ class WidgetCreatorTracker {
locationClass: _locationClass,
tracker: this);
for (Library library in module.libraries) {
for (Library library in libraries) {
if (library.isExternal) {
continue;
}

View file

@ -3,11 +3,17 @@
// BSD-style license that can be found in the LICENSE file.
library vm.target.flutter;
import 'package:kernel/ast.dart' show Component, Library;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/target/targets.dart';
import 'package:kernel/transformations/track_widget_constructor_locations.dart';
import 'package:vm/target/vm.dart' show VmTarget;
class FlutterTarget extends VmTarget {
FlutterTarget(TargetFlags flags) : super(flags);
FlutterTarget(TargetFlags flags, {this.trackWidgetCreation = false})
: super(flags);
final bool trackWidgetCreation;
@override
String get name => 'flutter';
@ -41,4 +47,16 @@ class FlutterTarget extends VmTarget {
'dart:ui',
'dart:vmservice_io',
];
@override
void performPreConstantEvaluationTransformations(
Component component,
CoreTypes coreTypes,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {
if (trackWidgetCreation) {
new WidgetCreatorTracker().transform(component, libraries);
}
}
}

View file

@ -19,7 +19,6 @@ import 'package:dev_compiler/src/kernel/target.dart';
import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
import 'package:kernel/ast.dart' show Component, Library;
import 'package:kernel/target/targets.dart';
import 'package:kernel/transformations/track_widget_constructor_locations.dart';
import 'package:vm/target/vm.dart';
import 'package:vm/target/flutter.dart';
import 'package:vm/target/flutter_runner.dart';
@ -175,11 +174,6 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
var summaryOnly = parsedArgs['summary-only'] as bool;
var trackKernelCreation = parsedArgs['track-kernel-creation'] as bool;
if (summaryOnly && trackKernelCreation) {
throw new ArgumentError('error: --summary-only is not compatible with '
'--track-kernel-creation');
}
// TODO(sigmund,jakemac): make target mandatory. We allow null to be backwards
// compatible while we migrate existing clients of this tool.
var targetName =
@ -194,7 +188,8 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
}
break;
case 'flutter':
target = new FlutterTarget(targetFlags);
target = new FlutterTarget(targetFlags,
trackWidgetCreation: trackKernelCreation);
if (summaryOnly) {
throw new ArgumentError(
'error: --summary-only not supported for the flutter target');
@ -217,7 +212,8 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
case 'ddc':
// TODO(jakemac):If `generateKernel` changes to return a summary
// component, process the component instead.
target = new DevCompilerSummaryTarget(sources, excludeNonSources);
target = new DevCompilerSummaryTarget(sources, excludeNonSources,
trackWidgetCreation: trackKernelCreation);
if (!summaryOnly) {
out.writeln('error: --no-summary-only not supported for the '
'ddc target');
@ -296,8 +292,6 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
incrementalComponent.problemsAsJson = null;
incrementalComponent.mainMethod = null;
target.performOutlineTransformations(incrementalComponent);
} else if (trackKernelCreation) {
(new WidgetCreatorTracker()).transform(incrementalComponent);
}
return Future.value(fe.serializeComponent(incrementalComponent));
@ -307,10 +301,6 @@ Future<ComputeKernelResult> computeKernel(List<String> args,
} else {
Component component =
await fe.compileComponent(state, sources, onDiagnostic);
if (trackKernelCreation) {
(new WidgetCreatorTracker()).transform(component);
}
kernel = fe.serializeComponent(component,
filter: (library) => sources.contains(library.importUri));
}
@ -342,7 +332,9 @@ class DevCompilerSummaryTarget extends DevCompilerTarget {
final List<Uri> sources;
final bool excludeNonSources;
DevCompilerSummaryTarget(this.sources, this.excludeNonSources);
DevCompilerSummaryTarget(this.sources, this.excludeNonSources,
{trackWidgetCreation = false})
: super(trackWidgetCreation: trackWidgetCreation);
@override
void performOutlineTransformations(Component component) {