mirror of
https://github.com/dart-lang/sdk
synced 2024-10-02 23:39:19 +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
|
||||
|
||||
* Removed `--no-defer-class-types` and `--no-new-deferred-split'.
|
||||
|
||||
### Tools
|
||||
|
||||
#### Dartanalyzer
|
||||
|
|
|
@ -113,13 +113,6 @@ class Flags {
|
|||
static const String soundNullSafety = '--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.
|
||||
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.terse, 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('--disallow-unsafe-eval', ignoreOption),
|
||||
new OptionHandler(Option.showPackageWarnings, passThrough),
|
||||
|
|
|
@ -7,6 +7,8 @@ library deferred_load;
|
|||
import 'dart:collection' show Queue;
|
||||
|
||||
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/tasks.dart' show CompilerTask;
|
||||
|
@ -18,12 +20,13 @@ import 'constants/values.dart'
|
|||
show
|
||||
ConstantValue,
|
||||
ConstructedConstantValue,
|
||||
TypeConstantValue,
|
||||
DeferredGlobalConstantValue,
|
||||
InstantiationConstantValue;
|
||||
import 'elements/types.dart';
|
||||
import 'elements/entities.dart';
|
||||
import 'ir/util.dart';
|
||||
import 'kernel/kelements.dart' show KLocalFunction;
|
||||
import 'kernel/element_map.dart';
|
||||
import 'serialization/serialization.dart';
|
||||
import 'options.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
|
||||
/// import is loaded. Elements that are used by several deferred imports are in
|
||||
/// shared OutputUnits.
|
||||
abstract class DeferredLoadTask extends CompilerTask {
|
||||
class DeferredLoadTask extends CompilerTask {
|
||||
@override
|
||||
String get name => 'Deferred Loading';
|
||||
|
||||
|
@ -149,17 +152,15 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
|
||||
final Compiler compiler;
|
||||
|
||||
KernelToElementMap _elementMap;
|
||||
|
||||
@override
|
||||
final _DeferredLoadTaskMetrics metrics = _DeferredLoadTaskMetrics();
|
||||
|
||||
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) {
|
||||
_mainOutputUnit = OutputUnit(true, 'main', <ImportEntity>{});
|
||||
DeferredLoadTask(this.compiler, this._elementMap) : super(compiler.measurer) {
|
||||
_mainOutputUnit = OutputUnit(true, 'main', {});
|
||||
importSets.mainSet.unit = _mainOutputUnit;
|
||||
_allOutputUnits.add(_mainOutputUnit);
|
||||
}
|
||||
|
@ -172,27 +173,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
|
||||
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].
|
||||
///
|
||||
/// 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.
|
||||
}
|
||||
|
||||
/// 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].
|
||||
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].
|
||||
void _collectTypeDependencies(DartType type, Dependencies dependencies,
|
||||
[ImportEntity import]) {
|
||||
TypeDependencyVisitor(dependencies, import, commonElements,
|
||||
collectClassesAndTypes: !deferClassTypes)
|
||||
.visit(type);
|
||||
TypeDependencyVisitor(dependencies, import, commonElements).visit(type);
|
||||
}
|
||||
|
||||
void _collectTypeArgumentDependencies(
|
||||
Iterable<DartType> typeArguments, Dependencies dependencies,
|
||||
[ImportEntity import]) {
|
||||
if (typeArguments == null) return;
|
||||
TypeDependencyVisitor(dependencies, import, commonElements,
|
||||
collectClassesAndTypes: !deferClassTypes)
|
||||
TypeDependencyVisitor(dependencies, import, commonElements)
|
||||
.visitList(typeArguments);
|
||||
}
|
||||
|
||||
|
@ -600,62 +587,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
/// same nodes we have already seen.
|
||||
_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(
|
||||
KClosedWorld closedWorld,
|
||||
LibraryEntity library,
|
||||
|
@ -665,7 +596,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
WorkQueue queue,
|
||||
Spannable context) {
|
||||
dependencies.classes.forEach((ClassEntity cls, DependencyInfo info) {
|
||||
_fixClassDependencyInfo(info, cls, library, context);
|
||||
if (info.isDeferred) {
|
||||
if (_shouldAddDeferredDependency(newSet)) {
|
||||
for (ImportEntity deferredImport in info.imports) {
|
||||
|
@ -678,7 +608,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
});
|
||||
|
||||
dependencies.classType.forEach((ClassEntity cls, DependencyInfo info) {
|
||||
_fixClassDependencyInfo(info, cls, library, context);
|
||||
if (info.isDeferred) {
|
||||
if (_shouldAddDeferredDependency(newSet)) {
|
||||
for (ImportEntity deferredImport in info.imports) {
|
||||
|
@ -691,7 +620,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
});
|
||||
|
||||
dependencies.members.forEach((MemberEntity member, DependencyInfo info) {
|
||||
_fixMemberDependencyInfo(info, member, library, context);
|
||||
if (info.isDeferred) {
|
||||
if (_shouldAddDeferredDependency(newSet)) {
|
||||
for (ImportEntity deferredImport in info.imports) {
|
||||
|
@ -709,7 +637,6 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
|
||||
dependencies.constants
|
||||
.forEach((ConstantValue constant, DependencyInfo info) {
|
||||
_fixConstantDependencyInfo(info, constant, library, context);
|
||||
if (info.isDeferred) {
|
||||
if (_shouldAddDeferredDependency(newSet)) {
|
||||
for (ImportEntity deferredImport in info.imports) {
|
||||
|
@ -948,10 +875,8 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
_localFunctionToSet = null;
|
||||
_constantToSet = null;
|
||||
importSets = null;
|
||||
cleanup();
|
||||
return OutputUnitData(
|
||||
this.isProgramSplit && !disableProgramSplit,
|
||||
deferClassTypes,
|
||||
this._mainOutputUnit,
|
||||
classMap,
|
||||
classTypeMap,
|
||||
|
@ -964,15 +889,11 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
_deferredImportDescriptions);
|
||||
}
|
||||
|
||||
/// Frees up strategy-specific temporary data.
|
||||
void cleanup() {}
|
||||
|
||||
void beforeResolution(Uri rootLibraryUri, Iterable<Uri> libraries) {
|
||||
measureSubtask('prepare', () {
|
||||
for (Uri uri in libraries) {
|
||||
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
|
||||
reporter.withCurrentElement(library, () {
|
||||
checkForDeferredErrorCases(library);
|
||||
for (ImportEntity import in elementEnvironment.getImports(library)) {
|
||||
if (import.isDeferred) {
|
||||
_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;
|
||||
|
||||
/// Creates a textual representation of the output unit content.
|
||||
|
@ -1014,7 +928,7 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
});
|
||||
_memberToSet.forEach((MemberEntity element, ImportSet importSet) {
|
||||
if (ignoreEntityInDump(element)) return;
|
||||
var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
|
||||
var elements = elementMap.putIfAbsent(importSet.unit, () => []);
|
||||
var id = element.name ?? '$element';
|
||||
var cls = element.enclosingClass?.name;
|
||||
if (cls != null) id = '$cls.$id';
|
||||
|
@ -1024,7 +938,7 @@ abstract class DeferredLoadTask extends CompilerTask {
|
|||
});
|
||||
_localFunctionToSet.forEach((Local element, ImportSet importSet) {
|
||||
if (ignoreEntityInDump(element)) return;
|
||||
var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
|
||||
var elements = elementMap.putIfAbsent(importSet.unit, () => []);
|
||||
var id = element.name ?? '$element';
|
||||
var context = (element as dynamic).memberContext.name;
|
||||
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 (value.isPrimitive) return;
|
||||
constantMap
|
||||
.putIfAbsent(importSet.unit, () => <String>[])
|
||||
.putIfAbsent(importSet.unit, () => [])
|
||||
.add(value.toStructuredText(dartTypes));
|
||||
});
|
||||
|
||||
|
@ -1464,7 +1378,6 @@ class OutputUnitData {
|
|||
static const String tag = 'output-unit-data';
|
||||
|
||||
final bool isProgramSplit;
|
||||
final bool deferClassTypes;
|
||||
final OutputUnit mainOutputUnit;
|
||||
final Map<ClassEntity, OutputUnit> _classToUnit;
|
||||
final Map<ClassEntity, OutputUnit> _classTypeToUnit;
|
||||
|
@ -1489,7 +1402,6 @@ class OutputUnitData {
|
|||
|
||||
OutputUnitData(
|
||||
this.isProgramSplit,
|
||||
this.deferClassTypes,
|
||||
this.mainOutputUnit,
|
||||
this._classToUnit,
|
||||
this._classTypeToUnit,
|
||||
|
@ -1532,13 +1444,12 @@ class OutputUnitData {
|
|||
|
||||
return OutputUnitData(
|
||||
other.isProgramSplit,
|
||||
other.deferClassTypes,
|
||||
other.mainOutputUnit,
|
||||
classToUnit,
|
||||
classTypeToUnit,
|
||||
memberToUnit,
|
||||
// Local functions only make sense in the K-world model.
|
||||
const <Local, OutputUnit>{},
|
||||
const {},
|
||||
constantToUnit,
|
||||
other.outputUnits,
|
||||
other._importDeferName,
|
||||
|
@ -1550,7 +1461,6 @@ class OutputUnitData {
|
|||
factory OutputUnitData.readFromDataSource(DataSource source) {
|
||||
source.begin(tag);
|
||||
bool isProgramSplit = source.readBool();
|
||||
bool deferClassTypes = source.readBool();
|
||||
List<OutputUnit> outputUnits = source.readList(() {
|
||||
bool isMainOutput = source.readBool();
|
||||
String name = source.readString();
|
||||
|
@ -1589,13 +1499,12 @@ class OutputUnitData {
|
|||
source.end(tag);
|
||||
return OutputUnitData(
|
||||
isProgramSplit,
|
||||
deferClassTypes,
|
||||
mainOutputUnit,
|
||||
classToUnit,
|
||||
classTypeToUnit,
|
||||
memberToUnit,
|
||||
// Local functions only make sense in the K-world model.
|
||||
const <Local, OutputUnit>{},
|
||||
const {},
|
||||
constantToUnit,
|
||||
outputUnits,
|
||||
importDeferName,
|
||||
|
@ -1607,7 +1516,6 @@ class OutputUnitData {
|
|||
void writeToDataSink(DataSink sink) {
|
||||
sink.begin(tag);
|
||||
sink.writeBool(isProgramSplit);
|
||||
sink.writeBool(deferClassTypes);
|
||||
Map<OutputUnit, int> outputUnitIndices = {};
|
||||
sink.writeList(outputUnits, (OutputUnit outputUnit) {
|
||||
outputUnitIndices[outputUnit] = outputUnitIndices.length;
|
||||
|
@ -1661,18 +1569,13 @@ class OutputUnitData {
|
|||
// TODO(joshualitt): see above TODO regarding allowNull.
|
||||
OutputUnit outputUnitForClassType(ClassEntity cls, {bool allowNull: false}) {
|
||||
if (!isProgramSplit) return mainOutputUnit;
|
||||
OutputUnit unit;
|
||||
if (deferClassTypes) {
|
||||
unit = _classTypeToUnit[cls];
|
||||
} else {
|
||||
unit = _classToUnit[cls];
|
||||
}
|
||||
OutputUnit unit = _classTypeToUnit[cls];
|
||||
assert(allowNull || unit != null, 'No output unit for type $cls');
|
||||
return unit ?? mainOutputUnit;
|
||||
}
|
||||
|
||||
OutputUnit outputUnitForClassTypeForTesting(ClassEntity cls) =>
|
||||
deferClassTypes ? _classTypeToUnit[cls] : _classToUnit[cls];
|
||||
_classTypeToUnit[cls];
|
||||
|
||||
/// Returns the [OutputUnit] where [member] belongs.
|
||||
OutputUnit outputUnitForMember(MemberEntity member) {
|
||||
|
@ -1801,10 +1704,8 @@ class OutputUnitData {
|
|||
|
||||
Map<String, dynamic> libraryMap = mapping.putIfAbsent(
|
||||
description.importingUri,
|
||||
() => <String, dynamic>{
|
||||
"name": getName(description._importingLibrary),
|
||||
"imports": <String, List<String>>{}
|
||||
});
|
||||
() =>
|
||||
{"name": getName(description._importingLibrary), "imports": {}});
|
||||
|
||||
List<String> partFileNames = outputUnits
|
||||
.where((outputUnit) => !omittedUnits.contains(outputUnit))
|
||||
|
@ -1874,16 +1775,11 @@ class DependencyInfo {
|
|||
}
|
||||
|
||||
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 ImportEntity _import;
|
||||
final CommonElements _commonElements;
|
||||
|
||||
TypeDependencyVisitor(this._dependencies, this._import, this._commonElements,
|
||||
{this.collectClassesAndTypes});
|
||||
TypeDependencyVisitor(this._dependencies, this._import, this._commonElements);
|
||||
|
||||
@override
|
||||
void visit(DartType type, [_]) {
|
||||
|
@ -1906,11 +1802,7 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
|||
|
||||
@override
|
||||
void visitFutureOrType(FutureOrType type, Null argument) {
|
||||
if (collectClassesAndTypes) {
|
||||
_dependencies.addClass(_commonElements.futureClass);
|
||||
} else {
|
||||
_dependencies.addClassType(_commonElements.futureClass);
|
||||
}
|
||||
visit(type.typeArgument);
|
||||
}
|
||||
|
||||
|
@ -1937,12 +1829,8 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
|||
@override
|
||||
void visitInterfaceType(InterfaceType type, Null argument) {
|
||||
visitList(type.typeArguments);
|
||||
if (collectClassesAndTypes) {
|
||||
_dependencies.addClass(type.element, _import);
|
||||
} else {
|
||||
_dependencies.addClassType(type.element, _import);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void visitFunctionType(FunctionType type, Null argument) {
|
||||
|
@ -1970,3 +1858,108 @@ class TypeDependencyVisitor implements DartTypeVisitor<void, Null> {
|
|||
// 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`.
|
||||
class Collector {
|
||||
final CompilerOptions _options;
|
||||
final JCommonElements _commonElements;
|
||||
final JElementEnvironment _elementEnvironment;
|
||||
final OutputUnitData _outputUnitData;
|
||||
|
@ -43,7 +42,6 @@ class Collector {
|
|||
final List<ClassEntity> nativeClassesAndSubclasses = [];
|
||||
|
||||
Collector(
|
||||
this._options,
|
||||
this._commonElements,
|
||||
this._elementEnvironment,
|
||||
this._outputUnitData,
|
||||
|
@ -105,7 +103,7 @@ class Collector {
|
|||
// Return the classes that are just helpers for the backend's type system.
|
||||
static Iterable<ClassEntity> getBackendTypeHelpers(
|
||||
JCommonElements commonElements) {
|
||||
return <ClassEntity>[
|
||||
return [
|
||||
commonElements.jsMutableArrayClass,
|
||||
commonElements.jsFixedArrayClass,
|
||||
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.
|
||||
void computeNeededDeclarations() {
|
||||
Set<ClassEntity> backendTypeHelpers =
|
||||
|
@ -157,7 +147,6 @@ class Collector {
|
|||
return !backendTypeHelpers.contains(cls) &&
|
||||
_rtiNeededClasses.contains(cls) &&
|
||||
!classesOnlyNeededForRti.contains(cls) &&
|
||||
_options.deferClassTypes &&
|
||||
_outputUnitData.outputUnitForClass(cls) !=
|
||||
_outputUnitData.outputUnitForClassType(cls);
|
||||
}
|
||||
|
@ -240,7 +229,7 @@ class Collector {
|
|||
// 7. Sort classes needed for type checking and then add them to their
|
||||
// respective OutputUnits.
|
||||
for (ClassEntity cls in _sorter.sortClasses(neededClassTypes)) {
|
||||
_outputListsForClassType
|
||||
outputClassTypeLists
|
||||
.putIfAbsent(_outputUnitData.outputUnitForClassType(cls), () => [])
|
||||
.add(cls);
|
||||
}
|
||||
|
|
|
@ -135,7 +135,6 @@ class ProgramBuilder {
|
|||
this._rtiNeededClasses,
|
||||
this._mainFunction)
|
||||
: this.collector = new Collector(
|
||||
_options,
|
||||
_commonElements,
|
||||
_elementEnvironment,
|
||||
_outputUnitData,
|
||||
|
@ -653,16 +652,11 @@ class ProgramBuilder {
|
|||
Class _buildClass(ClassEntity cls) {
|
||||
bool onlyForConstructor =
|
||||
collector.classesOnlyNeededForConstructor.contains(cls);
|
||||
bool onlyForRti = _options.deferClassTypes
|
||||
? false
|
||||
: collector.classesOnlyNeededForRti.contains(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 onlyForRti = _nativeData.isJsInteropClass(cls);
|
||||
bool hasRtiField = _rtiNeed.classNeedsTypeArguments(cls);
|
||||
bool onlyForConstructorOrRti = onlyForConstructor || onlyForRti;
|
||||
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_impact.dart';
|
||||
import '../util/enumset.dart';
|
||||
import 'deferred_load.dart';
|
||||
import 'element_map.dart';
|
||||
import 'element_map_impl.dart';
|
||||
import 'loader.dart';
|
||||
|
@ -54,7 +53,7 @@ import 'loader.dart';
|
|||
/// model from kernel IR nodes.
|
||||
class KernelFrontendStrategy extends FrontendStrategy {
|
||||
final NativeBasicDataBuilderImpl nativeBasicDataBuilder =
|
||||
new NativeBasicDataBuilderImpl();
|
||||
NativeBasicDataBuilderImpl();
|
||||
NativeBasicData _nativeBasicData;
|
||||
CompilerOptions _options;
|
||||
CompilerTask _compilerTask;
|
||||
|
@ -87,12 +86,11 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
KernelFrontendStrategy(this._compilerTask, this._options,
|
||||
DiagnosticReporter reporter, env.Environment environment) {
|
||||
assert(_compilerTask != null);
|
||||
_elementMap =
|
||||
new KernelToElementMapImpl(reporter, environment, this, _options);
|
||||
_modularStrategy = new KernelModularStrategy(_compilerTask, _elementMap);
|
||||
_backendUsageBuilder = new BackendUsageBuilderImpl(this);
|
||||
noSuchMethodRegistry = new NoSuchMethodRegistryImpl(
|
||||
commonElements, new KernelNoSuchMethodResolver(_elementMap));
|
||||
_elementMap = KernelToElementMapImpl(reporter, environment, this, _options);
|
||||
_modularStrategy = KernelModularStrategy(_compilerTask, _elementMap);
|
||||
_backendUsageBuilder = BackendUsageBuilderImpl(this);
|
||||
noSuchMethodRegistry = NoSuchMethodRegistryImpl(
|
||||
commonElements, KernelNoSuchMethodResolver(_elementMap));
|
||||
}
|
||||
|
||||
NativeResolutionEnqueuer get nativeResolutionEnqueuerForTesting =>
|
||||
|
@ -139,32 +137,30 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
ResolutionEnqueuer createResolutionEnqueuer(
|
||||
CompilerTask task, Compiler compiler) {
|
||||
RuntimeTypesNeedBuilder rtiNeedBuilder = _createRuntimeTypesNeedBuilder();
|
||||
BackendImpacts impacts =
|
||||
new BackendImpacts(commonElements, compiler.options);
|
||||
_nativeResolutionEnqueuer = new NativeResolutionEnqueuer(
|
||||
BackendImpacts impacts = BackendImpacts(commonElements, compiler.options);
|
||||
_nativeResolutionEnqueuer = NativeResolutionEnqueuer(
|
||||
compiler.options,
|
||||
elementEnvironment,
|
||||
commonElements,
|
||||
_elementMap.types,
|
||||
new BaseNativeClassFinder(elementEnvironment, nativeBasicData));
|
||||
_nativeDataBuilder = new NativeDataBuilderImpl(nativeBasicData);
|
||||
_customElementsResolutionAnalysis = new CustomElementsResolutionAnalysis(
|
||||
BaseNativeClassFinder(elementEnvironment, nativeBasicData));
|
||||
_nativeDataBuilder = NativeDataBuilderImpl(nativeBasicData);
|
||||
_customElementsResolutionAnalysis = CustomElementsResolutionAnalysis(
|
||||
elementEnvironment,
|
||||
commonElements,
|
||||
nativeBasicData,
|
||||
_backendUsageBuilder);
|
||||
_fieldAnalysis = new KFieldAnalysis(this);
|
||||
ClassQueries classQueries = new KernelClassQueries(elementMap);
|
||||
_fieldAnalysis = KFieldAnalysis(this);
|
||||
ClassQueries classQueries = KernelClassQueries(elementMap);
|
||||
ClassHierarchyBuilder classHierarchyBuilder =
|
||||
new ClassHierarchyBuilder(commonElements, classQueries);
|
||||
AnnotationsDataBuilder annotationsDataBuilder =
|
||||
new AnnotationsDataBuilder();
|
||||
ClassHierarchyBuilder(commonElements, classQueries);
|
||||
AnnotationsDataBuilder annotationsDataBuilder = AnnotationsDataBuilder();
|
||||
// TODO(johnniwinther): This is a hack. The annotation data is built while
|
||||
// using it. With CFE constants the annotations data can be built fully
|
||||
// before creating the resolution enqueuer.
|
||||
AnnotationsData annotationsData = new AnnotationsDataImpl(
|
||||
AnnotationsData annotationsData = AnnotationsDataImpl(
|
||||
compiler.options, annotationsDataBuilder.pragmaAnnotations);
|
||||
ImpactTransformer impactTransformer = new JavaScriptImpactTransformer(
|
||||
ImpactTransformer impactTransformer = JavaScriptImpactTransformer(
|
||||
elementEnvironment,
|
||||
commonElements,
|
||||
impacts,
|
||||
|
@ -175,13 +171,12 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
rtiNeedBuilder,
|
||||
classHierarchyBuilder,
|
||||
annotationsData);
|
||||
InterceptorDataBuilder interceptorDataBuilder =
|
||||
new InterceptorDataBuilderImpl(
|
||||
InterceptorDataBuilder interceptorDataBuilder = InterceptorDataBuilderImpl(
|
||||
nativeBasicData, elementEnvironment, commonElements);
|
||||
return new ResolutionEnqueuer(
|
||||
return ResolutionEnqueuer(
|
||||
task,
|
||||
compiler.reporter,
|
||||
new ResolutionEnqueuerListener(
|
||||
ResolutionEnqueuerListener(
|
||||
compiler.options,
|
||||
elementEnvironment,
|
||||
commonElements,
|
||||
|
@ -194,7 +189,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
_nativeResolutionEnqueuer,
|
||||
_fieldAnalysis,
|
||||
compiler.deferredLoadTask),
|
||||
new ResolutionWorldBuilderImpl(
|
||||
ResolutionWorldBuilderImpl(
|
||||
_options,
|
||||
elementMap,
|
||||
elementEnvironment,
|
||||
|
@ -212,7 +207,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
const StrongModeWorldStrategy(),
|
||||
classHierarchyBuilder,
|
||||
classQueries),
|
||||
new KernelWorkItemBuilder(
|
||||
KernelWorkItemBuilder(
|
||||
_compilerTask,
|
||||
elementMap,
|
||||
nativeBasicData,
|
||||
|
@ -251,8 +246,8 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
void registerLoadedLibraries(KernelResult kernelResult) {
|
||||
_elementMap.addComponent(kernelResult.component);
|
||||
_irAnnotationData = processAnnotations(
|
||||
new ModularCore(kernelResult.component, _elementMap.constantEvaluator));
|
||||
_annotationProcessor = new KernelAnnotationProcessor(
|
||||
ModularCore(kernelResult.component, _elementMap.constantEvaluator));
|
||||
_annotationProcessor = KernelAnnotationProcessor(
|
||||
elementMap, nativeBasicDataBuilder, _irAnnotationData);
|
||||
for (Uri uri in kernelResult.libraries) {
|
||||
LibraryEntity library = elementEnvironment.lookupLibrary(uri);
|
||||
|
@ -280,7 +275,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
|
||||
@override
|
||||
DeferredLoadTask createDeferredLoadTask(Compiler compiler) =>
|
||||
new KernelDeferredLoadTask(compiler, _elementMap);
|
||||
DeferredLoadTask(compiler, _elementMap);
|
||||
|
||||
@override
|
||||
FunctionEntity computeMain(WorldImpactBuilder impactBuilder) {
|
||||
|
@ -290,7 +285,7 @@ class KernelFrontendStrategy extends FrontendStrategy {
|
|||
RuntimeTypesNeedBuilder _createRuntimeTypesNeedBuilder() {
|
||||
return _runtimeTypesNeedBuilder ??= _options.disableRtiOptimization
|
||||
? const TrivialRuntimeTypesNeedBuilder()
|
||||
: new RuntimeTypesNeedBuilderImpl(elementEnvironment);
|
||||
: RuntimeTypesNeedBuilderImpl(elementEnvironment);
|
||||
}
|
||||
|
||||
RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
|
||||
|
@ -326,12 +321,12 @@ class KernelWorkItemBuilder implements WorkItemBuilder {
|
|||
this._fieldAnalysis,
|
||||
this._modularStrategy,
|
||||
this._irAnnotationData)
|
||||
: _nativeMemberResolver = new KernelNativeMemberResolver(
|
||||
: _nativeMemberResolver = KernelNativeMemberResolver(
|
||||
_elementMap, nativeBasicData, nativeDataBuilder);
|
||||
|
||||
@override
|
||||
WorkItem createWorkItem(MemberEntity entity) {
|
||||
return new KernelWorkItem(
|
||||
return KernelWorkItem(
|
||||
_compilerTask,
|
||||
_elementMap,
|
||||
_impactTransformer,
|
||||
|
@ -404,7 +399,7 @@ class KernelWorkItem implements WorkItem {
|
|||
ResolutionImpact impact = _elementMap.computeWorldImpact(
|
||||
element,
|
||||
scopeModel.variableScopeModel,
|
||||
new Set<PragmaAnnotation>.from(
|
||||
Set<PragmaAnnotation>.from(
|
||||
annotations.iterable(PragmaAnnotation.values)),
|
||||
impactBuilderData: impactBuilderData);
|
||||
WorldImpact worldImpact =
|
||||
|
@ -440,8 +435,8 @@ class KernelModularStrategy extends ModularStrategy {
|
|||
@override
|
||||
ModularMemberData getModularMemberData(
|
||||
ir.Member node, EnumSet<PragmaAnnotation> annotations) {
|
||||
ScopeModel scopeModel = _compilerTask.measureSubtask('closures',
|
||||
() => new ScopeModel.from(node, _elementMap.constantEvaluator));
|
||||
ScopeModel scopeModel = _compilerTask.measureSubtask(
|
||||
'closures', () => ScopeModel.from(node, _elementMap.constantEvaluator));
|
||||
ImpactBuilderData impactBuilderData;
|
||||
if (useImpactDataForTesting) {
|
||||
// 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
|
||||
// computed during conversion to [ResolutionImpact].
|
||||
impactBuilderData = _compilerTask.measureSubtask('worldImpact', () {
|
||||
ImpactBuilder builder = new ImpactBuilder(
|
||||
new ir.StaticTypeContext(node, _elementMap.typeEnvironment),
|
||||
ImpactBuilder builder = ImpactBuilder(
|
||||
ir.StaticTypeContext(node, _elementMap.typeEnvironment),
|
||||
_elementMap.classHierarchy,
|
||||
scopeModel.variableScopeModel,
|
||||
useAsserts: _elementMap.options.enableUserAssertions,
|
||||
|
@ -459,6 +454,6 @@ class KernelModularStrategy extends ModularStrategy {
|
|||
return builder.computeImpact(node);
|
||||
});
|
||||
}
|
||||
return new ModularMemberData(scopeModel, impactBuilderData);
|
||||
return ModularMemberData(scopeModel, impactBuilderData);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -142,32 +142,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
/// libraries are subdivided.
|
||||
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.
|
||||
// TODO(sigmund): negate, so all flags are positive
|
||||
bool disableInlining = false;
|
||||
|
@ -443,12 +417,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
_extractStringOption(options, '--build-id=', _UNDETERMINED_BUILD_ID)
|
||||
..compileForServer = _hasOption(options, Flags.serverMode)
|
||||
..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)
|
||||
..terseDiagnostics = _hasOption(options, Flags.terse)
|
||||
..suppressWarnings = _hasOption(options, Flags.suppressWarnings)
|
||||
|
@ -555,14 +523,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
throw ArgumentError("'${Flags.soundNullSafety}' requires the "
|
||||
"'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() {
|
||||
|
@ -620,12 +580,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
if (_disableMinification) {
|
||||
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.
|
||||
|
|
Loading…
Reference in a new issue