mirror of
https://github.com/dart-lang/sdk
synced 2024-10-02 23:24:42 +00:00
[dart2js] Remove obsolete flags.
Removes 'new-deferred-split', 'no-new-deferred-split', 'report-invalid-deferred-types', 'defer-class-types', and 'no-defer-class-types'. Change-Id: I8d7dd4500c776b2016697bf6c7342846041cc9fd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164040 Commit-Queue: Joshua Litt <joshualitt@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
parent
f9e6e38b21
commit
f767363767
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
### Dart2JS
|
### Dart2JS
|
||||||
|
|
||||||
|
* Removed `--no-defer-class-types` and `--no-new-deferred-split'.
|
||||||
|
|
||||||
### Tools
|
### Tools
|
||||||
|
|
||||||
#### Dartanalyzer
|
#### Dartanalyzer
|
||||||
|
|
|
@ -113,13 +113,6 @@ class Flags {
|
||||||
static const String soundNullSafety = '--sound-null-safety';
|
static const String soundNullSafety = '--sound-null-safety';
|
||||||
static const String noSoundNullSafety = '--no-sound-null-safety';
|
static const String noSoundNullSafety = '--no-sound-null-safety';
|
||||||
|
|
||||||
static const String newDeferredSplit = '--new-deferred-split';
|
|
||||||
static const String noNewDeferredSplit = '--no-new-deferred-split';
|
|
||||||
static const String reportInvalidInferredDeferredTypes =
|
|
||||||
'--report-invalid-deferred-types';
|
|
||||||
static const String deferClassTypes = '--defer-class-types';
|
|
||||||
static const String noDeferClassTypes = '--no-defer-class-types';
|
|
||||||
|
|
||||||
/// Flag for a combination of flags for 'production' mode.
|
/// Flag for a combination of flags for 'production' mode.
|
||||||
static const String benchmarkingProduction = '--benchmarking-production';
|
static const String benchmarkingProduction = '--benchmarking-production';
|
||||||
|
|
||||||
|
|
|
@ -468,10 +468,6 @@ Future<api.CompilationResult> compile(List<String> argv,
|
||||||
new OptionHandler(Flags.disableRtiOptimization, passThrough),
|
new OptionHandler(Flags.disableRtiOptimization, passThrough),
|
||||||
new OptionHandler(Flags.terse, passThrough),
|
new OptionHandler(Flags.terse, passThrough),
|
||||||
new OptionHandler('--deferred-map=.+', passThrough),
|
new OptionHandler('--deferred-map=.+', passThrough),
|
||||||
new OptionHandler(Flags.newDeferredSplit, passThrough),
|
|
||||||
new OptionHandler(Flags.reportInvalidInferredDeferredTypes, passThrough),
|
|
||||||
new OptionHandler(Flags.deferClassTypes, passThrough),
|
|
||||||
new OptionHandler(Flags.noDeferClassTypes, passThrough),
|
|
||||||
new OptionHandler('${Flags.dumpInfo}|${Flags.dumpInfo}=.+', setDumpInfo),
|
new OptionHandler('${Flags.dumpInfo}|${Flags.dumpInfo}=.+', setDumpInfo),
|
||||||
new OptionHandler('--disallow-unsafe-eval', ignoreOption),
|
new OptionHandler('--disallow-unsafe-eval', ignoreOption),
|
||||||
new OptionHandler(Option.showPackageWarnings, passThrough),
|
new OptionHandler(Option.showPackageWarnings, passThrough),
|
||||||
|
|
|
@ -7,6 +7,8 @@ library deferred_load;
|
||||||
import 'dart:collection' show Queue;
|
import 'dart:collection' show Queue;
|
||||||
|
|
||||||
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
|
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
|
||||||
|
import 'package:kernel/ast.dart' as ir;
|
||||||
|
import 'package:kernel/type_environment.dart' as ir;
|
||||||
|
|
||||||
import 'common/metrics.dart' show Metric, Metrics, CountMetric, DurationMetric;
|
import 'common/metrics.dart' show Metric, Metrics, CountMetric, DurationMetric;
|
||||||
import 'common/tasks.dart' show CompilerTask;
|
import 'common/tasks.dart' show CompilerTask;
|
||||||
|
@ -18,12 +20,13 @@ import 'constants/values.dart'
|
||||||
show
|
show
|
||||||
ConstantValue,
|
ConstantValue,
|
||||||
ConstructedConstantValue,
|
ConstructedConstantValue,
|
||||||
TypeConstantValue,
|
|
||||||
DeferredGlobalConstantValue,
|
DeferredGlobalConstantValue,
|
||||||
InstantiationConstantValue;
|
InstantiationConstantValue;
|
||||||
import 'elements/types.dart';
|
import 'elements/types.dart';
|
||||||
import 'elements/entities.dart';
|
import 'elements/entities.dart';
|
||||||
|
import 'ir/util.dart';
|
||||||
import 'kernel/kelements.dart' show KLocalFunction;
|
import 'kernel/kelements.dart' show KLocalFunction;
|
||||||
|
import 'kernel/element_map.dart';
|
||||||
import 'serialization/serialization.dart';
|
import 'serialization/serialization.dart';
|
||||||
import 'options.dart';
|
import 'options.dart';
|
||||||
import 'universe/use.dart';
|
import 'universe/use.dart';
|
||||||
|
@ -102,7 +105,7 @@ class _DeferredLoadTaskMetrics implements Metrics {
|
||||||
/// For each deferred import, find elements and constants to be loaded when that
|
/// For each deferred import, find elements and constants to be loaded when that
|
||||||
/// import is loaded. Elements that are used by several deferred imports are in
|
/// import is loaded. Elements that are used by several deferred imports are in
|
||||||
/// shared OutputUnits.
|
/// shared OutputUnits.
|
||||||
abstract class DeferredLoadTask extends CompilerTask {
|
class DeferredLoadTask extends CompilerTask {
|
||||||
@override
|
@override
|
||||||
String get name => 'Deferred Loading';
|
String get name => 'Deferred Loading';
|
||||||
|
|
||||||
|
@ -149,17 +152,15 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
|
|
||||||
final Compiler compiler;
|
final Compiler compiler;
|
||||||
|
|
||||||
|
KernelToElementMap _elementMap;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final _DeferredLoadTaskMetrics metrics = _DeferredLoadTaskMetrics();
|
final _DeferredLoadTaskMetrics metrics = _DeferredLoadTaskMetrics();
|
||||||
|
|
||||||
bool get disableProgramSplit => compiler.options.disableProgramSplit;
|
bool get disableProgramSplit => compiler.options.disableProgramSplit;
|
||||||
bool get newDeferredSplit => compiler.options.newDeferredSplit;
|
|
||||||
bool get reportInvalidInferredDeferredTypes =>
|
|
||||||
compiler.options.reportInvalidInferredDeferredTypes;
|
|
||||||
bool get deferClassTypes => compiler.options.deferClassTypes;
|
|
||||||
|
|
||||||
DeferredLoadTask(this.compiler) : super(compiler.measurer) {
|
DeferredLoadTask(this.compiler, this._elementMap) : super(compiler.measurer) {
|
||||||
_mainOutputUnit = OutputUnit(true, 'main', <ImportEntity>{});
|
_mainOutputUnit = OutputUnit(true, 'main', {});
|
||||||
importSets.mainSet.unit = _mainOutputUnit;
|
importSets.mainSet.unit = _mainOutputUnit;
|
||||||
_allOutputUnits.add(_mainOutputUnit);
|
_allOutputUnits.add(_mainOutputUnit);
|
||||||
}
|
}
|
||||||
|
@ -172,27 +173,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
|
|
||||||
DiagnosticReporter get reporter => compiler.reporter;
|
DiagnosticReporter get reporter => compiler.reporter;
|
||||||
|
|
||||||
/// Given [imports] that refer to an element from a library, determine whether
|
|
||||||
/// the element is explicitly deferred.
|
|
||||||
static bool _isExplicitlyDeferred(Iterable<ImportEntity> imports) {
|
|
||||||
// If the element is not imported explicitly, it is implicitly imported
|
|
||||||
// not deferred.
|
|
||||||
if (imports.isEmpty) return false;
|
|
||||||
// An element could potentially be loaded by several imports. If all of them
|
|
||||||
// is explicitly deferred, we say the element is explicitly deferred.
|
|
||||||
// TODO(sigurdm): We might want to give a warning if the imports do not
|
|
||||||
// agree.
|
|
||||||
return imports.every((ImportEntity import) => import.isDeferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns every [ImportEntity] that imports [element] into [library].
|
|
||||||
Iterable<ImportEntity> classImportsTo(
|
|
||||||
ClassEntity element, LibraryEntity library);
|
|
||||||
|
|
||||||
/// Returns every [ImportEntity] that imports [element] into [library].
|
|
||||||
Iterable<ImportEntity> memberImportsTo(
|
|
||||||
MemberEntity element, LibraryEntity library);
|
|
||||||
|
|
||||||
/// Collects all direct dependencies of [element].
|
/// Collects all direct dependencies of [element].
|
||||||
///
|
///
|
||||||
/// The collected dependent elements and constants are are added to
|
/// The collected dependent elements and constants are are added to
|
||||||
|
@ -275,30 +255,37 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
// they are processed as part of the class.
|
// they are processed as part of the class.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the set of constants that are used in annotations of [element].
|
|
||||||
///
|
|
||||||
/// If the underlying system doesn't support mirrors, then no constants are
|
|
||||||
/// added.
|
|
||||||
void collectConstantsFromMetadata(
|
|
||||||
Entity element, Set<ConstantValue> constants);
|
|
||||||
|
|
||||||
/// Extract the set of constants that are used in the body of [element].
|
/// Extract the set of constants that are used in the body of [element].
|
||||||
void collectConstantsInBody(MemberEntity element, Dependencies dependencies);
|
void collectConstantsInBody(MemberEntity element, Dependencies dependencies) {
|
||||||
|
ir.Member node = _elementMap.getMemberNode(element);
|
||||||
|
|
||||||
|
// Fetch the internal node in order to skip annotations on the member.
|
||||||
|
// TODO(sigmund): replace this pattern when the kernel-ast provides a better
|
||||||
|
// way to skip annotations (issue 31565).
|
||||||
|
var visitor = new ConstantCollector(
|
||||||
|
_elementMap, _elementMap.getStaticTypeContext(element), dependencies);
|
||||||
|
if (node is ir.Field) {
|
||||||
|
node.initializer?.accept(visitor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node is ir.Constructor) {
|
||||||
|
node.initializers.forEach((i) => i.accept(visitor));
|
||||||
|
}
|
||||||
|
node.function?.accept(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
/// Recursively collects all the dependencies of [type].
|
/// Recursively collects all the dependencies of [type].
|
||||||
void _collectTypeDependencies(DartType type, Dependencies dependencies,
|
void _collectTypeDependencies(DartType type, Dependencies dependencies,
|
||||||
[ImportEntity import]) {
|
[ImportEntity import]) {
|
||||||
TypeDependencyVisitor(dependencies, import, commonElements,
|
TypeDependencyVisitor(dependencies, import, commonElements).visit(type);
|
||||||
collectClassesAndTypes: !deferClassTypes)
|
|
||||||
.visit(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _collectTypeArgumentDependencies(
|
void _collectTypeArgumentDependencies(
|
||||||
Iterable<DartType> typeArguments, Dependencies dependencies,
|
Iterable<DartType> typeArguments, Dependencies dependencies,
|
||||||
[ImportEntity import]) {
|
[ImportEntity import]) {
|
||||||
if (typeArguments == null) return;
|
if (typeArguments == null) return;
|
||||||
TypeDependencyVisitor(dependencies, import, commonElements,
|
TypeDependencyVisitor(dependencies, import, commonElements)
|
||||||
collectClassesAndTypes: !deferClassTypes)
|
|
||||||
.visitList(typeArguments);
|
.visitList(typeArguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,62 +587,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
/// same nodes we have already seen.
|
/// same nodes we have already seen.
|
||||||
_shouldAddDeferredDependency(ImportSet newSet) => newSet.length <= 1;
|
_shouldAddDeferredDependency(ImportSet newSet) => newSet.length <= 1;
|
||||||
|
|
||||||
void _fixDependencyInfo(DependencyInfo info, List<ImportEntity> imports,
|
|
||||||
String prefix, String name, Spannable context) {
|
|
||||||
var isDeferred = _isExplicitlyDeferred(imports);
|
|
||||||
if (isDeferred) {
|
|
||||||
if (!newDeferredSplit) {
|
|
||||||
info.isDeferred = true;
|
|
||||||
info.imports = imports;
|
|
||||||
}
|
|
||||||
if (reportInvalidInferredDeferredTypes) {
|
|
||||||
reporter.reportErrorMessage(context, MessageKind.GENERIC, {
|
|
||||||
'text': "$prefix '$name' is deferred but appears to be inferred as"
|
|
||||||
" a return type or a type parameter (dartbug.com/35311)."
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following 3 methods are used to check whether the new deferred split
|
|
||||||
// algorithm and the old one match. Because of a soundness bug in the old
|
|
||||||
// algorithm the new algorithm can pull in a lot of code to the main output
|
|
||||||
// unit. This logic detects it and will make it easier for us to migrate code
|
|
||||||
// off it incrementally.
|
|
||||||
// Note: we only expect discrepancies on class-dependency-info due to how
|
|
||||||
// inferred types expose deferred types in type-variables and return types
|
|
||||||
// (Issue #35311). We added the other two methods to test our transition, but
|
|
||||||
// we don't expect to detect any mismatches there.
|
|
||||||
//
|
|
||||||
// TODO(sigmund): delete once the new implementation is on by default.
|
|
||||||
void _fixClassDependencyInfo(DependencyInfo info, ClassEntity cls,
|
|
||||||
LibraryEntity library, Spannable context) {
|
|
||||||
if (info.isDeferred) return;
|
|
||||||
if (newDeferredSplit && !reportInvalidInferredDeferredTypes) return;
|
|
||||||
var imports = classImportsTo(cls, library);
|
|
||||||
_fixDependencyInfo(info, imports, "Class", cls.name, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _fixMemberDependencyInfo(DependencyInfo info, MemberEntity member,
|
|
||||||
LibraryEntity library, Spannable context) {
|
|
||||||
if (info.isDeferred || compiler.options.newDeferredSplit) return;
|
|
||||||
var imports = memberImportsTo(member, library);
|
|
||||||
_fixDependencyInfo(info, imports, "Member", member.name, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _fixConstantDependencyInfo(DependencyInfo info, ConstantValue constant,
|
|
||||||
LibraryEntity library, Spannable context) {
|
|
||||||
if (info.isDeferred || compiler.options.newDeferredSplit) return;
|
|
||||||
if (constant is TypeConstantValue) {
|
|
||||||
var type = constant.representedType.withoutNullability;
|
|
||||||
if (type is InterfaceType) {
|
|
||||||
var imports = classImportsTo(type.element, library);
|
|
||||||
_fixDependencyInfo(
|
|
||||||
info, imports, "Class (in constant) ", type.element.name, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _processDependencies(
|
void _processDependencies(
|
||||||
KClosedWorld closedWorld,
|
KClosedWorld closedWorld,
|
||||||
LibraryEntity library,
|
LibraryEntity library,
|
||||||
|
@ -665,7 +596,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
WorkQueue queue,
|
WorkQueue queue,
|
||||||
Spannable context) {
|
Spannable context) {
|
||||||
dependencies.classes.forEach((ClassEntity cls, DependencyInfo info) {
|
dependencies.classes.forEach((ClassEntity cls, DependencyInfo info) {
|
||||||
_fixClassDependencyInfo(info, cls, library, context);
|
|
||||||
if (info.isDeferred) {
|
if (info.isDeferred) {
|
||||||
if (_shouldAddDeferredDependency(newSet)) {
|
if (_shouldAddDeferredDependency(newSet)) {
|
||||||
for (ImportEntity deferredImport in info.imports) {
|
for (ImportEntity deferredImport in info.imports) {
|
||||||
|
@ -678,7 +608,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
});
|
});
|
||||||
|
|
||||||
dependencies.classType.forEach((ClassEntity cls, DependencyInfo info) {
|
dependencies.classType.forEach((ClassEntity cls, DependencyInfo info) {
|
||||||
_fixClassDependencyInfo(info, cls, library, context);
|
|
||||||
if (info.isDeferred) {
|
if (info.isDeferred) {
|
||||||
if (_shouldAddDeferredDependency(newSet)) {
|
if (_shouldAddDeferredDependency(newSet)) {
|
||||||
for (ImportEntity deferredImport in info.imports) {
|
for (ImportEntity deferredImport in info.imports) {
|
||||||
|
@ -691,7 +620,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
});
|
});
|
||||||
|
|
||||||
dependencies.members.forEach((MemberEntity member, DependencyInfo info) {
|
dependencies.members.forEach((MemberEntity member, DependencyInfo info) {
|
||||||
_fixMemberDependencyInfo(info, member, library, context);
|
|
||||||
if (info.isDeferred) {
|
if (info.isDeferred) {
|
||||||
if (_shouldAddDeferredDependency(newSet)) {
|
if (_shouldAddDeferredDependency(newSet)) {
|
||||||
for (ImportEntity deferredImport in info.imports) {
|
for (ImportEntity deferredImport in info.imports) {
|
||||||
|
@ -709,7 +637,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
|
|
||||||
dependencies.constants
|
dependencies.constants
|
||||||
.forEach((ConstantValue constant, DependencyInfo info) {
|
.forEach((ConstantValue constant, DependencyInfo info) {
|
||||||
_fixConstantDependencyInfo(info, constant, library, context);
|
|
||||||
if (info.isDeferred) {
|
if (info.isDeferred) {
|
||||||
if (_shouldAddDeferredDependency(newSet)) {
|
if (_shouldAddDeferredDependency(newSet)) {
|
||||||
for (ImportEntity deferredImport in info.imports) {
|
for (ImportEntity deferredImport in info.imports) {
|
||||||
|
@ -948,10 +875,8 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
_localFunctionToSet = null;
|
_localFunctionToSet = null;
|
||||||
_constantToSet = null;
|
_constantToSet = null;
|
||||||
importSets = null;
|
importSets = null;
|
||||||
cleanup();
|
|
||||||
return OutputUnitData(
|
return OutputUnitData(
|
||||||
this.isProgramSplit && !disableProgramSplit,
|
this.isProgramSplit && !disableProgramSplit,
|
||||||
deferClassTypes,
|
|
||||||
this._mainOutputUnit,
|
this._mainOutputUnit,
|
||||||
classMap,
|
classMap,
|
||||||
classTypeMap,
|
classTypeMap,
|
||||||
|
@ -964,15 +889,11 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
_deferredImportDescriptions);
|
_deferredImportDescriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Frees up strategy-specific temporary data.
|
|
||||||
void cleanup() {}
|
|
||||||
|
|
||||||
void beforeResolution(Uri rootLibraryUri, Iterable<Uri> libraries) {
|
void beforeResolution(Uri rootLibraryUri, Iterable<Uri> libraries) {
|
||||||
measureSubtask('prepare', () {
|
measureSubtask('prepare', () {
|
||||||
for (Uri uri in libraries) {
|
for (Uri uri in libraries) {
|
||||||
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
|
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
|
||||||
reporter.withCurrentElement(library, () {
|
reporter.withCurrentElement(library, () {
|
||||||
checkForDeferredErrorCases(library);
|
|
||||||
for (ImportEntity import in elementEnvironment.getImports(library)) {
|
for (ImportEntity import in elementEnvironment.getImports(library)) {
|
||||||
if (import.isDeferred) {
|
if (import.isDeferred) {
|
||||||
_deferredImportDescriptions[import] =
|
_deferredImportDescriptions[import] =
|
||||||
|
@ -985,13 +906,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detects errors like duplicate uses of a prefix or using the old deferred
|
|
||||||
/// loading syntax.
|
|
||||||
///
|
|
||||||
/// These checks are already done by the shared front-end, so they can be
|
|
||||||
/// skipped by the new compiler pipeline.
|
|
||||||
void checkForDeferredErrorCases(LibraryEntity library);
|
|
||||||
|
|
||||||
bool ignoreEntityInDump(Entity element) => false;
|
bool ignoreEntityInDump(Entity element) => false;
|
||||||
|
|
||||||
/// Creates a textual representation of the output unit content.
|
/// Creates a textual representation of the output unit content.
|
||||||
|
@ -1014,7 +928,7 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
});
|
});
|
||||||
_memberToSet.forEach((MemberEntity element, ImportSet importSet) {
|
_memberToSet.forEach((MemberEntity element, ImportSet importSet) {
|
||||||
if (ignoreEntityInDump(element)) return;
|
if (ignoreEntityInDump(element)) return;
|
||||||
var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
|
var elements = elementMap.putIfAbsent(importSet.unit, () => []);
|
||||||
var id = element.name ?? '$element';
|
var id = element.name ?? '$element';
|
||||||
var cls = element.enclosingClass?.name;
|
var cls = element.enclosingClass?.name;
|
||||||
if (cls != null) id = '$cls.$id';
|
if (cls != null) id = '$cls.$id';
|
||||||
|
@ -1024,7 +938,7 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
});
|
});
|
||||||
_localFunctionToSet.forEach((Local element, ImportSet importSet) {
|
_localFunctionToSet.forEach((Local element, ImportSet importSet) {
|
||||||
if (ignoreEntityInDump(element)) return;
|
if (ignoreEntityInDump(element)) return;
|
||||||
var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
|
var elements = elementMap.putIfAbsent(importSet.unit, () => []);
|
||||||
var id = element.name ?? '$element';
|
var id = element.name ?? '$element';
|
||||||
var context = (element as dynamic).memberContext.name;
|
var context = (element as dynamic).memberContext.name;
|
||||||
id = element.name == null || element.name == '' ? '<anonymous>' : id;
|
id = element.name == null || element.name == '' ? '<anonymous>' : id;
|
||||||
|
@ -1037,7 +951,7 @@ abstract class DeferredLoadTask extends CompilerTask {
|
||||||
// if they are shared, they end up duplicated anyways across output units.
|
// if they are shared, they end up duplicated anyways across output units.
|
||||||
if (value.isPrimitive) return;
|
if (value.isPrimitive) return;
|
||||||
constantMap
|
constantMap
|
||||||
.putIfAbsent(importSet.unit, () => <String>[])
|
.putIfAbsent(importSet.unit, () => [])
|
||||||
.add(value.toStructuredText(dartTypes));
|
.add(value.toStructuredText(dartTypes));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1464,7 +1378,6 @@ class OutputUnitData {
|
||||||
static const String tag = 'output-unit-data';
|
static const String tag = 'output-unit-data';
|
||||||
|
|
||||||
final bool isProgramSplit;
|
final bool isProgramSplit;
|
||||||
final bool deferClassTypes;
|
|
||||||
final OutputUnit mainOutputUnit;
|
final OutputUnit mainOutputUnit;
|
||||||
final Map<ClassEntity, OutputUnit> _classToUnit;
|
final Map<ClassEntity, OutputUnit> _classToUnit;
|
||||||
final Map<ClassEntity, OutputUnit> _classTypeToUnit;
|
final Map<ClassEntity, OutputUnit> _classTypeToUnit;
|
||||||
|
@ -1489,7 +1402,6 @@ class OutputUnitData {
|
||||||
|
|
||||||
OutputUnitData(
|
OutputUnitData(
|
||||||
this.isProgramSplit,
|
this.isProgramSplit,
|
||||||
this.deferClassTypes,
|
|
||||||
this.mainOutputUnit,
|
this.mainOutputUnit,
|
||||||
this._classToUnit,
|
this._classToUnit,
|
||||||
this._classTypeToUnit,
|
this._classTypeToUnit,
|
||||||
|
@ -1532,13 +1444,12 @@ class OutputUnitData {
|
||||||
|
|
||||||
return OutputUnitData(
|
return OutputUnitData(
|
||||||
other.isProgramSplit,
|
other.isProgramSplit,
|
||||||
other.deferClassTypes,
|
|
||||||
other.mainOutputUnit,
|
other.mainOutputUnit,
|
||||||
classToUnit,
|
classToUnit,
|
||||||
classTypeToUnit,
|
classTypeToUnit,
|
||||||
memberToUnit,
|
memberToUnit,
|
||||||
// Local functions only make sense in the K-world model.
|
// Local functions only make sense in the K-world model.
|
||||||
const <Local, OutputUnit>{},
|
const {},
|
||||||
constantToUnit,
|
constantToUnit,
|
||||||
other.outputUnits,
|
other.outputUnits,
|
||||||
other._importDeferName,
|
other._importDeferName,
|
||||||
|
@ -1550,7 +1461,6 @@ class OutputUnitData {
|
||||||
factory OutputUnitData.readFromDataSource(DataSource source) {
|
factory OutputUnitData.readFromDataSource(DataSource source) {
|
||||||
source.begin(tag);
|
source.begin(tag);
|
||||||
bool isProgramSplit = source.readBool();
|
bool isProgramSplit = source.readBool();
|
||||||
bool deferClassTypes = source.readBool();
|
|
||||||
List<OutputUnit> outputUnits = source.readList(() {
|
List<OutputUnit> outputUnits = source.readList(() {
|
||||||
bool isMainOutput = source.readBool();
|
bool isMainOutput = source.readBool();
|
||||||
String name = source.readString();
|
String name = source.readString();
|
||||||
|
@ -1589,13 +1499,12 @@ class OutputUnitData {
|
||||||
source.end(tag);
|
source.end(tag);
|
||||||
return OutputUnitData(
|
return OutputUnitData(
|
||||||
isProgramSplit,
|
isProgramSplit,
|
||||||
deferClassTypes,
|
|
||||||
mainOutputUnit,
|
mainOutputUnit,
|
||||||
classToUnit,
|
classToUnit,
|
||||||
classTypeToUnit,
|
classTypeToUnit,
|
||||||
memberToUnit,
|
memberToUnit,
|
||||||
// Local functions only make sense in the K-world model.
|
// Local functions only make sense in the K-world model.
|
||||||
const <Local, OutputUnit>{},
|
const {},
|
||||||
constantToUnit,
|
constantToUnit,
|
||||||
outputUnits,
|
outputUnits,
|
||||||
importDeferName,
|
importDeferName,
|
||||||
|
@ -1607,7 +1516,6 @@ class OutputUnitData {
|
||||||
void writeToDataSink(DataSink sink) {
|
void writeToDataSink(DataSink sink) {
|
||||||
sink.begin(tag);
|
sink.begin(tag);
|
||||||
sink.writeBool(isProgramSplit);
|
sink.writeBool(isProgramSplit);
|
||||||
sink.writeBool(deferClassTypes);
|
|
||||||
Map<OutputUnit, int> outputUnitIndices = {};
|
Map<OutputUnit, int> outputUnitIndices = {};
|
||||||
sink.writeList(outputUnits, (OutputUnit outputUnit) {
|
sink.writeList(outputUnits, (OutputUnit outputUnit) {
|
||||||
outputUnitIndices[outputUnit] = outputUnitIndices.length;
|
outputUnitIndices[outputUnit] = outputUnitIndices.length;
|
||||||
|
@ -1661,18 +1569,13 @@ class OutputUnitData {
|
||||||
// TODO(joshualitt): see above TODO regarding allowNull.
|
// TODO(joshualitt): see above TODO regarding allowNull.
|
||||||
OutputUnit outputUnitForClassType(ClassEntity cls, {bool allowNull: false}) {
|
OutputUnit outputUnitForClassType(ClassEntity cls, {bool allowNull: false}) {
|
||||||
if (!isProgramSplit) return mainOutputUnit;
|
if (!isProgramSplit) return mainOutputUnit;
|
||||||
OutputUnit unit;
|
OutputUnit unit = _classTypeToUnit[cls];
|
||||||
if (deferClassTypes) {
|
|
||||||
unit = _classTypeToUnit[cls];
|
|
||||||
} else {
|
|
||||||
unit = _classToUnit[cls];
|
|
||||||
}
|
|
||||||
assert(allowNull || unit != null, 'No output unit for type $cls');
|
assert(allowNull || unit != null, 'No output unit for type $cls');
|
||||||
return unit ?? mainOutputUnit;
|
return unit ?? mainOutputUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputUnit outputUnitForClassTypeForTesting(ClassEntity cls) =>
|
OutputUnit outputUnitForClassTypeForTesting(ClassEntity cls) =>
|
||||||
deferClassTypes ? _classTypeToUnit[cls] : _classToUnit[cls];
|
_classTypeToUnit[cls];
|
||||||
|
|
||||||
/// Returns the [OutputUnit] where [member] belongs.
|
/// Returns the [OutputUnit] where [member] belongs.
|
||||||
OutputUnit outputUnitForMember(MemberEntity member) {
|
OutputUnit outputUnitForMember(MemberEntity member) {
|
||||||
|
@ -1801,10 +1704,8 @@ class OutputUnitData {
|
||||||
|
|
||||||
Map<String, dynamic> libraryMap = mapping.putIfAbsent(
|
Map<String, dynamic> libraryMap = mapping.putIfAbsent(
|
||||||
description.importingUri,
|
description.importingUri,
|
||||||
() => <String, dynamic>{
|
() =>
|
||||||
"name": getName(description._importingLibrary),
|
{"name": getName(description._importingLibrary), "imports": {}});
|
||||||
"imports": <String, List<String>>{}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<String> partFileNames = outputUnits
|
List<String> partFileNames = outputUnits
|
||||||
.where((outputUnit) => !omittedUnits.contains(outputUnit))
|
.where((outputUnit) => !omittedUnits.contains(outputUnit))
|
||||||
|
@ -1874,16 +1775,11 @@ class DependencyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
||||||
// If true, collect classes and types, otherwise just collect types.
|
|
||||||
// Note: When collecting classes, types are added implicitly by the
|
|
||||||
// dependencies class.
|
|
||||||
final bool collectClassesAndTypes;
|
|
||||||
final Dependencies _dependencies;
|
final Dependencies _dependencies;
|
||||||
final ImportEntity _import;
|
final ImportEntity _import;
|
||||||
final CommonElements _commonElements;
|
final CommonElements _commonElements;
|
||||||
|
|
||||||
TypeDependencyVisitor(this._dependencies, this._import, this._commonElements,
|
TypeDependencyVisitor(this._dependencies, this._import, this._commonElements);
|
||||||
{this.collectClassesAndTypes});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visit(DartType type, [_]) {
|
void visit(DartType type, [_]) {
|
||||||
|
@ -1906,11 +1802,7 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitFutureOrType(FutureOrType type, Null argument) {
|
void visitFutureOrType(FutureOrType type, Null argument) {
|
||||||
if (collectClassesAndTypes) {
|
_dependencies.addClassType(_commonElements.futureClass);
|
||||||
_dependencies.addClass(_commonElements.futureClass);
|
|
||||||
} else {
|
|
||||||
_dependencies.addClassType(_commonElements.futureClass);
|
|
||||||
}
|
|
||||||
visit(type.typeArgument);
|
visit(type.typeArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1937,11 +1829,7 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
||||||
@override
|
@override
|
||||||
void visitInterfaceType(InterfaceType type, Null argument) {
|
void visitInterfaceType(InterfaceType type, Null argument) {
|
||||||
visitList(type.typeArguments);
|
visitList(type.typeArguments);
|
||||||
if (collectClassesAndTypes) {
|
_dependencies.addClassType(type.element, _import);
|
||||||
_dependencies.addClass(type.element, _import);
|
|
||||||
} else {
|
|
||||||
_dependencies.addClassType(type.element, _import);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1970,3 +1858,108 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
||||||
// Nothing to add.
|
// Nothing to add.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ConstantCollector extends ir.RecursiveVisitor {
|
||||||
|
final KernelToElementMap elementMap;
|
||||||
|
final Dependencies dependencies;
|
||||||
|
final ir.StaticTypeContext staticTypeContext;
|
||||||
|
|
||||||
|
ConstantCollector(this.elementMap, this.staticTypeContext, this.dependencies);
|
||||||
|
|
||||||
|
CommonElements get commonElements => elementMap.commonElements;
|
||||||
|
|
||||||
|
void add(ir.Expression node, {bool required: true}) {
|
||||||
|
ConstantValue constant = elementMap
|
||||||
|
.getConstantValue(staticTypeContext, node, requireConstant: required);
|
||||||
|
if (constant != null) {
|
||||||
|
dependencies.addConstant(
|
||||||
|
constant, elementMap.getImport(getDeferredImport(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitIntLiteral(ir.IntLiteral literal) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitDoubleLiteral(ir.DoubleLiteral literal) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitBoolLiteral(ir.BoolLiteral literal) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitStringLiteral(ir.StringLiteral literal) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitSymbolLiteral(ir.SymbolLiteral literal) => add(literal);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitNullLiteral(ir.NullLiteral literal) {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitListLiteral(ir.ListLiteral literal) {
|
||||||
|
if (literal.isConst) {
|
||||||
|
add(literal);
|
||||||
|
} else {
|
||||||
|
super.visitListLiteral(literal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitSetLiteral(ir.SetLiteral literal) {
|
||||||
|
if (literal.isConst) {
|
||||||
|
add(literal);
|
||||||
|
} else {
|
||||||
|
super.visitSetLiteral(literal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitMapLiteral(ir.MapLiteral literal) {
|
||||||
|
if (literal.isConst) {
|
||||||
|
add(literal);
|
||||||
|
} else {
|
||||||
|
super.visitMapLiteral(literal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitConstructorInvocation(ir.ConstructorInvocation node) {
|
||||||
|
if (node.isConst) {
|
||||||
|
add(node);
|
||||||
|
} else {
|
||||||
|
super.visitConstructorInvocation(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitTypeParameter(ir.TypeParameter node) {
|
||||||
|
// We avoid visiting metadata on the type parameter declaration. The bound
|
||||||
|
// cannot hold constants so we skip that as well.
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitVariableDeclaration(ir.VariableDeclaration node) {
|
||||||
|
// We avoid visiting metadata on the parameter declaration by only visiting
|
||||||
|
// the initializer. The type cannot hold constants so can kan skip that
|
||||||
|
// as well.
|
||||||
|
node.initializer?.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitTypeLiteral(ir.TypeLiteral node) {
|
||||||
|
if (node.type is! ir.TypeParameterType) add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitInstantiation(ir.Instantiation node) {
|
||||||
|
// TODO(johnniwinther): The CFE should mark constant instantiations as
|
||||||
|
// constant.
|
||||||
|
add(node, required: false);
|
||||||
|
super.visitInstantiation(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitConstantExpression(ir.ConstantExpression node) {
|
||||||
|
add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ part of dart2js.js_emitter.program_builder;
|
||||||
///
|
///
|
||||||
/// The code for the containing (used) methods must exist in the `universe`.
|
/// The code for the containing (used) methods must exist in the `universe`.
|
||||||
class Collector {
|
class Collector {
|
||||||
final CompilerOptions _options;
|
|
||||||
final JCommonElements _commonElements;
|
final JCommonElements _commonElements;
|
||||||
final JElementEnvironment _elementEnvironment;
|
final JElementEnvironment _elementEnvironment;
|
||||||
final OutputUnitData _outputUnitData;
|
final OutputUnitData _outputUnitData;
|
||||||
|
@ -43,7 +42,6 @@ class Collector {
|
||||||
final List<ClassEntity> nativeClassesAndSubclasses = [];
|
final List<ClassEntity> nativeClassesAndSubclasses = [];
|
||||||
|
|
||||||
Collector(
|
Collector(
|
||||||
this._options,
|
|
||||||
this._commonElements,
|
this._commonElements,
|
||||||
this._elementEnvironment,
|
this._elementEnvironment,
|
||||||
this._outputUnitData,
|
this._outputUnitData,
|
||||||
|
@ -105,7 +103,7 @@ class Collector {
|
||||||
// Return the classes that are just helpers for the backend's type system.
|
// Return the classes that are just helpers for the backend's type system.
|
||||||
static Iterable<ClassEntity> getBackendTypeHelpers(
|
static Iterable<ClassEntity> getBackendTypeHelpers(
|
||||||
JCommonElements commonElements) {
|
JCommonElements commonElements) {
|
||||||
return <ClassEntity>[
|
return [
|
||||||
commonElements.jsMutableArrayClass,
|
commonElements.jsMutableArrayClass,
|
||||||
commonElements.jsFixedArrayClass,
|
commonElements.jsFixedArrayClass,
|
||||||
commonElements.jsExtendableArrayClass,
|
commonElements.jsExtendableArrayClass,
|
||||||
|
@ -137,14 +135,6 @@ class Collector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<OutputUnit, List<ClassEntity>> get _outputListsForClassType {
|
|
||||||
if (_options.deferClassTypes) {
|
|
||||||
return outputClassTypeLists;
|
|
||||||
} else {
|
|
||||||
return outputClassLists;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compute all the classes and typedefs that must be emitted.
|
/// Compute all the classes and typedefs that must be emitted.
|
||||||
void computeNeededDeclarations() {
|
void computeNeededDeclarations() {
|
||||||
Set<ClassEntity> backendTypeHelpers =
|
Set<ClassEntity> backendTypeHelpers =
|
||||||
|
@ -157,7 +147,6 @@ class Collector {
|
||||||
return !backendTypeHelpers.contains(cls) &&
|
return !backendTypeHelpers.contains(cls) &&
|
||||||
_rtiNeededClasses.contains(cls) &&
|
_rtiNeededClasses.contains(cls) &&
|
||||||
!classesOnlyNeededForRti.contains(cls) &&
|
!classesOnlyNeededForRti.contains(cls) &&
|
||||||
_options.deferClassTypes &&
|
|
||||||
_outputUnitData.outputUnitForClass(cls) !=
|
_outputUnitData.outputUnitForClass(cls) !=
|
||||||
_outputUnitData.outputUnitForClassType(cls);
|
_outputUnitData.outputUnitForClassType(cls);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +229,7 @@ class Collector {
|
||||||
// 7. Sort classes needed for type checking and then add them to their
|
// 7. Sort classes needed for type checking and then add them to their
|
||||||
// respective OutputUnits.
|
// respective OutputUnits.
|
||||||
for (ClassEntity cls in _sorter.sortClasses(neededClassTypes)) {
|
for (ClassEntity cls in _sorter.sortClasses(neededClassTypes)) {
|
||||||
_outputListsForClassType
|
outputClassTypeLists
|
||||||
.putIfAbsent(_outputUnitData.outputUnitForClassType(cls), () => [])
|
.putIfAbsent(_outputUnitData.outputUnitForClassType(cls), () => [])
|
||||||
.add(cls);
|
.add(cls);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,6 @@ class ProgramBuilder {
|
||||||
this._rtiNeededClasses,
|
this._rtiNeededClasses,
|
||||||
this._mainFunction)
|
this._mainFunction)
|
||||||
: this.collector = new Collector(
|
: this.collector = new Collector(
|
||||||
_options,
|
|
||||||
_commonElements,
|
_commonElements,
|
||||||
_elementEnvironment,
|
_elementEnvironment,
|
||||||
_outputUnitData,
|
_outputUnitData,
|
||||||
|
@ -653,16 +652,11 @@ class ProgramBuilder {
|
||||||
Class _buildClass(ClassEntity cls) {
|
Class _buildClass(ClassEntity cls) {
|
||||||
bool onlyForConstructor =
|
bool onlyForConstructor =
|
||||||
collector.classesOnlyNeededForConstructor.contains(cls);
|
collector.classesOnlyNeededForConstructor.contains(cls);
|
||||||
bool onlyForRti = _options.deferClassTypes
|
// TODO(joshualitt): Can we just emit JSInteropClasses as types?
|
||||||
? false
|
// TODO(jacobr): check whether the class has any active static fields
|
||||||
: collector.classesOnlyNeededForRti.contains(cls);
|
// if it does not we can suppress it completely.
|
||||||
|
bool onlyForRti = _nativeData.isJsInteropClass(cls);
|
||||||
bool hasRtiField = _rtiNeed.classNeedsTypeArguments(cls);
|
bool hasRtiField = _rtiNeed.classNeedsTypeArguments(cls);
|
||||||
if (_nativeData.isJsInteropClass(cls)) {
|
|
||||||
// TODO(joshualitt): Can we just emit JSInteropClasses as types?
|
|
||||||
// TODO(jacobr): check whether the class has any active static fields
|
|
||||||
// if it does not we can suppress it completely.
|
|
||||||
onlyForRti = true;
|
|
||||||
}
|
|
||||||
bool onlyForConstructorOrRti = onlyForConstructor || onlyForRti;
|
bool onlyForConstructorOrRti = onlyForConstructor || onlyForRti;
|
||||||
bool isClosureBaseClass = cls == _commonElements.closureClass;
|
bool isClosureBaseClass = cls == _commonElements.closureClass;
|
||||||
|
|
||||||
|
|
|
@ -1,217 +0,0 @@
|
||||||
// Copyright (c) 2014, 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.
|
|
||||||
|
|
||||||
library kernel.deferred_load_data;
|
|
||||||
|
|
||||||
import 'package:kernel/ast.dart' as ir;
|
|
||||||
import 'package:kernel/type_environment.dart' as ir;
|
|
||||||
|
|
||||||
import '../common_elements.dart';
|
|
||||||
import '../compiler.dart' show Compiler;
|
|
||||||
import '../constants/values.dart';
|
|
||||||
import '../deferred_load.dart';
|
|
||||||
import '../elements/entities.dart';
|
|
||||||
import '../ir/util.dart';
|
|
||||||
import 'element_map.dart';
|
|
||||||
|
|
||||||
class KernelDeferredLoadTask extends DeferredLoadTask {
|
|
||||||
KernelToElementMap _elementMap;
|
|
||||||
Map<ir.Library, Set<ir.NamedNode>> _additionalExportsSets =
|
|
||||||
<ir.Library, Set<ir.NamedNode>>{};
|
|
||||||
|
|
||||||
KernelDeferredLoadTask(Compiler compiler, this._elementMap) : super(compiler);
|
|
||||||
|
|
||||||
Iterable<ImportEntity> _findImportsTo(ir.NamedNode node, String nodeName,
|
|
||||||
ir.Library enclosingLibrary, LibraryEntity library) {
|
|
||||||
return measureSubtask('find-imports', () {
|
|
||||||
List<ImportEntity> imports = [];
|
|
||||||
ir.Library source = _elementMap.getLibraryNode(library);
|
|
||||||
if (!source.dependencies.any((d) => d.isDeferred)) return const [];
|
|
||||||
for (ir.LibraryDependency dependency in source.dependencies) {
|
|
||||||
if (dependency.isExport) continue;
|
|
||||||
if (!_isVisible(dependency.combinators, nodeName)) continue;
|
|
||||||
if (enclosingLibrary == dependency.targetLibrary ||
|
|
||||||
additionalExports(dependency.targetLibrary).contains(node)) {
|
|
||||||
imports.add(_elementMap.getImport(dependency));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return imports;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Iterable<ImportEntity> classImportsTo(
|
|
||||||
ClassEntity element, LibraryEntity library) {
|
|
||||||
ir.Class node = _elementMap.getClassNode(element);
|
|
||||||
return _findImportsTo(node, node.name, node.enclosingLibrary, library);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Iterable<ImportEntity> memberImportsTo(
|
|
||||||
Entity element, LibraryEntity library) {
|
|
||||||
ir.Member node = _elementMap.getMemberNode(element);
|
|
||||||
return _findImportsTo(
|
|
||||||
node is ir.Constructor ? node.enclosingClass : node,
|
|
||||||
node is ir.Constructor ? node.enclosingClass.name : node.name.text,
|
|
||||||
node.enclosingLibrary,
|
|
||||||
library);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void checkForDeferredErrorCases(LibraryEntity library) {
|
|
||||||
// Nothing to do. The FE checks for error cases upfront.
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void collectConstantsFromMetadata(
|
|
||||||
Entity element, Set<ConstantValue> constants) {
|
|
||||||
// Nothing to do. Kernel-pipeline doesn't support mirrors, so we don't need
|
|
||||||
// to track any constants from meta-data.
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void collectConstantsInBody(MemberEntity element, Dependencies dependencies) {
|
|
||||||
ir.Member node = _elementMap.getMemberNode(element);
|
|
||||||
|
|
||||||
// Fetch the internal node in order to skip annotations on the member.
|
|
||||||
// TODO(sigmund): replace this pattern when the kernel-ast provides a better
|
|
||||||
// way to skip annotations (issue 31565).
|
|
||||||
var visitor = new ConstantCollector(
|
|
||||||
_elementMap, _elementMap.getStaticTypeContext(element), dependencies);
|
|
||||||
if (node is ir.Field) {
|
|
||||||
node.initializer?.accept(visitor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node is ir.Constructor) {
|
|
||||||
node.initializers.forEach((i) => i.accept(visitor));
|
|
||||||
}
|
|
||||||
node.function?.accept(visitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<ir.NamedNode> additionalExports(ir.Library library) {
|
|
||||||
return _additionalExportsSets[library] ??= new Set<ir.NamedNode>.from(
|
|
||||||
library.additionalExports.map((ir.Reference ref) => ref.node));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void cleanup() {
|
|
||||||
_additionalExportsSets = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns whether [name] would be visible according to the given list of
|
|
||||||
/// show/hide [combinators].
|
|
||||||
bool _isVisible(List<ir.Combinator> combinators, String name) {
|
|
||||||
for (var c in combinators) {
|
|
||||||
if (c.isShow && !c.names.contains(name)) return false;
|
|
||||||
if (c.isHide && c.names.contains(name)) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConstantCollector extends ir.RecursiveVisitor {
|
|
||||||
final KernelToElementMap elementMap;
|
|
||||||
final Dependencies dependencies;
|
|
||||||
final ir.StaticTypeContext staticTypeContext;
|
|
||||||
|
|
||||||
ConstantCollector(this.elementMap, this.staticTypeContext, this.dependencies);
|
|
||||||
|
|
||||||
CommonElements get commonElements => elementMap.commonElements;
|
|
||||||
|
|
||||||
void add(ir.Expression node, {bool required: true}) {
|
|
||||||
ConstantValue constant = elementMap
|
|
||||||
.getConstantValue(staticTypeContext, node, requireConstant: required);
|
|
||||||
if (constant != null) {
|
|
||||||
dependencies.addConstant(
|
|
||||||
constant, elementMap.getImport(getDeferredImport(node)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitIntLiteral(ir.IntLiteral literal) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitDoubleLiteral(ir.DoubleLiteral literal) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitBoolLiteral(ir.BoolLiteral literal) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitStringLiteral(ir.StringLiteral literal) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitSymbolLiteral(ir.SymbolLiteral literal) => add(literal);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitNullLiteral(ir.NullLiteral literal) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitListLiteral(ir.ListLiteral literal) {
|
|
||||||
if (literal.isConst) {
|
|
||||||
add(literal);
|
|
||||||
} else {
|
|
||||||
super.visitListLiteral(literal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitSetLiteral(ir.SetLiteral literal) {
|
|
||||||
if (literal.isConst) {
|
|
||||||
add(literal);
|
|
||||||
} else {
|
|
||||||
super.visitSetLiteral(literal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitMapLiteral(ir.MapLiteral literal) {
|
|
||||||
if (literal.isConst) {
|
|
||||||
add(literal);
|
|
||||||
} else {
|
|
||||||
super.visitMapLiteral(literal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitConstructorInvocation(ir.ConstructorInvocation node) {
|
|
||||||
if (node.isConst) {
|
|
||||||
add(node);
|
|
||||||
} else {
|
|
||||||
super.visitConstructorInvocation(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitTypeParameter(ir.TypeParameter node) {
|
|
||||||
// We avoid visiting metadata on the type parameter declaration. The bound
|
|
||||||
// cannot hold constants so we skip that as well.
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitVariableDeclaration(ir.VariableDeclaration node) {
|
|
||||||
// We avoid visiting metadata on the parameter declaration by only visiting
|
|
||||||
// the initializer. The type cannot hold constants so can kan skip that
|
|
||||||
// as well.
|
|
||||||
node.initializer?.accept(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitTypeLiteral(ir.TypeLiteral node) {
|
|
||||||
if (node.type is! ir.TypeParameterType) add(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitInstantiation(ir.Instantiation node) {
|
|
||||||
// TODO(johnniwinther): The CFE should mark constant instantiations as
|
|
||||||
// constant.
|
|
||||||
add(node, required: false);
|
|
||||||
super.visitInstantiation(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void visitConstantExpression(ir.ConstantExpression node) {
|
|
||||||
add(node);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -45,7 +45,6 @@ import '../universe/resolution_world_builder.dart';
|
||||||
import '../universe/world_builder.dart';
|
import '../universe/world_builder.dart';
|
||||||
import '../universe/world_impact.dart';
|
import '../universe/world_impact.dart';
|
||||||
import '../util/enumset.dart';
|
import '../util/enumset.dart';
|
||||||
import 'deferred_load.dart';
|
|
||||||
import 'element_map.dart';
|
import 'element_map.dart';
|
||||||
import 'element_map_impl.dart';
|
import 'element_map_impl.dart';
|
||||||
import 'loader.dart';
|
import 'loader.dart';
|
||||||
|
@ -54,7 +53,7 @@ import 'loader.dart';
|
||||||
/// model from kernel IR nodes.
|
/// model from kernel IR nodes.
|
||||||
class KernelFrontendStrategy extends FrontendStrategy {
|
class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
|
final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
|
||||||
new NativeBasicDataBuilderImpl();
|
NativeBasicDataBuilderImpl();
|
||||||
NativeBasicData _nativeBasicData;
|
NativeBasicData _nativeBasicData;
|
||||||
CompilerOptions _options;
|
CompilerOptions _options;
|
||||||
CompilerTask _compilerTask;
|
CompilerTask _compilerTask;
|
||||||
|
@ -87,12 +86,11 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
KernelFrontendStrategy(this._compilerTask, this._options,
|
KernelFrontendStrategy(this._compilerTask, this._options,
|
||||||
DiagnosticReporter reporter, env.Environment environment) {
|
DiagnosticReporter reporter, env.Environment environment) {
|
||||||
assert(_compilerTask != null);
|
assert(_compilerTask != null);
|
||||||
_elementMap =
|
_elementMap = KernelToElementMapImpl(reporter, environment, this, _options);
|
||||||
new KernelToElementMapImpl(reporter, environment, this, _options);
|
_modularStrategy = KernelModularStrategy(_compilerTask, _elementMap);
|
||||||
_modularStrategy = new KernelModularStrategy(_compilerTask, _elementMap);
|
_backendUsageBuilder = BackendUsageBuilderImpl(this);
|
||||||
_backendUsageBuilder = new BackendUsageBuilderImpl(this);
|
noSuchMethodRegistry = NoSuchMethodRegistryImpl(
|
||||||
noSuchMethodRegistry = new NoSuchMethodRegistryImpl(
|
commonElements, KernelNoSuchMethodResolver(_elementMap));
|
||||||
commonElements, new KernelNoSuchMethodResolver(_elementMap));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeResolutionEnqueuer get nativeResolutionEnqueuerForTesting =>
|
NativeResolutionEnqueuer get nativeResolutionEnqueuerForTesting =>
|
||||||
|
@ -139,32 +137,30 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
ResolutionEnqueuer createResolutionEnqueuer(
|
ResolutionEnqueuer createResolutionEnqueuer(
|
||||||
CompilerTask task, Compiler compiler) {
|
CompilerTask task, Compiler compiler) {
|
||||||
RuntimeTypesNeedBuilder rtiNeedBuilder = _createRuntimeTypesNeedBuilder();
|
RuntimeTypesNeedBuilder rtiNeedBuilder = _createRuntimeTypesNeedBuilder();
|
||||||
BackendImpacts impacts =
|
BackendImpacts impacts = BackendImpacts(commonElements, compiler.options);
|
||||||
new BackendImpacts(commonElements, compiler.options);
|
_nativeResolutionEnqueuer = NativeResolutionEnqueuer(
|
||||||
_nativeResolutionEnqueuer = new NativeResolutionEnqueuer(
|
|
||||||
compiler.options,
|
compiler.options,
|
||||||
elementEnvironment,
|
elementEnvironment,
|
||||||
commonElements,
|
commonElements,
|
||||||
_elementMap.types,
|
_elementMap.types,
|
||||||
new BaseNativeClassFinder(elementEnvironment, nativeBasicData));
|
BaseNativeClassFinder(elementEnvironment, nativeBasicData));
|
||||||
_nativeDataBuilder = new NativeDataBuilderImpl(nativeBasicData);
|
_nativeDataBuilder = NativeDataBuilderImpl(nativeBasicData);
|
||||||
_customElementsResolutionAnalysis = new CustomElementsResolutionAnalysis(
|
_customElementsResolutionAnalysis = CustomElementsResolutionAnalysis(
|
||||||
elementEnvironment,
|
elementEnvironment,
|
||||||
commonElements,
|
commonElements,
|
||||||
nativeBasicData,
|
nativeBasicData,
|
||||||
_backendUsageBuilder);
|
_backendUsageBuilder);
|
||||||
_fieldAnalysis = new KFieldAnalysis(this);
|
_fieldAnalysis = KFieldAnalysis(this);
|
||||||
ClassQueries classQueries = new KernelClassQueries(elementMap);
|
ClassQueries classQueries = KernelClassQueries(elementMap);
|
||||||
ClassHierarchyBuilder classHierarchyBuilder =
|
ClassHierarchyBuilder classHierarchyBuilder =
|
||||||
new ClassHierarchyBuilder(commonElements, classQueries);
|
ClassHierarchyBuilder(commonElements, classQueries);
|
||||||
AnnotationsDataBuilder annotationsDataBuilder =
|
AnnotationsDataBuilder annotationsDataBuilder = AnnotationsDataBuilder();
|
||||||
new AnnotationsDataBuilder();
|
|
||||||
// TODO(johnniwinther): This is a hack. The annotation data is built while
|
// TODO(johnniwinther): This is a hack. The annotation data is built while
|
||||||
// using it. With CFE constants the annotations data can be built fully
|
// using it. With CFE constants the annotations data can be built fully
|
||||||
// before creating the resolution enqueuer.
|
// before creating the resolution enqueuer.
|
||||||
AnnotationsData annotationsData = new AnnotationsDataImpl(
|
AnnotationsData annotationsData = AnnotationsDataImpl(
|
||||||
compiler.options, annotationsDataBuilder.pragmaAnnotations);
|
compiler.options, annotationsDataBuilder.pragmaAnnotations);
|
||||||
ImpactTransformer impactTransformer = new JavaScriptImpactTransformer(
|
ImpactTransformer impactTransformer = JavaScriptImpactTransformer(
|
||||||
elementEnvironment,
|
elementEnvironment,
|
||||||
commonElements,
|
commonElements,
|
||||||
impacts,
|
impacts,
|
||||||
|
@ -175,13 +171,12 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
rtiNeedBuilder,
|
rtiNeedBuilder,
|
||||||
classHierarchyBuilder,
|
classHierarchyBuilder,
|
||||||
annotationsData);
|
annotationsData);
|
||||||
InterceptorDataBuilder interceptorDataBuilder =
|
InterceptorDataBuilder interceptorDataBuilder = InterceptorDataBuilderImpl(
|
||||||
new InterceptorDataBuilderImpl(
|
nativeBasicData, elementEnvironment, commonElements);
|
||||||
nativeBasicData, elementEnvironment, commonElements);
|
return ResolutionEnqueuer(
|
||||||
return new ResolutionEnqueuer(
|
|
||||||
task,
|
task,
|
||||||
compiler.reporter,
|
compiler.reporter,
|
||||||
new ResolutionEnqueuerListener(
|
ResolutionEnqueuerListener(
|
||||||
compiler.options,
|
compiler.options,
|
||||||
elementEnvironment,
|
elementEnvironment,
|
||||||
commonElements,
|
commonElements,
|
||||||
|
@ -194,7 +189,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
_nativeResolutionEnqueuer,
|
_nativeResolutionEnqueuer,
|
||||||
_fieldAnalysis,
|
_fieldAnalysis,
|
||||||
compiler.deferredLoadTask),
|
compiler.deferredLoadTask),
|
||||||
new ResolutionWorldBuilderImpl(
|
ResolutionWorldBuilderImpl(
|
||||||
_options,
|
_options,
|
||||||
elementMap,
|
elementMap,
|
||||||
elementEnvironment,
|
elementEnvironment,
|
||||||
|
@ -212,7 +207,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
const StrongModeWorldStrategy(),
|
const StrongModeWorldStrategy(),
|
||||||
classHierarchyBuilder,
|
classHierarchyBuilder,
|
||||||
classQueries),
|
classQueries),
|
||||||
new KernelWorkItemBuilder(
|
KernelWorkItemBuilder(
|
||||||
_compilerTask,
|
_compilerTask,
|
||||||
elementMap,
|
elementMap,
|
||||||
nativeBasicData,
|
nativeBasicData,
|
||||||
|
@ -251,8 +246,8 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
void registerLoadedLibraries(KernelResult kernelResult) {
|
void registerLoadedLibraries(KernelResult kernelResult) {
|
||||||
_elementMap.addComponent(kernelResult.component);
|
_elementMap.addComponent(kernelResult.component);
|
||||||
_irAnnotationData = processAnnotations(
|
_irAnnotationData = processAnnotations(
|
||||||
new ModularCore(kernelResult.component, _elementMap.constantEvaluator));
|
ModularCore(kernelResult.component, _elementMap.constantEvaluator));
|
||||||
_annotationProcessor = new KernelAnnotationProcessor(
|
_annotationProcessor = KernelAnnotationProcessor(
|
||||||
elementMap, nativeBasicDataBuilder, _irAnnotationData);
|
elementMap, nativeBasicDataBuilder, _irAnnotationData);
|
||||||
for (Uri uri in kernelResult.libraries) {
|
for (Uri uri in kernelResult.libraries) {
|
||||||
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
|
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
|
||||||
|
@ -280,7 +275,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
|
DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
|
||||||
new KernelDeferredLoadTask(compiler, _elementMap);
|
DeferredLoadTask(compiler, _elementMap);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FunctionEntity computeMain(WorldImpactBuilder impactBuilder) {
|
FunctionEntity computeMain(WorldImpactBuilder impactBuilder) {
|
||||||
|
@ -290,7 +285,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
||||||
RuntimeTypesNeedBuilder _createRuntimeTypesNeedBuilder() {
|
RuntimeTypesNeedBuilder _createRuntimeTypesNeedBuilder() {
|
||||||
return _runtimeTypesNeedBuilder ??= _options.disableRtiOptimization
|
return _runtimeTypesNeedBuilder ??= _options.disableRtiOptimization
|
||||||
? const TrivialRuntimeTypesNeedBuilder()
|
? const TrivialRuntimeTypesNeedBuilder()
|
||||||
: new RuntimeTypesNeedBuilderImpl(elementEnvironment);
|
: RuntimeTypesNeedBuilderImpl(elementEnvironment);
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
|
RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
|
||||||
|
@ -326,12 +321,12 @@ class KernelWorkItemBuilder implements WorkItemBuilder {
|
||||||
this._fieldAnalysis,
|
this._fieldAnalysis,
|
||||||
this._modularStrategy,
|
this._modularStrategy,
|
||||||
this._irAnnotationData)
|
this._irAnnotationData)
|
||||||
: _nativeMemberResolver = new KernelNativeMemberResolver(
|
: _nativeMemberResolver = KernelNativeMemberResolver(
|
||||||
_elementMap, nativeBasicData, nativeDataBuilder);
|
_elementMap, nativeBasicData, nativeDataBuilder);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WorkItem createWorkItem(MemberEntity entity) {
|
WorkItem createWorkItem(MemberEntity entity) {
|
||||||
return new KernelWorkItem(
|
return KernelWorkItem(
|
||||||
_compilerTask,
|
_compilerTask,
|
||||||
_elementMap,
|
_elementMap,
|
||||||
_impactTransformer,
|
_impactTransformer,
|
||||||
|
@ -404,7 +399,7 @@ class KernelWorkItem implements WorkItem {
|
||||||
ResolutionImpact impact = _elementMap.computeWorldImpact(
|
ResolutionImpact impact = _elementMap.computeWorldImpact(
|
||||||
element,
|
element,
|
||||||
scopeModel.variableScopeModel,
|
scopeModel.variableScopeModel,
|
||||||
new Set<PragmaAnnotation>.from(
|
Set<PragmaAnnotation>.from(
|
||||||
annotations.iterable(PragmaAnnotation.values)),
|
annotations.iterable(PragmaAnnotation.values)),
|
||||||
impactBuilderData: impactBuilderData);
|
impactBuilderData: impactBuilderData);
|
||||||
WorldImpact worldImpact =
|
WorldImpact worldImpact =
|
||||||
|
@ -440,8 +435,8 @@ class KernelModularStrategy extends ModularStrategy {
|
||||||
@override
|
@override
|
||||||
ModularMemberData getModularMemberData(
|
ModularMemberData getModularMemberData(
|
||||||
ir.Member node, EnumSet<PragmaAnnotation> annotations) {
|
ir.Member node, EnumSet<PragmaAnnotation> annotations) {
|
||||||
ScopeModel scopeModel = _compilerTask.measureSubtask('closures',
|
ScopeModel scopeModel = _compilerTask.measureSubtask(
|
||||||
() => new ScopeModel.from(node, _elementMap.constantEvaluator));
|
'closures', () => ScopeModel.from(node, _elementMap.constantEvaluator));
|
||||||
ImpactBuilderData impactBuilderData;
|
ImpactBuilderData impactBuilderData;
|
||||||
if (useImpactDataForTesting) {
|
if (useImpactDataForTesting) {
|
||||||
// TODO(johnniwinther): Always create and use the [ImpactBuilderData].
|
// TODO(johnniwinther): Always create and use the [ImpactBuilderData].
|
||||||
|
@ -449,8 +444,8 @@ class KernelModularStrategy extends ModularStrategy {
|
||||||
// depend on metadata, so these parts of the impact data need to be
|
// depend on metadata, so these parts of the impact data need to be
|
||||||
// computed during conversion to [ResolutionImpact].
|
// computed during conversion to [ResolutionImpact].
|
||||||
impactBuilderData = _compilerTask.measureSubtask('worldImpact', () {
|
impactBuilderData = _compilerTask.measureSubtask('worldImpact', () {
|
||||||
ImpactBuilder builder = new ImpactBuilder(
|
ImpactBuilder builder = ImpactBuilder(
|
||||||
new ir.StaticTypeContext(node, _elementMap.typeEnvironment),
|
ir.StaticTypeContext(node, _elementMap.typeEnvironment),
|
||||||
_elementMap.classHierarchy,
|
_elementMap.classHierarchy,
|
||||||
scopeModel.variableScopeModel,
|
scopeModel.variableScopeModel,
|
||||||
useAsserts: _elementMap.options.enableUserAssertions,
|
useAsserts: _elementMap.options.enableUserAssertions,
|
||||||
|
@ -459,6 +454,6 @@ class KernelModularStrategy extends ModularStrategy {
|
||||||
return builder.computeImpact(node);
|
return builder.computeImpact(node);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return new ModularMemberData(scopeModel, impactBuilderData);
|
return ModularMemberData(scopeModel, impactBuilderData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,32 +142,6 @@ class CompilerOptions implements DiagnosticOptions {
|
||||||
/// libraries are subdivided.
|
/// libraries are subdivided.
|
||||||
Uri deferredMapUri;
|
Uri deferredMapUri;
|
||||||
|
|
||||||
/// Whether to apply the new deferred split fixes. The fixes improve on
|
|
||||||
/// performance and fix a soundness issue with inferred types. The latter will
|
|
||||||
/// move more code to the main output unit, because of that we are not
|
|
||||||
/// enabling the feature by default right away.
|
|
||||||
///
|
|
||||||
/// When [reportInvalidInferredDeferredTypes] shows no errors, we expect this
|
|
||||||
/// flag to produce the same or better results than the current unsound
|
|
||||||
/// implementation.
|
|
||||||
bool newDeferredSplit = true; // default value.
|
|
||||||
bool _newDeferredSplit = false;
|
|
||||||
bool _noNewDeferredSplit = false;
|
|
||||||
|
|
||||||
/// Show errors when a deferred type is inferred as a return type of a closure
|
|
||||||
/// or in a type parameter. Those cases cause the compiler today to behave
|
|
||||||
/// unsoundly by putting the code in a deferred output unit. In the future
|
|
||||||
/// when [newDeferredSplit] is on by default, those cases will be treated
|
|
||||||
/// soundly and will cause more code to be moved to the main output unit.
|
|
||||||
///
|
|
||||||
/// This flag is presented to help developers find and fix the affected code.
|
|
||||||
bool reportInvalidInferredDeferredTypes = false;
|
|
||||||
|
|
||||||
/// Whether to defer load class types.
|
|
||||||
bool deferClassTypes = true; // default value.
|
|
||||||
bool _deferClassTypes = false;
|
|
||||||
bool _noDeferClassTypes = false;
|
|
||||||
|
|
||||||
/// Whether to disable inlining during the backend optimizations.
|
/// Whether to disable inlining during the backend optimizations.
|
||||||
// TODO(sigmund): negate, so all flags are positive
|
// TODO(sigmund): negate, so all flags are positive
|
||||||
bool disableInlining = false;
|
bool disableInlining = false;
|
||||||
|
@ -443,12 +417,6 @@ class CompilerOptions implements DiagnosticOptions {
|
||||||
_extractStringOption(options, '--build-id=', _UNDETERMINED_BUILD_ID)
|
_extractStringOption(options, '--build-id=', _UNDETERMINED_BUILD_ID)
|
||||||
..compileForServer = _hasOption(options, Flags.serverMode)
|
..compileForServer = _hasOption(options, Flags.serverMode)
|
||||||
..deferredMapUri = _extractUriOption(options, '--deferred-map=')
|
..deferredMapUri = _extractUriOption(options, '--deferred-map=')
|
||||||
.._newDeferredSplit = _hasOption(options, Flags.newDeferredSplit)
|
|
||||||
.._noNewDeferredSplit = _hasOption(options, Flags.noNewDeferredSplit)
|
|
||||||
..reportInvalidInferredDeferredTypes =
|
|
||||||
_hasOption(options, Flags.reportInvalidInferredDeferredTypes)
|
|
||||||
.._deferClassTypes = _hasOption(options, Flags.deferClassTypes)
|
|
||||||
.._noDeferClassTypes = _hasOption(options, Flags.noDeferClassTypes)
|
|
||||||
..fatalWarnings = _hasOption(options, Flags.fatalWarnings)
|
..fatalWarnings = _hasOption(options, Flags.fatalWarnings)
|
||||||
..terseDiagnostics = _hasOption(options, Flags.terse)
|
..terseDiagnostics = _hasOption(options, Flags.terse)
|
||||||
..suppressWarnings = _hasOption(options, Flags.suppressWarnings)
|
..suppressWarnings = _hasOption(options, Flags.suppressWarnings)
|
||||||
|
@ -555,14 +523,6 @@ class CompilerOptions implements DiagnosticOptions {
|
||||||
throw ArgumentError("'${Flags.soundNullSafety}' requires the "
|
throw ArgumentError("'${Flags.soundNullSafety}' requires the "
|
||||||
"'non-nullable' experiment to be enabled");
|
"'non-nullable' experiment to be enabled");
|
||||||
}
|
}
|
||||||
if (_deferClassTypes && _noDeferClassTypes) {
|
|
||||||
throw ArgumentError("'${Flags.deferClassTypes}' incompatible with "
|
|
||||||
"'${Flags.noDeferClassTypes}'");
|
|
||||||
}
|
|
||||||
if (_newDeferredSplit && _noNewDeferredSplit) {
|
|
||||||
throw ArgumentError("'${Flags.newDeferredSplit}' incompatible with "
|
|
||||||
"'${Flags.noNewDeferredSplit}'");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void deriveOptions() {
|
void deriveOptions() {
|
||||||
|
@ -620,12 +580,6 @@ class CompilerOptions implements DiagnosticOptions {
|
||||||
if (_disableMinification) {
|
if (_disableMinification) {
|
||||||
enableMinification = false;
|
enableMinification = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_deferClassTypes) deferClassTypes = true;
|
|
||||||
if (_noDeferClassTypes) deferClassTypes = false;
|
|
||||||
|
|
||||||
if (_newDeferredSplit) newDeferredSplit = true;
|
|
||||||
if (_noNewDeferredSplit) newDeferredSplit = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if warnings and hints are shown for all packages.
|
/// Returns `true` if warnings and hints are shown for all packages.
|
||||||
|
|
Loading…
Reference in a new issue