Migrate pkg/vm to null safety, part 3
TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/46620
Change-Id: I1ab793eec6ffd7e01cee1e6641138e96a4f4d9fc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207864
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 83c9a50..75eff47 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Global type flow analysis.
-library kernel.transformations.analysis;
import 'dart:collection';
import 'dart:core' hide Type;
@@ -51,24 +48,28 @@
/// Maintains set of dependent invocations.
class _DependencyTracker {
- Set<_Invocation> _dependentInvocations;
+ Set<_Invocation>? _dependentInvocations;
void addDependentInvocation(_Invocation invocation) {
if (!identical(invocation, this)) {
- _dependentInvocations ??= new Set<_Invocation>();
- _dependentInvocations.add(invocation);
+ var dependentInvocations = _dependentInvocations;
+ if (dependentInvocations == null) {
+ _dependentInvocations = dependentInvocations = Set<_Invocation>();
+ }
+ dependentInvocations.add(invocation);
}
}
void invalidateDependentInvocations(_WorkList workList) {
- if (_dependentInvocations != null) {
+ final dependentInvocations = _dependentInvocations;
+ if (dependentInvocations != null) {
if (kPrintTrace) {
tracePrint(' - CHANGED: $this');
- for (var di in _dependentInvocations) {
+ for (var di in dependentInvocations) {
tracePrint(' - invalidating $di');
}
}
- _dependentInvocations.forEach(workList.invalidateInvocation);
+ dependentInvocations.forEach(workList.invalidateInvocation);
}
}
}
@@ -83,12 +84,12 @@
final Selector selector;
final Args<Type> args;
- Type result;
+ Type? result;
/// Result of the invocation calculated before invocation was invalidated.
/// Used to check if the re-analysis of the invocation yields the same
/// result or not (to avoid invalidation of callers if result hasn't changed).
- Type invalidatedResult;
+ Type? invalidatedResult;
/// Number of times result of this invocation was invalidated.
int invalidationCounter = 0;
@@ -108,7 +109,7 @@
/// Returns result of this invocation if its available without
/// further analysis, or `null` if it's not available.
/// Used for recursive calls while this invocation is being processed.
- Type get resultForRecursiveInvocation => result;
+ Type? get resultForRecursiveInvocation => result;
/// Use [type] as a current computed result of this invocation.
/// If this invocation was invalidated, and the invalidated result is
@@ -116,7 +117,6 @@
/// Result type may be saturated if this invocation was invalidated
/// too many times.
void setResult(TypeFlowAnalysis typeFlowAnalysis, Type type) {
- assert(type != null);
result = type;
if (invalidatedResult != null) {
@@ -132,8 +132,8 @@
// the analysis, result is saturated after invocation is invalidated
// at least [_Invocation.invalidationLimit] times.
if (invalidationCounter > _Invocation.invalidationLimit) {
- result =
- result.union(invalidatedResult, typeFlowAnalysis.hierarchyCache);
+ result = result!
+ .union(invalidatedResult!, typeFlowAnalysis.hierarchyCache);
}
}
invalidatedResult = null;
@@ -192,11 +192,12 @@
// they could fail bounds checks.
//
// TODO(sjindel): Use [TypeCheck] to avoid bounds checks.
- if (selector.member.function != null) {
- typeChecksNeeded = selector.member.function.typeParameters
- .any((t) => t.isGenericCovariantImpl);
+ final function = selector.member.function;
+ if (function != null) {
+ typeChecksNeeded =
+ function.typeParameters.any((t) => t.isGenericCovariantImpl);
} else {
- Field field = selector.member;
+ Field field = selector.member as Field;
if (selector.callKind == CallKind.PropertySet) {
// TODO(dartbug.com/40615): Use TFA results to improve this criterion.
typeChecksNeeded = field.isGenericCovariantImpl;
@@ -277,13 +278,10 @@
fieldValue.isInitialized = true;
return const EmptyType();
}
-
- // Make dartanalyzer happy.
- throw 'Unexpected call kind ${selector.callKind}';
}
Type _processFunction(TypeFlowAnalysis typeFlowAnalysis) {
- final Member member = selector.member;
+ final Member member = selector.member!;
if (selector.memberAgreesToCallKind(member)) {
if (_argumentsValid()) {
final summary = typeFlowAnalysis.getSummary(member);
@@ -326,13 +324,12 @@
}
bool _argumentsValid() {
- final function = selector.member.function;
- assert(function != null);
-
+ final member = selector.member!;
+ final function = member.function!;
final int positionalArguments = args.positionalCount;
- final int firstParamIndex = numTypeParams(selector.member) +
- (hasReceiverArg(selector.member) ? 1 : 0);
+ final int firstParamIndex =
+ numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
final int requiredParameters =
firstParamIndex + function.requiredParameterCount;
if (positionalArguments < requiredParameters) {
@@ -361,9 +358,9 @@
class _DispatchableInvocation extends _Invocation {
bool _isPolymorphic = false;
- Set<Call> _callSites; // Populated only if not polymorphic.
- Member _monomorphicTarget;
- _DirectInvocation _monomorphicDirectInvocation;
+ Set<Call>? _callSites; // Populated only if not polymorphic.
+ Member? _monomorphicTarget;
+ _DirectInvocation? _monomorphicDirectInvocation;
@override
set typeChecksNeeded(bool value) {
@@ -434,7 +431,8 @@
if (!_isPolymorphic) {
assert(target == _monomorphicTarget);
- _monomorphicDirectInvocation = directInvocation;
+ _monomorphicDirectInvocation =
+ directInvocation as _DirectInvocation;
}
type = typeFlowAnalysis.workList.processInvocation(directInvocation);
@@ -486,13 +484,13 @@
final bool isNullableReceiver = receiver is NullableType;
if (isNullableReceiver) {
- receiver = (receiver as NullableType).baseType;
+ receiver = receiver.baseType;
assert(receiver is! NullableType);
}
if (selector is InterfaceSelector) {
final staticReceiverType = new ConeType(typeFlowAnalysis.hierarchyCache
- .getTFClass(selector.member.enclosingClass));
+ .getTFClass(selector.member!.enclosingClass!));
receiver = receiver.intersection(
staticReceiverType, typeFlowAnalysis.hierarchyCache);
assert(receiver is! NullableType);
@@ -507,7 +505,7 @@
// invocation to the receiver class. A new allocated class discovered
// in the receiver cone will invalidate this invocation.
receiver = typeFlowAnalysis.hierarchyCache
- .specializeTypeCone((receiver as ConeType).cls, allowWideCone: false);
+ .specializeTypeCone(receiver.cls, allowWideCone: false);
}
assert(targets.isEmpty);
@@ -535,7 +533,7 @@
Class nullClass =
typeFlowAnalysis.environment.coreTypes.deprecatedNullClass;
- Member target = typeFlowAnalysis.hierarchyCache.hierarchy
+ Member? target = typeFlowAnalysis.hierarchyCache.hierarchy
.getDispatchTarget(nullClass, selector.name, setter: selector.isSetter);
if (target != null) {
@@ -552,7 +550,7 @@
TypeFlowAnalysis typeFlowAnalysis) {
final TFClass cls = receiver.cls;
- Member target =
+ Member? target =
(cls as _TFClassImpl).getDispatchTarget(selector, typeFlowAnalysis);
if (target != null) {
@@ -647,8 +645,9 @@
if (_isPolymorphic) {
callSite.setPolymorphic();
} else {
- if (_monomorphicTarget != null) {
- callSite.addTarget(_monomorphicTarget);
+ final monomorphicTarget = _monomorphicTarget;
+ if (monomorphicTarget != null) {
+ callSite.addTarget(monomorphicTarget);
}
}
@@ -660,18 +659,20 @@
/// Notify call sites monitoring this invocation about changes in
/// polymorphism of this invocation.
void _notifyCallSites() {
- if (_callSites != null) {
- _callSites.forEach(_notifyCallSite);
+ final callSites = _callSites;
+ if (callSites != null) {
+ callSites.forEach(_notifyCallSite);
}
}
@override
- Type get resultForRecursiveInvocation {
+ Type? get resultForRecursiveInvocation {
if (result != null) {
return result;
}
- if (_monomorphicDirectInvocation != null) {
- return _monomorphicDirectInvocation.resultForRecursiveInvocation;
+ final monomorphicDirectInvocation = _monomorphicDirectInvocation;
+ if (monomorphicDirectInvocation != null) {
+ return monomorphicDirectInvocation.resultForRecursiveInvocation;
}
return null;
}
@@ -683,30 +684,30 @@
/// 1) Add 1..N concrete types ordered by classId OR add 1 arbitrary type.
/// 2) Make type nullable.
class _ReceiverTypeBuilder {
- Type _type;
- List<ConcreteType> _list;
+ Type? _type;
+ List<ConcreteType>? _list;
bool _nullable = false;
/// Appends a ConcreteType. May be called multiple times.
/// Should not be used in conjunction with [addType].
void addConcreteType(ConcreteType type) {
- if (_list == null) {
- if (_type == null) {
+ final list = _list;
+ if (list == null) {
+ final Type? t = _type;
+ if (t == null) {
_type = type;
return;
}
+ final ct = t as ConcreteType;
- assert(_type is ConcreteType);
- assert(_type != type);
-
- _list = <ConcreteType>[];
- _list.add(_type);
-
+ assert(ct != type);
+ assert(ct.cls.id < type.cls.id);
+ _list = <ConcreteType>[ct, type];
_type = null;
+ } else {
+ assert(list.last.cls.id < type.cls.id);
+ list.add(type);
}
-
- assert(_list.last.cls.id < type.cls.id);
- _list.add(type);
}
/// Appends an arbitrary Type. May be called only once.
@@ -723,12 +724,13 @@
/// Returns union of added types.
Type toType() {
- Type t = _type;
+ Type? t = _type;
if (t == null) {
- if (_list == null) {
+ final list = _list;
+ if (list == null) {
t = const EmptyType();
} else {
- t = new SetType(_list);
+ t = SetType(list);
}
} else {
assert(_list == null);
@@ -753,7 +755,7 @@
static const int maxInvocationsPerSelector = 5000;
int count = 0;
- _Invocation approximation;
+ _Invocation? approximation;
}
/// Maintains ([Selector], [Args]) => [_Invocation] cache.
@@ -771,7 +773,7 @@
_Invocation invocation = (selector is DirectSelector)
? new _DirectInvocation(selector, args)
: new _DispatchableInvocation(selector, args);
- _Invocation result = _invocations.lookup(invocation);
+ _Invocation? result = _invocations.lookup(invocation);
if (result != null) {
return result;
}
@@ -784,14 +786,16 @@
final sa = (_approximations[selector] ??= new _SelectorApproximation());
if (sa.count >= _SelectorApproximation.maxInvocationsPerSelector) {
- if (sa.approximation == null) {
+ _Invocation? approximation = sa.approximation;
+ if (approximation == null) {
final rawArgs =
_typeFlowAnalysis.summaryCollector.rawArguments(selector);
- sa.approximation = new _DispatchableInvocation(selector, rawArgs);
+ sa.approximation =
+ approximation = _DispatchableInvocation(selector, rawArgs);
Statistics.approximateInvocationsCreated++;
}
Statistics.approximateInvocationsUsed++;
- return sa.approximation;
+ return approximation;
}
++sa.count;
@@ -809,8 +813,8 @@
class _FieldValue extends _DependencyTracker {
final Field field;
final Type staticType;
- final Summary typeGuardSummary;
- Type value;
+ final Summary? typeGuardSummary;
+ Type value = const EmptyType();
/// Flag indicating if field initializer was executed.
bool isInitialized = false;
@@ -825,8 +829,6 @@
: staticType = typesBuilder.fromStaticType(field.type, true) {
if (field.initializer == null && _isDefaultValueOfFieldObservable()) {
value = new Type.nullable(const EmptyType());
- } else {
- value = const EmptyType();
}
}
@@ -839,8 +841,7 @@
return true;
}
- final enclosingClass = field.enclosingClass;
- assert(enclosingClass != null);
+ final enclosingClass = field.enclosingClass!;
// Default value is not observable if every generative constructor
// is redirecting or initializes the field.
@@ -856,10 +857,11 @@
});
}
- void ensureInitialized(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ void ensureInitialized(
+ TypeFlowAnalysis typeFlowAnalysis, Type? receiverType) {
if (field.initializer != null) {
assert(field.isStatic == (receiverType == null));
- final args = !field.isStatic ? <Type>[receiverType] : const <Type>[];
+ final args = !field.isStatic ? <Type>[receiverType!] : const <Type>[];
final initializerInvocation = typeFlowAnalysis._invocationsCache
.getInvocation(
new DirectSelector(field, callKind: CallKind.FieldInitializer),
@@ -870,17 +872,18 @@
}
}
- Type getValue(TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ Type getValue(TypeFlowAnalysis typeFlowAnalysis, Type? receiverType) {
ensureInitialized(typeFlowAnalysis, receiverType);
addDependentInvocation(typeFlowAnalysis.currentInvocation);
+ final typeGuardSummary = this.typeGuardSummary;
return (typeGuardSummary != null)
- ? typeGuardSummary.apply(Args([receiverType, value]),
+ ? typeGuardSummary.apply(Args([receiverType!, value]),
typeFlowAnalysis.hierarchyCache, typeFlowAnalysis)
: value;
}
void setValue(
- Type newValue, TypeFlowAnalysis typeFlowAnalysis, Type receiverType) {
+ Type newValue, TypeFlowAnalysis typeFlowAnalysis, Type? receiverType) {
// Make sure type cones are specialized before putting them into field
// value, in order to ensure that dependency is established between
// cone's base type and corresponding field setter.
@@ -907,10 +910,11 @@
//
final hierarchy = typeFlowAnalysis.hierarchyCache;
// TODO(sjindel/tfa): Perform narrowing inside 'TypeCheck'.
+ final typeGuardSummary = this.typeGuardSummary;
final narrowedNewValue = typeGuardSummary != null
? typeGuardSummary
- .apply(
- new Args([receiverType, newValue]), hierarchy, typeFlowAnalysis)
+ .apply(new Args([receiverType!, newValue]), hierarchy,
+ typeFlowAnalysis)
.intersection(staticType, hierarchy)
: newValue.specialize(hierarchy).intersection(staticType, hierarchy);
Type newType =
@@ -952,28 +956,26 @@
/// Flag indicating if this class has a noSuchMethod() method not inherited
/// from Object.
/// Lazy initialized by ClassHierarchyCache.hasNonTrivialNoSuchMethod().
- bool hasNonTrivialNoSuchMethod;
+ bool? hasNonTrivialNoSuchMethod;
_TFClassImpl(int id, Class classNode, this.supertypes)
: super(id, classNode) {
supertypes.add(this);
}
- ConcreteType _concreteType;
- ConcreteType get concreteType =>
- _concreteType ??= new ConcreteType(this, null);
+ late final ConcreteType concreteType = ConcreteType(this, null);
- Type _specializedConeType;
+ Type? _specializedConeType;
Type get specializedConeType =>
_specializedConeType ??= _calculateConeTypeSpecialization();
bool get hasWideCone =>
_allocatedSubtypes.length > maxAllocatedTypesInSetSpecializations;
- WideConeType _wideConeType;
+ late final WideConeType _wideConeType = WideConeType(this);
WideConeType get wideConeType {
assert(hasWideCone);
- return _wideConeType ??= new WideConeType(this);
+ return _wideConeType;
}
Type _calculateConeTypeSpecialization() {
@@ -999,14 +1001,16 @@
_specializedConeType = null; // Reset cached specialization.
}
- Member getDispatchTarget(
+ Member? getDispatchTarget(
Selector selector, TypeFlowAnalysis typeFlowAnalysis) {
- Member target = _dispatchTargets[selector];
+ Member? target = _dispatchTargets[selector];
if (target == null) {
target = typeFlowAnalysis.hierarchyCache.hierarchy.getDispatchTarget(
classNode, selector.name,
setter: selector.isSetter);
- _dispatchTargets[selector] = target;
+ if (target != null) {
+ _dispatchTargets[selector] = target;
+ }
}
return target;
}
@@ -1021,10 +1025,11 @@
final cachedFlattenedTypeArgs = <Class, List<DartType>>{};
final cachedFlattenedTypeArgsForNonGeneric = <Class, List<Type>>{};
- RuntimeTypeTranslatorImpl closedTypeTranslator;
+ late final RuntimeTypeTranslatorImpl closedTypeTranslator;
- GenericInterfacesInfoImpl(this.hierarchy) {
- closedTypeTranslator = RuntimeTypeTranslatorImpl.forClosedTypes(this);
+ GenericInterfacesInfoImpl(CoreTypes coreTypes, this.hierarchy) {
+ closedTypeTranslator =
+ RuntimeTypeTranslatorImpl.forClosedTypes(coreTypes, this);
}
List<DartType> flattenedTypeArgumentsFor(Class klass, {bool useCache: true}) {
@@ -1049,7 +1054,7 @@
if (klass == iface) return 0;
final pair = new SubtypePair(klass, iface);
- int offset = supertypeOffsetsCache[pair];
+ int? offset = supertypeOffsetsCache[pair];
if (offset != null) return offset;
@@ -1064,16 +1069,16 @@
}
List<Type> flattenedTypeArgumentsForNonGeneric(Class klass) {
- List<Type> result = cachedFlattenedTypeArgsForNonGeneric[klass];
+ List<Type>? result = cachedFlattenedTypeArgsForNonGeneric[klass];
if (result != null) return result;
List<DartType> flattenedTypeArgs =
flattenedTypeArgumentsFor(klass, useCache: false);
- result = new List<Type>.filled(flattenedTypeArgs.length, null);
- for (int i = 0; i < flattenedTypeArgs.length; ++i) {
- final translated = closedTypeTranslator.translate(flattenedTypeArgs[i]);
+ result = <Type>[];
+ for (DartType arg in flattenedTypeArgs) {
+ final translated = closedTypeTranslator.translate(arg);
assert(translated is RuntimeType || translated is UnknownType);
- result[i] = translated;
+ result.add(translated as Type);
}
cachedFlattenedTypeArgsForNonGeneric[klass] = result;
return result;
@@ -1108,10 +1113,8 @@
_ClassHierarchyCache(this._typeFlowAnalysis, this.hierarchy,
this.genericInterfacesInfo, this.environment, bool nullSafety)
: objectNoSuchMethod = hierarchy.getDispatchTarget(
- environment.coreTypes.objectClass, noSuchMethodName),
- super(environment.coreTypes, nullSafety) {
- assert(objectNoSuchMethod != null);
- }
+ environment.coreTypes.objectClass, noSuchMethodName)!,
+ super(environment.coreTypes, nullSafety);
@override
_TFClassImpl getTFClass(Class c) {
@@ -1198,10 +1201,13 @@
bool hasNonTrivialNoSuchMethod(TFClass c) {
final classImpl = c as _TFClassImpl;
- classImpl.hasNonTrivialNoSuchMethod ??=
- (hierarchy.getDispatchTarget(c.classNode, noSuchMethodName) !=
- objectNoSuchMethod);
- return classImpl.hasNonTrivialNoSuchMethod;
+ bool? value = classImpl.hasNonTrivialNoSuchMethod;
+ if (value == null) {
+ classImpl.hasNonTrivialNoSuchMethod = value =
+ (hierarchy.getDispatchTarget(c.classNode, noSuchMethodName) !=
+ objectNoSuchMethod);
+ }
+ return value;
}
_DynamicTargetSet getDynamicTargetSet(DynamicSelector selector) {
@@ -1294,10 +1300,11 @@
}
bool invalidateProtobufFields() {
- if (_typeFlowAnalysis.protobufHandler == null) {
+ final protobufHandler = _typeFlowAnalysis.protobufHandler;
+ if (protobufHandler == null) {
return false;
}
- final fields = _typeFlowAnalysis.protobufHandler.getInvalidatedFields();
+ final fields = protobufHandler.getInvalidatedFields();
if (fields.isEmpty) {
return false;
}
@@ -1305,7 +1312,7 @@
for (var field in fields) {
assert(field.isStatic);
// Reset summary in order to rebuild it.
- _typeFlowAnalysis._summaries[field] = null;
+ _typeFlowAnalysis._summaries.remove(field);
// Invalidate (and enqueue) field initializer invocation.
final initializerInvocation = _typeFlowAnalysis._invocationsCache
.getInvocation(
@@ -1328,10 +1335,11 @@
}
Type processInvocation(_Invocation invocation) {
- if (invocation.result != null) {
+ Type? result = invocation.result;
+ if (result != null) {
// Already processed.
Statistics.usedCachedResultsOfInvocations++;
- return invocation.result;
+ return result;
}
// Test if tracing is enabled to avoid expensive message formatting.
@@ -1374,18 +1382,18 @@
-1);
}
processing.remove(invocation);
- return invocation.invalidatedResult;
+ return invocation.invalidatedResult!;
}
callStack.add(invocation);
pending.remove(invocation);
- Type result = invocation.process(_typeFlowAnalysis);
+ result = invocation.process(_typeFlowAnalysis);
invocation.setResult(_typeFlowAnalysis, result);
// setResult may saturate result to ensure convergence.
- result = invocation.result;
+ result = invocation.result!;
// Invocation is still pending - it was invalidated while being processed.
// Move result to invalidatedResult.
@@ -1434,12 +1442,12 @@
final TypeEnvironment environment;
final LibraryIndex libraryIndex;
final PragmaAnnotationParser annotationMatcher;
- final ProtobufHandler protobufHandler;
- NativeCodeOracle nativeCodeOracle;
- _ClassHierarchyCache hierarchyCache;
- SummaryCollector summaryCollector;
- _InvocationsCache _invocationsCache;
- _WorkList workList;
+ final ProtobufHandler? protobufHandler;
+ late NativeCodeOracle nativeCodeOracle;
+ late _ClassHierarchyCache hierarchyCache;
+ late SummaryCollector summaryCollector;
+ late _InvocationsCache _invocationsCache;
+ late _WorkList workList;
GenericInterfacesInfo _genericInterfacesInfo;
final Map<Member, Summary> _summaries = <Member, Summary>{};
@@ -1459,7 +1467,7 @@
this.environment,
this.libraryIndex,
this.protobufHandler,
- PragmaAnnotationParser matcher)
+ PragmaAnnotationParser? matcher)
: annotationMatcher =
matcher ?? new ConstantPragmaAnnotationParser(coreTypes) {
nativeCodeOracle = new NativeCodeOracle(libraryIndex, annotationMatcher);
@@ -1488,9 +1496,9 @@
}
_FieldValue getFieldValue(Field field) {
- _FieldValue fieldValue = _fieldValues[field];
+ _FieldValue? fieldValue = _fieldValues[field];
if (fieldValue == null) {
- Summary typeGuardSummary = null;
+ Summary? typeGuardSummary = null;
if (field.isGenericCovariantImpl) {
typeGuardSummary = summaryCollector.createSummary(field,
fieldSummaryType: FieldSummaryType.kFieldGuard);
@@ -1548,24 +1556,24 @@
bool isClassAllocated(Class c) => hierarchyCache.allocatedClasses.contains(c);
- Call callSite(TreeNode node) => summaryCollector.callSites[node];
+ Call? callSite(TreeNode node) => summaryCollector.callSites[node];
- TypeCheck explicitCast(AsExpression cast) =>
+ TypeCheck? explicitCast(AsExpression cast) =>
summaryCollector.explicitCasts[cast];
- TypeCheck isTest(IsExpression node) => summaryCollector.isTests[node];
+ TypeCheck? isTest(IsExpression node) => summaryCollector.isTests[node];
- NarrowNotNull nullTest(TreeNode node) => summaryCollector.nullTests[node];
+ NarrowNotNull? nullTest(TreeNode node) => summaryCollector.nullTests[node];
- Type fieldType(Field field) => _fieldValues[field]?.value;
+ Type? fieldType(Field field) => _fieldValues[field]?.value;
- Args<Type> argumentTypes(Member member) => _summaries[member]?.argumentTypes;
+ Args<Type>? argumentTypes(Member member) => _summaries[member]?.argumentTypes;
- Type argumentType(Member member, VariableDeclaration memberParam) {
+ Type? argumentType(Member member, VariableDeclaration memberParam) {
return _summaries[member]?.argumentType(member, memberParam);
}
- List<VariableDeclaration> uncheckedParameters(Member member) =>
+ List<VariableDeclaration>? uncheckedParameters(Member member) =>
_summaries[member]?.uncheckedParameters;
bool isTearOffTaken(Member member) => _tearOffTaken.contains(member);
@@ -1599,7 +1607,7 @@
/// ---- Implementation of [CallHandler] interface. ----
@override
- Type applyCall(Call callSite, Selector selector, Args<Type> args,
+ Type applyCall(Call? callSite, Selector selector, Args<Type> args,
{bool isResultUsed: true, bool processImmediately: true}) {
_Invocation invocation = _invocationsCache.getInvocation(selector, args);
@@ -1629,7 +1637,7 @@
workList.enqueueInvocation(invocation);
}
- return null;
+ return const EmptyType();
}
}
@@ -1680,7 +1688,7 @@
}
@override
- void recordTearOff(Procedure target) {
+ void recordTearOff(Member target) {
_tearOffTaken.add(target);
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/calls.dart b/pkg/vm/lib/transformations/type_flow/calls.dart
index 060500a..dd16279d 100644
--- a/pkg/vm/lib/transformations/type_flow/calls.dart
+++ b/pkg/vm/lib/transformations/type_flow/calls.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Declares classes which describe a call: selectors and arguments.
-library vm.transformations.type_flow.calls;
import 'dart:core' hide Type;
@@ -30,10 +27,10 @@
Selector(this.callKind);
/// Interface or concrete target, may be null.
- Member get member;
+ Member? get member;
/// Selector name.
- Name get name => member.name;
+ Name get name => member!.name;
bool get isSetter => (callKind == CallKind.PropertySet);
@@ -46,6 +43,7 @@
/// Static approximation of Dart return type.
DartType get staticReturnType {
+ final member = this.member;
if (member == null) {
return const DynamicType();
}
@@ -61,7 +59,6 @@
case CallKind.SetFieldInConstructor:
return const NeverType.nonNullable();
}
- return null;
}
bool memberAgreesToCallKind(Member member) {
@@ -79,7 +76,6 @@
case CallKind.SetFieldInConstructor:
return member is Field;
}
- return false;
}
String get _callKindPrefix {
@@ -94,7 +90,6 @@
case CallKind.FieldInitializer:
return 'init ';
}
- return '';
}
}
@@ -169,7 +164,7 @@
DynamicSelector(CallKind callKind, this.name) : super(callKind);
@override
- Member get member => null;
+ Member? get member => null;
@override
int get hashCode => (super.hashCode ^ name.hashCode + 37) & kHashMask;
@@ -189,7 +184,8 @@
final List<T> values;
final List<String> names;
- int _hashCode;
+ @override
+ late final int hashCode = _computeHashCode();
Args(this.values, {this.names = const <String>[]}) {
assert(isSorted(names));
@@ -206,9 +202,6 @@
T get receiver => values[0];
- @override
- int get hashCode => _hashCode ??= _computeHashCode();
-
int _computeHashCode() {
int hash = 1231;
for (var v in values) {
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 7a5baf9..0611379 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Handling of native code and entry points.
-library vm.transformations.type_flow.native_code;
import 'dart:core' hide Type;
@@ -35,24 +32,21 @@
/// Record the fact that given member is called from this.
void recordMemberCalledViaThis(Member target);
- /// Record the fact that given method is torn off.
- void recordTearOff(Procedure target) {}
+ /// Record the fact that given member is torn off.
+ void recordTearOff(Member target) {}
}
class PragmaEntryPointsVisitor extends RecursiveVisitor {
final EntryPointsListener entryPoints;
final NativeCodeOracle nativeCodeOracle;
final PragmaAnnotationParser matcher;
- Class currentClass = null;
PragmaEntryPointsVisitor(
- this.entryPoints, this.nativeCodeOracle, this.matcher) {
- assert(matcher != null);
- }
+ this.entryPoints, this.nativeCodeOracle, this.matcher);
- PragmaEntryPointType _annotationsDefineRoot(List<Expression> annotations) {
+ PragmaEntryPointType? _annotationsDefineRoot(List<Expression> annotations) {
for (var annotation in annotations) {
- ParsedPragma pragma = matcher.parsePragma(annotation);
+ ParsedPragma? pragma = matcher.parsePragma(annotation);
if (pragma == null) continue;
if (pragma is ParsedEntryPointPragma) return pragma.type;
}
@@ -72,7 +66,6 @@
}
nativeCodeOracle.addClassReferencedFromNativeCode(klass);
}
- currentClass = klass;
klass.visitChildren(this);
}
@@ -88,8 +81,7 @@
}
Member target = proc;
while (target is Procedure && target.isRedirectingFactory) {
- target = getRedirectingFactoryBody(target).target;
- assert(target != null);
+ target = getRedirectingFactoryBody(target)!.target!;
assert(
(target is Procedure && target.isFactory) || target is Constructor);
}
@@ -152,7 +144,7 @@
}
entryPoints
.addRawCall(new DirectSelector(ctor, callKind: CallKind.Method));
- entryPoints.addAllocatedClass(currentClass);
+ entryPoints.addAllocatedClass(ctor.enclosingClass);
nativeCodeOracle.setMemberReferencedFromNativeCode(ctor);
}
}
@@ -201,9 +193,7 @@
final Set<Class> _classesReferencedFromNativeCode = new Set<Class>();
final PragmaAnnotationParser _matcher;
- NativeCodeOracle(this._libraryIndex, this._matcher) {
- assert(_matcher != null);
- }
+ NativeCodeOracle(this._libraryIndex, this._matcher);
void addClassReferencedFromNativeCode(Class klass) {
_classesReferencedFromNativeCode.add(klass);
@@ -219,9 +209,9 @@
bool isMemberReferencedFromNativeCode(Member member) =>
_membersReferencedFromNativeCode.contains(member);
- PragmaRecognizedType recognizedType(Member member) {
+ PragmaRecognizedType? recognizedType(Member member) {
for (var annotation in member.annotations) {
- ParsedPragma pragma = _matcher.parsePragma(annotation);
+ ParsedPragma? pragma = _matcher.parsePragma(annotation);
if (pragma is ParsedRecognized) {
return pragma.type;
}
@@ -229,15 +219,16 @@
return null;
}
- bool isRecognized(Member member, [List<PragmaRecognizedType> expectedTypes]) {
- PragmaRecognizedType type = recognizedType(member);
+ bool isRecognized(Member member,
+ [List<PragmaRecognizedType>? expectedTypes]) {
+ PragmaRecognizedType? type = recognizedType(member);
return type != null &&
(expectedTypes == null || expectedTypes.contains(type));
}
bool hasDisableUnboxedParameters(Member member) {
for (var annotation in member.annotations) {
- ParsedPragma pragma = _matcher.parsePragma(annotation);
+ ParsedPragma? pragma = _matcher.parsePragma(annotation);
if (pragma is ParsedDisableUnboxedParameters) {
if (member.enclosingLibrary.importUri.scheme != "dart") {
throw "ERROR: Cannot use @pragma(vm:disable-unboxed-parameters) outside core libraries.";
@@ -255,11 +246,11 @@
EntryPointsListener entryPointsListener,
TypesBuilder typesBuilder,
RuntimeTypeTranslator translator) {
- TypeExpr returnType = null;
- bool nullable = null;
+ TypeExpr? returnType = null;
+ bool? nullable = null;
for (var annotation in member.annotations) {
- ParsedPragma pragma = _matcher.parsePragma(annotation);
+ ParsedPragma? pragma = _matcher.parsePragma(annotation);
if (pragma == null) continue;
if (pragma is ParsedResultTypeByTypePragma ||
pragma is ParsedResultTypeByPathPragma ||
@@ -278,8 +269,8 @@
returnType = entryPointsListener.addAllocatedClass(type.classNode);
if (pragma.resultTypeUsesPassedTypeArguments) {
returnType = translator.instantiateConcreteType(
- returnType,
- member.function.typeParameters
+ returnType as ConcreteType,
+ member.function!.typeParameters
.map((t) => TypeParameterType(
t, TypeParameterType.computeNullabilityFromBound(t)))
.toList());
@@ -314,7 +305,7 @@
return returnType;
} else {
return typesBuilder.fromStaticType(
- member.function.returnType, nullable ?? true);
+ member.function!.returnType, nullable ?? true);
}
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
index a4b0bbc..c0175a4 100644
--- a/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
+++ b/pkg/vm/lib/transformations/type_flow/protobuf_handler.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
import 'package:kernel/core_types.dart' show CoreTypes;
@@ -47,14 +45,14 @@
final Procedure _builderInfoAddMethod;
// Type of BuilderInfo.add<Null>().
- FunctionType _typeOfBuilderInfoAddOfNull;
+ late FunctionType _typeOfBuilderInfoAddOfNull;
final _messageClasses = <Class, _MessageClass>{};
final _invalidatedClasses = <_MessageClass>{};
/// Creates [ProtobufHandler] instance for [component].
/// Returns null if protobuf library is not used.
- static ProtobufHandler forComponent(
+ static ProtobufHandler? forComponent(
Component component, CoreTypes coreTypes) {
final libraryIndex = LibraryIndex(component, [protobufLibraryUri]);
if (!libraryIndex.containsLibrary(protobufLibraryUri)) {
@@ -68,12 +66,12 @@
libraryIndex.getClass(protobufLibraryUri, 'GeneratedMessage'),
_tagNumberClass =
libraryIndex.getClass(protobufLibraryUri, 'TagNumber'),
- _tagNumberField = libraryIndex.getMember(
- protobufLibraryUri, 'TagNumber', 'tagNumber'),
+ _tagNumberField =
+ libraryIndex.getField(protobufLibraryUri, 'TagNumber', 'tagNumber'),
_builderInfoClass =
libraryIndex.getClass(protobufLibraryUri, 'BuilderInfo'),
- _builderInfoAddMethod =
- libraryIndex.getMember(protobufLibraryUri, 'BuilderInfo', 'add') {
+ _builderInfoAddMethod = libraryIndex.getProcedure(
+ protobufLibraryUri, 'BuilderInfo', 'add') {
final functionType = _builderInfoAddMethod.getterType as FunctionType;
_typeOfBuilderInfoAddOfNull = Substitution.fromPairs(
functionType.typeParameters, const <DartType>[NullType()])
@@ -130,8 +128,9 @@
List<Field> getInvalidatedFields() {
final fields = <Field>[];
for (var cls in _invalidatedClasses) {
- if (cls._metadataField != null) {
- fields.add(cls._metadataField);
+ final field = cls._metadataField;
+ if (field != null) {
+ fields.add(field);
}
}
_invalidatedClasses.clear();
@@ -143,14 +142,15 @@
++Statistics.protobufMetadataInitializersUpdated;
Statistics.protobufMetadataFieldsPruned -= cls.numberOfFieldsPruned;
- final field = cls._metadataField;
- if (cls._originalInitializer == null) {
- cls._originalInitializer = field.initializer;
+ final field = cls._metadataField!;
+ Expression? originalInitializer = cls._originalInitializer;
+ if (originalInitializer == null) {
+ cls._originalInitializer = originalInitializer = field.initializer!;
}
final cloner = CloneVisitorNotMembers();
- field.initializer = cloner.clone(cls._originalInitializer)..parent = field;
+ field.initializer = cloner.clone(originalInitializer)..parent = field;
final transformer = _MetadataTransformer(this, cls);
- field.initializer.accept(transformer);
+ field.initializer!.accept(transformer);
_invalidatedClasses.remove(cls);
cls.numberOfFieldsPruned = transformer.numberOfFieldsPruned;
@@ -168,8 +168,8 @@
}
class _MessageClass {
- Field _metadataField;
- Expression _originalInitializer;
+ Field? _metadataField;
+ Expression? _originalInitializer;
final _usedTags = <int>{};
int numberOfFieldsPruned = 0;
}
diff --git a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
index a61e222..5ae2e16 100644
--- a/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
+++ b/pkg/vm/lib/transformations/type_flow/signature_shaking.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/external_name.dart';
import 'package:kernel/type_environment.dart';
@@ -57,7 +55,7 @@
SignatureShaker(this.typeFlowAnalysis, this.tableSelectorAssigner);
- _ProcedureInfo _infoForMember(Member member) {
+ _ProcedureInfo? _infoForMember(Member member) {
if (!(member is Procedure &&
(member.kind == ProcedureKind.Method ||
member.kind == ProcedureKind.Factory) ||
@@ -89,7 +87,7 @@
}
while (worklist.isNotEmpty) {
_ParameterInfo param = worklist.removeLast();
- for (_ParameterInfo dependencyParam in param.useDependencies) {
+ for (_ParameterInfo dependencyParam in param.useDependencies!) {
if (!dependencyParam.isRead) {
dependencyParam.isRead = true;
if (dependencyParam.useDependencies != null) {
@@ -141,7 +139,7 @@
return positional.any((param) =>
param.canBeEliminated ||
(param.isAlwaysPassed &&
- param.index >= function.requiredParameterCount)) ||
+ param.index! >= function.requiredParameterCount)) ||
named.values
.any((param) => param.canBeEliminated || param.isAlwaysPassed);
}
@@ -149,7 +147,7 @@
class _ParameterInfo {
final _ProcedureInfo info;
- final int index;
+ final int? index;
int passCount = 0;
bool isRead = false;
@@ -160,7 +158,7 @@
/// List of parameter variables which were passed as arguments via this
/// parameter. When this parameter is considered used, all [useDependencies]
/// parameters should be transitively marked as read.
- List<_ParameterInfo> useDependencies = null;
+ List<_ParameterInfo>? useDependencies = null;
_ParameterInfo(this.info, this.index);
@@ -177,7 +175,7 @@
void observeParameter(
Member member, VariableDeclaration param, SignatureShaker shaker) {
- final Type type = shaker.typeFlowAnalysis.argumentType(member, param);
+ final Type? type = shaker.typeFlowAnalysis.argumentType(member, param);
// A parameter is considered constant if the TFA has inferred it to have a
// constant value in every implementation. The constant value inferred does
@@ -214,19 +212,19 @@
_Collect(this.shaker);
void enterFunction(Member member) {
- final _ProcedureInfo info = shaker._infoForMember(member);
+ final _ProcedureInfo? info = shaker._infoForMember(member);
if (info == null) return;
localParameters.clear();
useDependencies.clear();
- final FunctionNode fun = member.function;
+ final FunctionNode fun = member.function!;
for (int i = 0; i < fun.positionalParameters.length; i++) {
final VariableDeclaration param = fun.positionalParameters[i];
localParameters[param] = info.ensurePositional(i)
..observeParameter(member, param, shaker);
}
for (VariableDeclaration param in fun.namedParameters) {
- localParameters[param] = info.ensureNamed(param.name)
+ localParameters[param] = info.ensureNamed(param.name!)
..observeParameter(member, param, shaker);
}
@@ -270,19 +268,22 @@
void addUseDependency(Expression arg, _ParameterInfo param) {
if (arg is VariableGet) {
- _ParameterInfo localParam = localParameters[arg.variable];
+ _ParameterInfo? localParam = localParameters[arg.variable];
if (localParam != null && !localParam.isUsed) {
// This is a parameter passed as an argument. Mark it as a use
// dependency.
- param.useDependencies ??= [];
- param.useDependencies.add(localParam);
+ var paramUseDependencies = param.useDependencies;
+ if (paramUseDependencies == null) {
+ param.useDependencies = paramUseDependencies = [];
+ }
+ paramUseDependencies.add(localParam);
useDependencies.add(arg);
}
}
}
void collectCall(Member member, Arguments args) {
- final _ProcedureInfo info = shaker._infoForMember(member);
+ final _ProcedureInfo? info = shaker._infoForMember(member);
if (info == null) return;
for (int i = 0; i < args.positional.length; i++) {
@@ -306,7 +307,10 @@
@override
void visitSuperMethodInvocation(SuperMethodInvocation node) {
- collectCall(node.interfaceTarget, node.arguments);
+ final interfaceTarget = node.interfaceTarget;
+ if (interfaceTarget != null) {
+ collectCall(interfaceTarget, node.arguments);
+ }
super.visitSuperMethodInvocation(node);
}
@@ -338,7 +342,7 @@
class _Transform extends RecursiveVisitor {
final SignatureShaker shaker;
- StaticTypeContext typeContext;
+ late StaticTypeContext typeContext;
final Map<VariableDeclaration, Constant> eliminatedParams = {};
final Set<VariableDeclaration> unusedParams = {};
final List<LocalInitializer> addedInitializers = [];
@@ -349,16 +353,15 @@
Member member, _ParameterInfo param, VariableDeclaration variable) {
Constant value;
if (param.isConstant) {
- Type type = shaker.typeFlowAnalysis.argumentType(member, variable);
+ Type type = shaker.typeFlowAnalysis.argumentType(member, variable)!;
if (type is ConcreteType) {
- assert(type.constant != null);
- value = type.constant;
+ value = type.constant!;
} else {
assert(type is NullableType && type.baseType is EmptyType);
value = NullConstant();
}
} else {
- value = (variable.initializer as ConstantExpression)?.constant ??
+ value = (variable.initializer as ConstantExpression?)?.constant ??
NullConstant();
}
eliminatedParams[variable] = value;
@@ -370,10 +373,10 @@
eliminatedParams.clear();
unusedParams.clear();
- final _ProcedureInfo info = shaker._infoForMember(member);
+ final _ProcedureInfo? info = shaker._infoForMember(member);
if (info == null || !info.eligible || info.callCount == 0) return;
- final FunctionNode function = member.function;
+ final FunctionNode function = member.function!;
if (!info.transformNeeded(function)) return;
@@ -404,9 +407,9 @@
// as required positional parameters, alphabetically by name.
final List<VariableDeclaration> sortedNamed = function.namedParameters
.toList()
- ..sort((var1, var2) => var1.name.compareTo(var2.name));
+ ..sort((var1, var2) => var1.name!.compareTo(var2.name!));
for (VariableDeclaration variable in sortedNamed) {
- final _ParameterInfo param = info.named[variable.name];
+ final _ParameterInfo param = info.named[variable.name!]!;
if (param.isAlwaysPassed) {
if (param.isUsed) {
if (param.canBeEliminated) {
@@ -451,7 +454,7 @@
// 4. All named parameters that are not always passed and can't be
// eliminated, as named parameters in alphabetical order.
for (VariableDeclaration variable in sortedNamed) {
- final _ParameterInfo param = info.named[variable.name];
+ final _ParameterInfo param = info.named[variable.name!]!;
if (!param.isAlwaysPassed) {
if (param.isUsed) {
if (param.canBeEliminated) {
@@ -475,7 +478,7 @@
@override
void visitVariableGet(VariableGet node) {
- Constant constantValue = eliminatedParams[node.variable];
+ Constant? constantValue = eliminatedParams[node.variable];
if (constantValue != null) {
node.replaceWith(ConstantExpression(constantValue));
}
@@ -511,7 +514,7 @@
void Function(Expression, _ParameterInfo) fun) {
for (int i = args.named.length - 1; i >= 0; i--) {
final NamedExpression namedExp = args.named[i];
- fun(namedExp.value, info.named[namedExp.name]);
+ fun(namedExp.value, info.named[namedExp.name]!);
}
for (int i = args.positional.length - 1; i >= 0; i--) {
fun(args.positional[i], info.positional[i]);
@@ -519,8 +522,8 @@
}
void transformCall(
- Member target, TreeNode call, Expression receiver, Arguments args) {
- final _ProcedureInfo info = shaker._infoForMember(target);
+ Member target, TreeNode call, Expression? receiver, Arguments args) {
+ final _ProcedureInfo? info = shaker._infoForMember(target);
if (info == null || !info.eligible) return;
bool transformNeeded = false;
@@ -544,7 +547,7 @@
Map<Expression, VariableDeclaration> hoisted = {};
if (hoistingNeeded) {
if (call is Initializer) {
- final Constructor constructor = call.parent;
+ final Constructor constructor = call.parent as Constructor;
forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
if (mayHaveOrSeeSideEffects(arg) && !isUnusedParam(arg)) {
VariableDeclaration argVar = VariableDeclaration(null,
@@ -557,8 +560,8 @@
}
});
} else {
- final TreeNode parent = call.parent;
- Expression current = call;
+ final TreeNode parent = call.parent!;
+ Expression current = call as Expression;
forEachArgumentRev(args, info, (Expression arg, _ParameterInfo param) {
if (mayHaveOrSeeSideEffects(arg) && !isUnusedParam(arg)) {
VariableDeclaration argVar = VariableDeclaration(null,
@@ -606,7 +609,7 @@
final List<NamedExpression> sortedNamed = args.named.toList()
..sort((var1, var2) => var1.name.compareTo(var2.name));
for (NamedExpression arg in sortedNamed) {
- final _ParameterInfo param = info.named[arg.name];
+ final _ParameterInfo param = info.named[arg.name]!;
if (param.isAlwaysPassed && !param.canBeEliminated) {
positional.add(getMaybeHoistedArg(arg.value));
}
@@ -625,7 +628,7 @@
// eliminated, as named parameters in alphabetical order.
// (Arguments are kept in original order.)
for (NamedExpression arg in args.named) {
- final _ParameterInfo param = info.named[arg.name];
+ final _ParameterInfo param = info.named[arg.name]!;
if (!param.isAlwaysPassed && !param.canBeEliminated) {
arg.value = getMaybeHoistedArg(arg.value)..parent = arg;
named.add(arg);
@@ -644,7 +647,10 @@
@override
void visitSuperMethodInvocation(SuperMethodInvocation node) {
super.visitSuperMethodInvocation(node);
- transformCall(node.interfaceTarget, node, null, node.arguments);
+ final interfaceTarget = node.interfaceTarget;
+ if (interfaceTarget != null) {
+ transformCall(interfaceTarget, node, null, node.arguments);
+ }
}
@override
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index dcae2df..fb18cec 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Type flow summary of a member, function or initializer.
-library vm.transformations.type_flow.summary;
import 'dart:core' hide Type;
@@ -18,7 +15,7 @@
abstract class CallHandler {
Type applyCall(Call callSite, Selector selector, Args<Type> args,
- {bool isResultUsed});
+ {required bool isResultUsed});
void typeCheckTriggered();
void addAllocatedClass(Class c);
}
@@ -27,14 +24,10 @@
abstract class Statement extends TypeExpr {
/// Index of this statement in the [Summary].
int index = -1;
- Summary summary;
+ late Summary summary;
@override
- Type getComputedType(List<Type> types) {
- final type = types[index];
- assert(type != null);
- return type;
- }
+ Type getComputedType(List<Type?> types) => types[index]!;
String get label => "t$index";
@@ -48,7 +41,7 @@
void accept(StatementVisitor visitor);
/// Execute this statement and compute its resulting type.
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler);
}
@@ -74,9 +67,9 @@
// [staticType] is null if no narrowing should be performed. This happens for
// type parameters and for parameters whose type is narrowed by a [TypeCheck]
// statement.
- final Type staticTypeForNarrowing;
+ final Type? staticTypeForNarrowing;
- Type defaultValue;
+ Type? defaultValue;
Type _argumentType = const EmptyType();
Parameter(this.name, this.staticTypeForNarrowing);
@@ -97,7 +90,7 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
throw 'Unable to apply _Parameter';
@@ -110,7 +103,7 @@
}
Type _observeNotPassed(TypeHierarchy typeHierarchy) {
- final Type argType = defaultValue.specialize(typeHierarchy);
+ final Type argType = defaultValue!.specialize(typeHierarchy);
_observeArgumentType(argType, typeHierarchy);
return argType;
}
@@ -130,7 +123,7 @@
String dump() => "$label = _Narrow ($arg to $type)";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
arg.getComputedType(computedTypes).intersection(type, typeHierarchy);
}
@@ -147,11 +140,11 @@
// Shared NarrowNotNull instances which are used when the outcome is
// known at summary creation time.
- static final NarrowNotNull alwaysNotNull = NarrowNotNull(null)
+ static final NarrowNotNull alwaysNotNull = NarrowNotNull(const EmptyType())
.._flags = canBeNotNullFlag;
- static final NarrowNotNull alwaysNull = NarrowNotNull(null)
+ static final NarrowNotNull alwaysNull = NarrowNotNull(const EmptyType())
.._flags = canBeNullFlag;
- static final NarrowNotNull unknown = NarrowNotNull(null)
+ static final NarrowNotNull unknown = NarrowNotNull(const EmptyType())
.._flags = canBeNullFlag | canBeNotNullFlag;
bool get isAlwaysNull => (_flags & canBeNotNullFlag) == 0;
@@ -173,14 +166,14 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
handleArgument(arg.getComputedType(computedTypes));
}
/// Joins values from multiple sources. Its type is a union of [values].
class Join extends Statement {
- final String _name;
+ final String? _name;
final DartType staticType;
final List<TypeExpr> values = <TypeExpr>[]; // TODO(alexmarkov): Set
@@ -197,15 +190,14 @@
" (${values.join(", ")})";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- Type type = null;
- assert(values.isNotEmpty);
+ Type? type = null;
for (var value in values) {
final valueType = value.getComputedType(computedTypes);
type = type != null ? type.union(valueType, typeHierarchy) : valueType;
}
- return type;
+ return type!;
}
}
@@ -222,7 +214,7 @@
String dump() => "$label = _Use ($arg)";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) =>
throw 'Use statements should be removed during summary normalization';
}
@@ -231,7 +223,7 @@
class Call extends Statement {
final Selector selector;
final Args<TypeExpr> args;
- final Type staticResultType;
+ final Type? staticResultType;
Call(this.selector, this.args, this.staticResultType,
bool isInstanceCreation) {
@@ -252,9 +244,10 @@
String dump() => "$label${isResultUsed ? '*' : ''} = _Call $selector $args";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- final List<Type> argTypes = new List<Type>.filled(args.values.length, null);
+ final List<Type> argTypes =
+ new List<Type>.filled(args.values.length, const EmptyType());
for (int i = 0; i < args.values.length; i++) {
final Type type = args.values[i].getComputedType(computedTypes);
if (type == const EmptyType()) {
@@ -271,14 +264,15 @@
callHandler
.addAllocatedClass((argTypes[0] as ConcreteType).cls.classNode);
}
- final Stopwatch timer = kPrintTimings ? (new Stopwatch()..start()) : null;
+ final Stopwatch? timer = kPrintTimings ? (new Stopwatch()..start()) : null;
Type result = callHandler.applyCall(
this, selector, new Args<Type>(argTypes, names: args.names),
isResultUsed: isResultUsed);
- summary.calleeTime += kPrintTimings ? timer.elapsedMicroseconds : 0;
+ summary.calleeTime += kPrintTimings ? timer!.elapsedMicroseconds : 0;
if (isInstanceCreation) {
result = argTypes[0];
} else if (isResultUsed) {
+ final staticResultType = this.staticResultType;
if (staticResultType != null) {
result = result.intersection(staticResultType, typeHierarchy);
}
@@ -302,9 +296,9 @@
static const int kReceiverMayBeInt = (1 << 6);
static const int kInstanceCreation = (1 << 7);
- Member _monomorphicTarget;
+ Member? _monomorphicTarget;
- Member get monomorphicTarget => _monomorphicTarget;
+ Member? get monomorphicTarget => _monomorphicTarget;
bool get isMonomorphic => (_flags & kMonomorphic) != 0;
@@ -396,18 +390,19 @@
"/$paramIndex]${nullability.suffix})";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
Type argType = arg.getComputedType(computedTypes);
- Type extractedType;
+ Type? extractedType;
void extractType(ConcreteType c) {
- if (c.typeArgs == null) {
+ final typeArgs = c.typeArgs;
+ if (typeArgs == null) {
extractedType = const UnknownType();
} else {
final interfaceOffset = typeHierarchy.genericInterfaceOffsetFor(
c.cls.classNode, referenceClass);
- final typeArg = c.typeArgs[interfaceOffset + paramIndex];
+ final typeArg = typeArgs[interfaceOffset + paramIndex];
Type extracted = typeArg;
if (typeArg is RuntimeType) {
final argNullability = typeArg.nullability;
@@ -472,16 +467,15 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
bool hasRuntimeType = false;
- final types = new List<Type>.filled(flattenedTypeArgs.length, null);
- for (int i = 0; i < types.length; ++i) {
+ final types = List<Type>.generate(flattenedTypeArgs.length, (int i) {
final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
assert(computed is RuntimeType || computed is UnknownType);
if (computed is RuntimeType) hasRuntimeType = true;
- types[i] = computed;
- }
+ return computed;
+ });
return new ConcreteType(cls, hasRuntimeType ? types : null);
}
}
@@ -505,14 +499,13 @@
"${nullability.suffix})";
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- final types = new List<RuntimeType>.filled(flattenedTypeArgs.length, null);
- for (int i = 0; i < types.length; ++i) {
- final computed = flattenedTypeArgs[i].getComputedType(computedTypes);
- assert(computed is RuntimeType || computed is UnknownType);
+ final types = <RuntimeType>[];
+ for (TypeExpr arg in flattenedTypeArgs) {
+ final computed = arg.getComputedType(computedTypes);
if (computed is UnknownType) return const UnknownType();
- types[i] = computed;
+ types.add(computed as RuntimeType);
}
DartType dartType;
if (klass == typeHierarchy.coreTypes.deprecatedFutureOrClass) {
@@ -545,17 +538,15 @@
// "unchecked" entrypoint.
bool isTestedOnlyOnCheckedEntryPoint;
- VariableDeclaration get parameter =>
- node is VariableDeclaration ? node : null;
+ bool get isParameterCheck => node is VariableDeclaration;
+ VariableDeclaration get parameterVariable => node as VariableDeclaration;
bool alwaysPass = true;
bool alwaysFail = true;
- TypeCheck(this.arg, this.type, this.node, this.staticType, this.kind) {
- assert(node != null);
- isTestedOnlyOnCheckedEntryPoint =
- parameter != null && !parameter.isCovariant;
- }
+ TypeCheck(this.arg, this.type, this.node, this.staticType, this.kind)
+ : isTestedOnlyOnCheckedEntryPoint =
+ node is VariableDeclaration && !node.isCovariant;
@override
void accept(StatementVisitor visitor) => visitor.visitTypeCheck(this);
@@ -568,7 +559,7 @@
}
@override
- Type apply(List<Type> computedTypes, TypeHierarchy typeHierarchy,
+ Type apply(List<Type?> computedTypes, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
Type argType = arg.getComputedType(computedTypes);
Type checkType = type.getComputedType(computedTypes);
@@ -624,11 +615,11 @@
int requiredParameterCount;
List<Statement> _statements = <Statement>[];
- TypeExpr result = null;
- Type resultType = EmptyType();
+ TypeExpr result = const EmptyType();
+ Type resultType = const EmptyType();
// Analysis time of callees. Populated only if kPrintTimings.
- int calleeTime;
+ int calleeTime = 0;
Summary(this.name,
{this.parameterCount: 0,
@@ -658,7 +649,7 @@
/// Apply this summary to the given arguments and return the resulting type.
Type apply(Args<Type> arguments, TypeHierarchy typeHierarchy,
CallHandler callHandler) {
- final Stopwatch timer = kPrintTimings ? (new Stopwatch()..start()) : null;
+ final Stopwatch? timer = kPrintTimings ? (new Stopwatch()..start()) : null;
final int oldCalleeTime = calleeTime;
calleeTime = 0;
final args = arguments.values;
@@ -677,7 +668,7 @@
//
// The first `parameterCount` statements are Parameters.
- List<Type> types = new List<Type>.filled(_statements.length, null);
+ List<Type?> types = new List<Type?>.filled(_statements.length, null);
for (int i = 0; i < positionalArgCount; i++) {
final Parameter param = _statements[i] as Parameter;
@@ -687,9 +678,9 @@
}
final argType = args[i].specialize(typeHierarchy);
param._observeArgumentType(argType, typeHierarchy);
- if (param.staticTypeForNarrowing != null) {
- types[i] =
- argType.intersection(param.staticTypeForNarrowing, typeHierarchy);
+ final staticTypeForNarrowing = param.staticTypeForNarrowing;
+ if (staticTypeForNarrowing != null) {
+ types[i] = argType.intersection(staticTypeForNarrowing, typeHierarchy);
} else {
// TODO(sjindel/tfa): Narrowing is performed inside a [TypeCheck] later.
types[i] = args[i];
@@ -710,9 +701,10 @@
args[positionalArgCount + argIndex].specialize(typeHierarchy);
argIndex++;
param._observeArgumentType(argType, typeHierarchy);
- if (param.staticTypeForNarrowing != null) {
+ final staticTypeForNarrowing = param.staticTypeForNarrowing;
+ if (staticTypeForNarrowing != null) {
types[i] =
- argType.intersection(param.staticTypeForNarrowing, typeHierarchy);
+ argType.intersection(staticTypeForNarrowing, typeHierarchy);
} else {
types[i] = argType;
}
@@ -741,7 +733,7 @@
resultType = resultType.union(computedType, typeHierarchy);
if (kPrintTimings) {
- final dirtyTime = timer.elapsedMicroseconds;
+ final dirtyTime = timer!.elapsedMicroseconds;
final pureTime = dirtyTime < calleeTime ? 0 : (dirtyTime - calleeTime);
Statistics.numSummaryApplications.add(name);
Statistics.dirtySummaryAnalysisTime.add(name, dirtyTime);
@@ -753,9 +745,9 @@
}
Args<Type> get argumentTypes {
- final argTypes = new List<Type>.filled(parameterCount, null);
- final argNames = new List<String>.filled(
- parameterCount - positionalParameterCount, null);
+ final argTypes = new List<Type>.filled(parameterCount, const EmptyType());
+ final argNames =
+ new List<String>.filled(parameterCount - positionalParameterCount, '');
for (int i = 0; i < parameterCount; i++) {
Parameter param = _statements[i] as Parameter;
argTypes[i] = param.argumentType;
@@ -769,7 +761,7 @@
Type argumentType(Member member, VariableDeclaration memberParam) {
final int firstParamIndex =
numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final positional = member.function.positionalParameters;
+ final positional = member.function!.positionalParameters;
for (int i = 0; i < positional.length; i++) {
if (positional[i] == memberParam) {
final Parameter param = _statements[firstParamIndex + i] as Parameter;
@@ -791,8 +783,8 @@
for (Statement statement in _statements) {
if (statement is TypeCheck &&
statement.alwaysPass &&
- statement.parameter != null) {
- params.add(statement.parameter);
+ statement.isParameterCheck) {
+ params.add(statement.parameterVariable);
}
}
return params;
@@ -808,17 +800,17 @@
(hasReceiverArg(member) ? 1 : 0) + numTypeParams(member);
final Map<String, Parameter> paramsByName = {};
for (int i = implicit; i < parameterCount; i++) {
- final Parameter param = statements[i];
+ final Parameter param = statements[i] as Parameter;
paramsByName[param.name] = param;
}
- FunctionNode function = member.function;
+ FunctionNode function = member.function!;
statements.length = implicit;
for (VariableDeclaration param in function.positionalParameters) {
- statements.add(paramsByName[param.name]);
+ statements.add(paramsByName[param.name]!);
}
positionalParameterCount = statements.length;
for (VariableDeclaration param in function.namedParameters) {
- statements.add(paramsByName[param.name]);
+ statements.add(paramsByName[param.name]!);
}
parameterCount = statements.length;
requiredParameterCount = implicit + function.requiredParameterCount;
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index cd78792..d2157f7 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Creation of type flow summaries out of kernel AST.
-library vm.transformations.type_flow.summary_collector;
import 'dart:core' hide Type;
@@ -14,6 +11,7 @@
import 'package:kernel/ast.dart' as ast show Statement, StatementVisitor;
import 'package:kernel/class_hierarchy.dart'
show ClassHierarchy, ClosedWorldClassHierarchy;
+import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/type_environment.dart'
show StaticTypeContext, SubtypeCheckMode, TypeEnvironment;
import 'package:kernel/type_algebra.dart' show Substitution;
@@ -239,7 +237,7 @@
// function and checks if control can fall through them or not.
bool controlCanFallThrough(FunctionNode function) {
- return function.body.accept(this);
+ return function.body!.accept(this);
}
@override
@@ -285,11 +283,11 @@
bool visitContinueSwitchStatement(ContinueSwitchStatement node) => false;
@override
- bool visitIfStatement(IfStatement node) =>
- node.then == null ||
- node.otherwise == null ||
- node.then.accept(this) ||
- node.otherwise.accept(this);
+ bool visitIfStatement(IfStatement node) {
+ final otherwise = node.otherwise;
+ if (otherwise == null) return true;
+ return node.then.accept(this) || otherwise.accept(this);
+ }
@override
bool visitReturnStatement(ReturnStatement node) => false;
@@ -323,7 +321,7 @@
final List<VariableDeclaration> varDeclarations = <VariableDeclaration>[];
/// Set of captured variables.
- Set<VariableDeclaration> captured;
+ Set<VariableDeclaration>? captured;
/// Set of variables which were modified for each loop, switch statement
/// and try block statement. Doesn't include captured variables and
@@ -334,10 +332,10 @@
int numVariablesAtFunctionEntry = 0;
/// Active loops, switch statements and try blocks.
- List<ast.Statement> activeStatements;
+ List<ast.Statement>? activeStatements;
/// Number of variables at entry of active statements.
- List<int> numVariablesAtActiveStatements;
+ List<int>? numVariablesAtActiveStatements;
_VariablesInfoCollector(Member member) {
member.accept(this);
@@ -345,8 +343,10 @@
int get numVariables => varDeclarations.length;
- bool isCaptured(VariableDeclaration variable) =>
- captured != null && captured.contains(variable);
+ bool isCaptured(VariableDeclaration variable) {
+ final captured = this.captured;
+ return captured != null && captured.contains(variable);
+ }
Set<int> getModifiedVariables(ast.Statement st) {
return modifiedSets[st] ?? const <int>{};
@@ -387,14 +387,15 @@
}
void _useVariable(VariableDeclaration variable, bool isVarAssignment) {
- final index = varIndex[variable];
+ final index = varIndex[variable]!;
if (_isDeclaredBefore(index, numVariablesAtFunctionEntry)) {
_captureVariable(variable);
return;
}
+ final activeStatements = this.activeStatements;
if (isVarAssignment && activeStatements != null) {
for (int i = activeStatements.length - 1; i >= 0; --i) {
- if (_isDeclaredBefore(index, numVariablesAtActiveStatements[i])) {
+ if (_isDeclaredBefore(index, numVariablesAtActiveStatements![i])) {
final st = activeStatements[i];
(modifiedSets[st] ??= <int>{}).add(index);
} else {
@@ -410,8 +411,8 @@
}
void _endCollectingModifiedVariables() {
- activeStatements.removeLast();
- numVariablesAtActiveStatements.removeLast();
+ activeStatements!.removeLast();
+ numVariablesAtActiveStatements!.removeLast();
}
@override
@@ -457,7 +458,7 @@
@override
visitTryCatch(TryCatch node) {
_startCollectingModifiedVariables(node);
- node.body?.accept(this);
+ node.body.accept(this);
_endCollectingModifiedVariables();
visitList(node.catches, this);
}
@@ -465,9 +466,9 @@
@override
visitTryFinally(TryFinally node) {
_startCollectingModifiedVariables(node);
- node.body?.accept(this);
+ node.body.accept(this);
_endCollectingModifiedVariables();
- node.finalizer?.accept(this);
+ node.finalizer.accept(this);
}
@override
@@ -489,7 +490,7 @@
visitList(node.variables, this);
_startCollectingModifiedVariables(node);
node.condition?.accept(this);
- node.body?.accept(this);
+ node.body.accept(this);
visitList(node.updates, this);
_endCollectingModifiedVariables();
}
@@ -521,7 +522,7 @@
enum FieldSummaryType { kFieldGuard, kInitializer }
/// Create a type flow summary for a member from the kernel AST.
-class SummaryCollector extends RecursiveResultVisitor<TypeExpr> {
+class SummaryCollector extends RecursiveResultVisitor<TypeExpr?> {
final Target target;
final TypeEnvironment _environment;
final ClosedWorldClassHierarchy _hierarchy;
@@ -529,7 +530,7 @@
final TypesBuilder _typesBuilder;
final NativeCodeOracle _nativeCodeOracle;
final GenericInterfacesInfo _genericInterfacesInfo;
- final ProtobufHandler _protobufHandler;
+ final ProtobufHandler? _protobufHandler;
final Map<TreeNode, Call> callSites = <TreeNode, Call>{};
final Map<AsExpression, TypeCheck> explicitCasts =
@@ -540,13 +541,13 @@
final Set<Name> _nullMethodsAndGetters = <Name>{};
final Set<Name> _nullSetters = <Name>{};
- Summary _summary;
- _VariablesInfoCollector _variablesInfo;
+ Summary _summary = Summary('<unused>');
+ late _VariablesInfoCollector _variablesInfo;
// Current value of each variable. May contain null if variable is not
// declared yet, or EmptyType if current location is unreachable
// (e.g. after return or throw).
- List<TypeExpr> _variableValues;
+ List<TypeExpr?> _variableValues = const <TypeExpr?>[];
// Contains Joins which accumulate all values of certain variables.
// Used only when all variable values should be merged regardless of control
@@ -558,30 +559,30 @@
// If _variableCells[i] != null, then all values are accumulated in the
// _variableCells[i]. _variableValues[i] does not change and remains equal
// to _variableCells[i].
- List<Join> _variableCells;
+ List<Join?> _variableCells = const <Join?>[];
// Counts number of Joins inserted for each variable. Only used to set
// readable names for such joins (foo_0, foo_1 etc.)
- List<int> _variableVersions;
+ List<int> _variableVersions = const <int>[];
// State of variables after corresponding LabeledStatement.
// Used to collect states from BreakStatements.
- Map<LabeledStatement, List<TypeExpr>> _variableValuesAfterLabeledStatements;
+ Map<LabeledStatement, List<TypeExpr?>>? _variableValuesAfterLabeledStatements;
// Joins corresponding to variables on entry to switch cases.
// Used to propagate state from ContinueSwitchStatement to a target case.
- Map<SwitchCase, List<Join>> _joinsAtSwitchCases;
+ Map<SwitchCase, List<Join?>>? _joinsAtSwitchCases;
// Join which accumulates all return values.
- Join _returnValue;
+ Join? _returnValue;
- Parameter _receiver;
- ConstantAllocationCollector constantAllocationCollector;
- RuntimeTypeTranslatorImpl _translator;
- StaticTypeContext _staticTypeContext;
+ Parameter? _receiver;
+ late ConstantAllocationCollector constantAllocationCollector;
+ late RuntimeTypeTranslatorImpl _translator;
+ StaticTypeContext? _staticTypeContext;
// Currently only used for factory constructors.
- Map<TypeParameter, TypeExpr> _fnTypeVariables;
+ Map<TypeParameter, TypeExpr>? _fnTypeVariables;
SummaryCollector(
this.target,
@@ -592,7 +593,6 @@
this._nativeCodeOracle,
this._genericInterfacesInfo,
this._protobufHandler) {
- assert(_genericInterfacesInfo != null);
constantAllocationCollector = new ConstantAllocationCollector(this);
_nullMethodsAndGetters.addAll(getSelectors(
_hierarchy, _environment.coreTypes.deprecatedNullClass,
@@ -615,8 +615,8 @@
_staticTypeContext = new StaticTypeContext(member, _environment);
_variablesInfo = new _VariablesInfoCollector(member);
_variableValues =
- new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
- _variableCells = new List<Join>.filled(_variablesInfo.numVariables, null);
+ new List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
+ _variableCells = new List<Join?>.filled(_variablesInfo.numVariables, null);
_variableVersions = new List<int>.filled(_variablesInfo.numVariables, 0);
_variableValuesAfterLabeledStatements = null;
_joinsAtSwitchCases = null;
@@ -633,25 +633,24 @@
parameterCount: numArgs, positionalParameterCount: numArgs);
// TODO(alexmarkov): subclass cone
_receiver = _declareParameter("this",
- _environment.coreTypes.legacyRawType(member.enclosingClass), null,
+ _environment.coreTypes.legacyRawType(member.enclosingClass!), null,
isReceiver: true);
} else {
_summary = new Summary(summaryName);
}
- _translator = new RuntimeTypeTranslatorImpl(
- this, _summary, _receiver, null, _genericInterfacesInfo);
+ _translator = new RuntimeTypeTranslatorImpl(_environment.coreTypes,
+ _summary, _receiver, null, _genericInterfacesInfo);
if (fieldSummaryType == FieldSummaryType.kInitializer) {
- assert(member.initializer != null);
- _summary.result = _visit(member.initializer);
+ _summary.result = _visit(member.initializer!);
} else {
final Parameter valueParam =
_declareParameter("value", member.type, null);
_summary.result = _typeCheck(valueParam, member.type, member);
}
} else {
- FunctionNode function = member.function;
+ final FunctionNode function = member.function!;
final numTypeParameters = numTypeParams(member);
final firstParamIndex = (hasReceiver ? 1 : 0) + numTypeParameters;
@@ -666,43 +665,42 @@
firstParamIndex + function.requiredParameterCount);
if (numTypeParameters > 0) {
- _fnTypeVariables = <TypeParameter, TypeExpr>{};
- for (int i = 0; i < numTypeParameters; ++i) {
- _fnTypeVariables[function.typeParameters[i]] =
- _declareParameter(function.typeParameters[i].name, null, null);
- }
+ _fnTypeVariables = <TypeParameter, TypeExpr>{
+ for (TypeParameter tp in function.typeParameters)
+ tp: _declareParameter(tp.name!, null, null)
+ };
}
if (hasReceiver) {
// TODO(alexmarkov): subclass cone
_receiver = _declareParameter("this",
- _environment.coreTypes.legacyRawType(member.enclosingClass), null,
+ _environment.coreTypes.legacyRawType(member.enclosingClass!), null,
isReceiver: true);
}
- _translator = new RuntimeTypeTranslatorImpl(
- this, _summary, _receiver, _fnTypeVariables, _genericInterfacesInfo);
+ _translator = new RuntimeTypeTranslatorImpl(_environment.coreTypes,
+ _summary, _receiver, _fnTypeVariables, _genericInterfacesInfo);
// Handle forwarding stubs. We need to check types against the types of
// the forwarding stub's target, [member.concreteForwardingStubTarget].
- FunctionNode useTypesFrom = member.function;
- if (member is Procedure &&
- member.isForwardingStub &&
- member.concreteForwardingStubTarget != null) {
+ FunctionNode useTypesFrom = function;
+ if (member is Procedure && member.isForwardingStub) {
final target = member.concreteForwardingStubTarget;
- if (target is Field) {
- useTypesFrom = FunctionNode(null, positionalParameters: [
- VariableDeclaration("value", type: target.type)
- ]);
- } else {
- useTypesFrom = member.concreteForwardingStubTarget.function;
+ if (target != null) {
+ if (target is Field) {
+ useTypesFrom = FunctionNode(null, positionalParameters: [
+ VariableDeclaration("value", type: target.type)
+ ]);
+ } else {
+ useTypesFrom = target.function!;
+ }
}
}
for (int i = 0; i < function.positionalParameters.length; ++i) {
final decl = function.positionalParameters[i];
_declareParameter(
- decl.name,
+ decl.name!,
_useTypeCheckForParameter(decl)
? null
: useTypesFrom.positionalParameters[i].type,
@@ -711,7 +709,7 @@
for (int i = 0; i < function.namedParameters.length; ++i) {
final decl = function.namedParameters[i];
_declareParameter(
- decl.name,
+ decl.name!,
_useTypeCheckForParameter(decl)
? null
: useTypesFrom.namedParameters[i].type,
@@ -740,7 +738,7 @@
assert(count == _summary.parameterCount);
_returnValue = new Join("%result", function.returnType);
- _summary.add(_returnValue);
+ _summary.add(_returnValue!);
if (member is Constructor) {
// Make sure instance field initializers are visited.
@@ -750,7 +748,7 @@
new DirectSelector(f, callKind: CallKind.FieldInitializer));
}
}
- member.initializers.forEach(_visit);
+ member.initializers.forEach(_visitWithoutResult);
}
if (function.body == null) {
@@ -760,15 +758,15 @@
// Runtime type could be more precise than static type, so
// calculate intersection.
final typeCheck = _typeCheck(type, function.returnType, function);
- _returnValue.values.add(typeCheck);
+ _returnValue!.values.add(typeCheck);
} else {
- _returnValue.values.add(type);
+ _returnValue!.values.add(type);
}
} else {
- _visit(function.body);
+ _visitWithoutResult(function.body!);
if (_fallthroughDetector.controlCanFallThrough(function)) {
- _returnValue.values.add(_nullType);
+ _returnValue!.values.add(_nullType);
}
}
@@ -776,15 +774,15 @@
// In addition to what is returned from the function body,
// operator == performs implicit comparison with null
// and returns bool.
- _returnValue.values.add(_boolType);
+ _returnValue!.values.add(_boolType);
}
- _summary.result = _returnValue;
+ _summary.result = _returnValue!;
}
member.annotations.forEach(_visit);
- member.enclosingClass?.annotations?.forEach(_visit);
- member.enclosingLibrary?.annotations?.forEach(_visit);
+ member.enclosingClass?.annotations.forEach(_visit);
+ member.enclosingLibrary.annotations.forEach(_visit);
_staticTypeContext = null;
@@ -808,9 +806,7 @@
}
Args<Type> rawArguments(Selector selector) {
- final member = selector.member;
- assert(member != null);
-
+ final member = selector.member!;
final List<Type> args = <Type>[];
final List<String> names = <String>[];
@@ -822,15 +818,14 @@
if (hasReceiverArg(member)) {
assert(member.enclosingClass != null);
final receiver =
- new ConeType(_typesBuilder.getTFClass(member.enclosingClass));
+ new ConeType(_typesBuilder.getTFClass(member.enclosingClass!));
args.add(receiver);
}
switch (selector.callKind) {
case CallKind.Method:
if (member is! Field) {
- final function = member.function;
- assert(function != null);
+ final function = member.function!;
final int paramCount = function.positionalParameters.length +
function.namedParameters.length;
@@ -840,7 +835,7 @@
if (function.namedParameters.isNotEmpty) {
for (var param in function.namedParameters) {
- names.add(param.name);
+ names.add(param.name!);
}
// TODO(dartbug.com/32292): make sure parameters are sorted in
// kernel AST and remove this sorting.
@@ -864,11 +859,15 @@
return new Args<Type>(args, names: names);
}
- TypeExpr _visit(TreeNode node) => node.accept(this);
+ TypeExpr _visit(Expression node) => node.accept(this)!;
- Args<TypeExpr> _visitArguments(TypeExpr receiver, Arguments arguments,
+ void _visitWithoutResult(TreeNode node) {
+ node.accept(this);
+ }
+
+ Args<TypeExpr> _visitArguments(TypeExpr? receiver, Arguments arguments,
{bool passTypeArguments: false}) {
- final args = <TypeExpr>[];
+ final List<TypeExpr> args = <TypeExpr>[];
if (passTypeArguments) {
for (var type in arguments.types) {
args.add(_translator.translate(type));
@@ -890,7 +889,7 @@
}
names.sort();
for (var name in names) {
- args.add(map[name]);
+ args.add(map[name]!);
}
return new Args<TypeExpr>(args, names: names);
} else {
@@ -899,9 +898,9 @@
}
Parameter _declareParameter(
- String name, DartType type, Expression initializer,
+ String name, DartType? type, Expression? initializer,
{bool isReceiver: false}) {
- Type staticType;
+ Type? staticType;
if (type != null) {
staticType = _typesBuilder.fromStaticType(type, !isReceiver);
}
@@ -916,7 +915,7 @@
} else if (initializer is BasicLiteral ||
initializer is SymbolLiteral ||
initializer is TypeLiteral) {
- param.defaultValue = _visit(initializer);
+ param.defaultValue = _visit(initializer) as Type;
} else {
throw 'Unexpected parameter $name default value ${initializer.runtimeType} $initializer';
}
@@ -930,8 +929,7 @@
}
void _declareVariable(VariableDeclaration decl, TypeExpr initialValue) {
- final int varIndex = _variablesInfo.varIndex[decl];
- assert(varIndex != null);
+ final int varIndex = _variablesInfo.varIndex[decl]!;
assert(_variablesInfo.varDeclarations[varIndex] == decl);
assert(_variableValues[varIndex] == null);
if (_variablesInfo.isCaptured(decl)) {
@@ -944,8 +942,8 @@
}
void _writeVariable(VariableDeclaration variable, TypeExpr value) {
- final int varIndex = _variablesInfo.varIndex[variable];
- final Join join = _variableCells[varIndex];
+ final int varIndex = _variablesInfo.varIndex[variable]!;
+ final Join? join = _variableCells[varIndex];
if (join != null) {
join.values.add(value);
} else {
@@ -953,11 +951,12 @@
}
}
- List<TypeExpr> _cloneVariableValues(List<TypeExpr> values) =>
- new List<TypeExpr>.from(values);
+ List<TypeExpr?> _cloneVariableValues(List<TypeExpr?> values) =>
+ new List<TypeExpr?>.from(values);
- List<TypeExpr> _makeEmptyVariableValues() {
- final values = new List<TypeExpr>.filled(_variablesInfo.numVariables, null);
+ List<TypeExpr?> _makeEmptyVariableValues() {
+ final values =
+ new List<TypeExpr?>.filled(_variablesInfo.numVariables, null);
for (int i = 0; i < values.length; ++i) {
if (_variableCells[i] != null) {
values[i] = _variableValues[i];
@@ -978,11 +977,11 @@
return join;
}
- void _mergeVariableValues(List<TypeExpr> dst, List<TypeExpr> src) {
+ void _mergeVariableValues(List<TypeExpr?> dst, List<TypeExpr?> src) {
assert(dst.length == src.length);
for (int i = 0; i < dst.length; ++i) {
- final TypeExpr dstValue = dst[i];
- final TypeExpr srcValue = src[i];
+ final TypeExpr? dstValue = dst[i];
+ final TypeExpr? srcValue = src[i];
if (identical(dstValue, srcValue)) {
continue;
}
@@ -997,21 +996,21 @@
} else if (srcValue is Join && srcValue.values.contains(dstValue)) {
dst[i] = srcValue;
} else {
- final Join join = _makeJoin(i, dst[i]);
- join.values.add(src[i]);
+ final Join join = _makeJoin(i, dstValue);
+ join.values.add(srcValue);
dst[i] = join;
}
}
}
- void _copyVariableValues(List<TypeExpr> dst, List<TypeExpr> src) {
+ void _copyVariableValues(List<TypeExpr?> dst, List<TypeExpr?> src) {
assert(dst.length == src.length);
for (int i = 0; i < dst.length; ++i) {
dst[i] = src[i];
}
}
- bool _isIdenticalState(List<TypeExpr> state1, List<TypeExpr> state2) {
+ bool _isIdenticalState(List<TypeExpr?> state1, List<TypeExpr?> state2) {
assert(state1.length == state2.length);
for (int i = 0; i < state1.length; ++i) {
if (!identical(state1[i], state2[i])) {
@@ -1021,14 +1020,14 @@
return true;
}
- List<Join> _insertJoinsForModifiedVariables(TreeNode node, bool isTry) {
- final List<Join> joins =
- new List<Join>.filled(_variablesInfo.numVariables, null);
+ List<Join?> _insertJoinsForModifiedVariables(ast.Statement node, bool isTry) {
+ final List<Join?> joins =
+ new List<Join?>.filled(_variablesInfo.numVariables, null);
for (var i in _variablesInfo.getModifiedVariables(node)) {
if (_variableCells[i] != null) {
assert(_variableCells[i] == _variableValues[i]);
} else {
- final join = _makeJoin(i, _variableValues[i]);
+ final join = _makeJoin(i, _variableValues[i]!);
joins[i] = join;
_variableValues[i] = join;
if (isTry) {
@@ -1044,7 +1043,7 @@
/// Stops accumulating values in [joins] by removing them from
/// _variableCells.
- void _restoreVariableCellsAfterTry(List<Join> joins) {
+ void _restoreVariableCellsAfterTry(List<Join?> joins) {
for (int i = 0; i < joins.length; ++i) {
if (joins[i] != null) {
assert(_variableCells[i] == joins[i]);
@@ -1053,14 +1052,14 @@
}
}
- void _mergeVariableValuesToJoins(List<TypeExpr> values, List<Join> joins) {
+ void _mergeVariableValuesToJoins(List<TypeExpr?> values, List<Join?> joins) {
for (int i = 0; i < joins.length; ++i) {
final join = joins[i];
final value = values[i];
if (join != null &&
!identical(join, value) &&
!identical(join.values.first, value)) {
- join.values.add(value);
+ join.values.add(value!);
}
}
}
@@ -1079,16 +1078,17 @@
// TODO(alexmarkov): Avoid declaring variables with static types.
void _declareVariableWithStaticType(VariableDeclaration decl) {
- if (decl.initializer != null) {
- _visit(decl.initializer);
+ final initializer = decl.initializer;
+ if (initializer != null) {
+ _visit(initializer);
}
_declareVariable(decl, _typesBuilder.fromStaticType(decl.type, true));
}
Call _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args,
{bool isInstanceCreation = false}) {
- Type staticResultType = null;
- Member target;
+ Type? staticResultType = null;
+ Member? target;
if (selector is DirectSelector) {
target = selector.member;
} else if (selector is InterfaceSelector) {
@@ -1101,9 +1101,7 @@
}
Call call = new Call(selector, args, staticResultType, isInstanceCreation);
_summary.add(call);
- if (node != null) {
- callSites[node] = call;
- }
+ callSites[node] = call;
return call;
}
@@ -1189,53 +1187,43 @@
}
DartType _staticDartType(Expression node) =>
- node.getStaticType(_staticTypeContext);
+ node.getStaticType(_staticTypeContext!);
Type _staticType(Expression node) =>
_typesBuilder.fromStaticType(_staticDartType(node), true);
- ConcreteType _cachedBoolType;
- ConcreteType get _boolType => _cachedBoolType ??=
+ late final ConcreteType _boolType =
_entryPointsListener.addAllocatedClass(_environment.coreTypes.boolClass);
- ConcreteType _cachedBoolTrue;
- ConcreteType get _boolTrue => _cachedBoolTrue ??=
- new ConcreteType(_boolType.cls, null, BoolConstant(true));
+ late final ConcreteType _boolTrue =
+ ConcreteType(_boolType.cls, null, BoolConstant(true));
- ConcreteType _cachedBoolFalse;
- ConcreteType get _boolFalse => _cachedBoolFalse ??=
- new ConcreteType(_boolType.cls, null, BoolConstant(false));
+ late final ConcreteType _boolFalse =
+ ConcreteType(_boolType.cls, null, BoolConstant(false));
- Type _cachedDoubleType;
- Type get _doubleType => _cachedDoubleType ??= new ConeType(
- _typesBuilder.getTFClass(_environment.coreTypes.doubleClass));
+ late final Type _doubleType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.doubleClass));
- Type _cachedIntType;
- Type get _intType => _cachedIntType ??=
- new ConeType(_typesBuilder.getTFClass(_environment.coreTypes.intClass));
+ late final Type _intType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.intClass));
- Type _cachedStringType;
- Type get _stringType => _cachedStringType ??= new ConeType(
- _typesBuilder.getTFClass(_environment.coreTypes.stringClass));
+ late final Type _stringType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.stringClass));
- Type _cachedSymbolType;
- Type get _symbolType => _cachedSymbolType ??= new ConeType(
- _typesBuilder.getTFClass(_environment.coreTypes.symbolClass));
+ late final Type _symbolType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.symbolClass));
- Type _cachedTypeType;
- Type get _typeType => _cachedTypeType ??=
- new ConeType(_typesBuilder.getTFClass(_environment.coreTypes.typeClass));
+ late final Type _typeType =
+ ConeType(_typesBuilder.getTFClass(_environment.coreTypes.typeClass));
- Type _cachedNullType;
- Type get _nullType =>
- _cachedNullType ??= new Type.nullable(const EmptyType());
+ late final Type _nullType = Type.nullable(const EmptyType());
- Class get _superclass => _staticTypeContext.thisType.classNode.superclass;
+ Class get _superclass => _staticTypeContext!.thisType!.classNode.superclass!;
Type _boolLiteralType(bool value) => value ? _boolTrue : _boolFalse;
- Type _intLiteralType(int value, Constant constant) {
- final Class concreteClass =
+ Type _intLiteralType(int value, Constant? constant) {
+ final Class? concreteClass =
target.concreteIntLiteralClass(_environment.coreTypes, value);
if (concreteClass != null) {
constant ??= IntConstant(value);
@@ -1247,8 +1235,8 @@
return _intType;
}
- Type _doubleLiteralType(double value, Constant constant) {
- final Class concreteClass =
+ Type _doubleLiteralType(double value, Constant? constant) {
+ final Class? concreteClass =
target.concreteDoubleLiteralClass(_environment.coreTypes, value);
if (concreteClass != null) {
constant ??= DoubleConstant(value);
@@ -1260,8 +1248,8 @@
return _doubleType;
}
- Type _stringLiteralType(String value, Constant constant) {
- final Class concreteClass =
+ Type _stringLiteralType(String value, Constant? constant) {
+ final Class? concreteClass =
target.concreteStringLiteralClass(_environment.coreTypes, value);
if (concreteClass != null) {
constant ??= StringConstant(value);
@@ -1284,7 +1272,7 @@
node.positionalParameters.forEach(_declareVariableWithStaticType);
node.namedParameters.forEach(_declareVariableWithStaticType);
- _visit(node.body);
+ _visitWithoutResult(node.body!);
_variableValues = savedVariableValues;
_returnValue = savedReturn;
@@ -1307,8 +1295,7 @@
for (Class c
in _hierarchy.computeSubtypesInformation().getSubtypesOf(cls)) {
if (!c.isAbstract) {
- final candidate = _hierarchy.getDispatchTarget(c, _equalsName);
- assert(candidate != null);
+ final candidate = _hierarchy.getDispatchTarget(c, _equalsName)!;
assert(!candidate.isAbstract);
if (candidate != _environment.coreTypes.objectEquals) {
_cachedHasOverriddenEquals[cls] = true;
@@ -1328,12 +1315,12 @@
// On exit _variableValues is null, so caller should explicitly pick
// either trueState or falseState.
void _visitCondition(
- Expression node, List<TypeExpr> trueState, List<TypeExpr> falseState) {
+ Expression node, List<TypeExpr?> trueState, List<TypeExpr?> falseState) {
assert(_isIdenticalState(_variableValues, trueState));
assert(_isIdenticalState(_variableValues, falseState));
if (node is Not) {
_visitCondition(node.operand, falseState, trueState);
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is LogicalExpression) {
final isOR = (node.operatorEnum == LogicalExpressionOperator.OR);
@@ -1351,7 +1338,7 @@
_visitCondition(node.right, trueState, falseStateAfterRHS);
_mergeVariableValues(falseState, falseStateAfterRHS);
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is VariableGet ||
(node is AsExpression && node.operand is VariableGet)) {
@@ -1359,12 +1346,12 @@
_addUse(_visit(node));
final variableGet =
(node is AsExpression ? node.operand : node) as VariableGet;
- final int varIndex = _variablesInfo.varIndex[variableGet.variable];
+ final int varIndex = _variablesInfo.varIndex[variableGet.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = _boolTrue;
falseState[varIndex] = _boolFalse;
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is EqualsCall && node.left is VariableGet) {
final lhs = node.left as VariableGet;
@@ -1379,11 +1366,11 @@
!_hasOverriddenEquals(lhs.variable.type))) {
// 'x == c', where x is a variable and c is a constant.
_addUse(_visit(node));
- final int varIndex = _variablesInfo.varIndex[lhs.variable];
+ final int varIndex = _variablesInfo.varIndex[lhs.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = _visit(rhs);
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
}
} else if (node is EqualsNull && node.expression is VariableGet) {
@@ -1393,12 +1380,12 @@
_makeCall(node, DirectSelector(_environment.coreTypes.objectEquals),
Args<TypeExpr>([expr, _nullType]));
final narrowedNotNull = _makeNarrowNotNull(node, expr);
- final int varIndex = _variablesInfo.varIndex[lhs.variable];
+ final int varIndex = _variablesInfo.varIndex[lhs.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = _nullType;
falseState[varIndex] = narrowedNotNull;
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
} else if (node is IsExpression && node.operand is VariableGet) {
// Handle 'x is T', where x is a variable.
@@ -1406,17 +1393,17 @@
final TypeCheck typeCheck =
_typeCheck(_visit(operand), node.type, node, SubtypeTestKind.IsTest);
isTests[node] = typeCheck;
- final int varIndex = _variablesInfo.varIndex[operand.variable];
+ final int varIndex = _variablesInfo.varIndex[operand.variable]!;
if (_variableCells[varIndex] == null) {
trueState[varIndex] = typeCheck;
}
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
return;
}
_addUse(_visit(node));
_copyVariableValues(trueState, _variableValues);
_copyVariableValues(falseState, _variableValues);
- _variableValues = null;
+ _variableValues = const <TypeExpr?>[]; // Should not be used.
}
void _updateReceiverAfterCall(
@@ -1425,7 +1412,7 @@
if (receiverNode is VariableGet) {
final nullSelectors = isSetter ? _nullSetters : _nullMethodsAndGetters;
if (!nullSelectors.contains(selector)) {
- final int varIndex = _variablesInfo.varIndex[receiverNode.variable];
+ final int varIndex = _variablesInfo.varIndex[receiverNode.variable]!;
if (_variableCells[varIndex] == null) {
_variableValues[varIndex] =
_makeNarrow(receiverValue, const AnyType());
@@ -1434,9 +1421,8 @@
}
}
- Procedure _cachedUnsafeCast;
- Procedure get unsafeCast => _cachedUnsafeCast ??= _environment.coreTypes.index
- .getTopLevelMember('dart:_internal', 'unsafeCast');
+ late final Procedure unsafeCast = _environment.coreTypes.index
+ .getTopLevelProcedure('dart:_internal', 'unsafeCast');
@override
defaultTreeNode(TreeNode node) =>
@@ -1446,10 +1432,10 @@
TypeExpr visitAsExpression(AsExpression node) {
final operandNode = node.operand;
final TypeExpr operand = _visit(operandNode);
- final TypeExpr result = _typeCheck(operand, node.type, node);
+ final TypeCheck result = _typeCheck(operand, node.type, node);
explicitCasts[node] = result;
if (operandNode is VariableGet) {
- final int varIndex = _variablesInfo.varIndex[operandNode.variable];
+ final int varIndex = _variablesInfo.varIndex[operandNode.variable]!;
if (_variableCells[varIndex] == null) {
_variableValues[varIndex] = result;
}
@@ -1462,7 +1448,7 @@
final operandNode = node.operand;
final TypeExpr result = _makeNarrowNotNull(node, _visit(operandNode));
if (operandNode is VariableGet) {
- final int varIndex = _variablesInfo.varIndex[operandNode.variable];
+ final int varIndex = _variablesInfo.varIndex[operandNode.variable]!;
if (_variableCells[varIndex] == null) {
_variableValues[varIndex] = result;
}
@@ -1549,20 +1535,20 @@
@override
TypeExpr visitLet(Let node) {
- _declareVariable(node.variable, _visit(node.variable.initializer));
+ _declareVariable(node.variable, _visit(node.variable.initializer!));
return _visit(node.body);
}
@override
TypeExpr visitBlockExpression(BlockExpression node) {
- _visit(node.body);
+ _visitWithoutResult(node.body);
return _visit(node.value);
}
@override
TypeExpr visitListLiteral(ListLiteral node) {
node.expressions.forEach(_visit);
- Class concreteClass =
+ Class? concreteClass =
target.concreteListLiteralClass(_environment.coreTypes);
if (concreteClass != null) {
return _translator.instantiateConcreteType(
@@ -1588,7 +1574,7 @@
_visit(entry.key);
_visit(entry.value);
}
- Class concreteClass =
+ Class? concreteClass =
target.concreteMapLiteralClass(_environment.coreTypes);
if (concreteClass != null) {
return _translator.instantiateConcreteType(
@@ -1690,7 +1676,7 @@
}
TypeExpr _handlePropertyGet(
- TreeNode node, Expression receiverNode, Member target, Name selector) {
+ TreeNode node, Expression receiverNode, Member? target, Name selector) {
var receiver = _visit(receiverNode);
var args = new Args<TypeExpr>([receiver]);
TypeExpr result;
@@ -1779,8 +1765,7 @@
@override
TypeExpr visitSuperPropertyGet(SuperPropertyGet node) {
assert(kPartialMixinResolution);
- assert(_receiver != null, "Should have receiver. Node: $node");
- final args = new Args<TypeExpr>([_receiver]);
+ final args = new Args<TypeExpr>([_receiver!]);
// Re-resolve target due to partial mixin resolution.
final target = _hierarchy.getDispatchTarget(_superclass, node.name);
if (target == null) {
@@ -1794,9 +1779,8 @@
@override
TypeExpr visitSuperPropertySet(SuperPropertySet node) {
assert(kPartialMixinResolution);
- assert(_receiver != null, "Should have receiver. Node: $node");
final value = _visit(node.value);
- final args = new Args<TypeExpr>([_receiver, value]);
+ final args = new Args<TypeExpr>([_receiver!, value]);
// Re-resolve target due to partial mixin resolution.
final target =
_hierarchy.getDispatchTarget(_superclass, node.name, setter: true);
@@ -1882,8 +1866,7 @@
@override
TypeExpr visitThisExpression(ThisExpression node) {
- assert(_receiver != null, "Should have receiver. Node: $node");
- return _receiver;
+ return _receiver!;
}
@override
@@ -1900,7 +1883,7 @@
@override
TypeExpr visitVariableGet(VariableGet node) {
- final v = _variableValues[_variablesInfo.varIndex[node.variable]];
+ final v = _variableValues[_variablesInfo.varIndex[node.variable]!];
if (v == null) {
throw 'Unable to find variable ${node.variable} at ${node.location}';
}
@@ -1925,56 +1908,60 @@
}
@override
- TypeExpr visitAssertStatement(AssertStatement node) {
+ TypeExpr? visitAssertStatement(AssertStatement node) {
if (!kRemoveAsserts) {
_addUse(_visit(node.condition));
- if (node.message != null) {
- _visit(node.message);
+ final message = node.message;
+ if (message != null) {
+ _visit(message);
}
}
return null;
}
@override
- TypeExpr visitBlock(Block node) {
- node.statements.forEach(_visit);
+ TypeExpr? visitBlock(Block node) {
+ node.statements.forEach(_visitWithoutResult);
return null;
}
@override
- TypeExpr visitAssertBlock(AssertBlock node) {
+ TypeExpr? visitAssertBlock(AssertBlock node) {
if (!kRemoveAsserts) {
- node.statements.forEach(_visit);
+ node.statements.forEach(_visitWithoutResult);
}
return null;
}
@override
- TypeExpr visitBreakStatement(BreakStatement node) {
- _variableValuesAfterLabeledStatements ??=
- <LabeledStatement, List<TypeExpr>>{};
- final state = _variableValuesAfterLabeledStatements[node.target];
+ TypeExpr? visitBreakStatement(BreakStatement node) {
+ var afterLabels = _variableValuesAfterLabeledStatements;
+ if (afterLabels == null) {
+ _variableValuesAfterLabeledStatements =
+ afterLabels = <LabeledStatement, List<TypeExpr?>>{};
+ }
+ final state = afterLabels[node.target];
if (state != null) {
_mergeVariableValues(state, _variableValues);
} else {
- _variableValuesAfterLabeledStatements[node.target] = _variableValues;
+ afterLabels[node.target] = _variableValues;
}
_variableValues = _makeEmptyVariableValues();
return null;
}
@override
- TypeExpr visitContinueSwitchStatement(ContinueSwitchStatement node) {
+ TypeExpr? visitContinueSwitchStatement(ContinueSwitchStatement node) {
_mergeVariableValuesToJoins(
- _variableValues, _joinsAtSwitchCases[node.target]);
+ _variableValues, _joinsAtSwitchCases![node.target]!);
_variableValues = _makeEmptyVariableValues();
return null;
}
@override
- TypeExpr visitDoStatement(DoStatement node) {
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
- _visit(node.body);
+ TypeExpr? visitDoStatement(DoStatement node) {
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
+ _visitWithoutResult(node.body);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
_visitCondition(node.condition, trueState, falseState);
@@ -1988,39 +1975,39 @@
}
@override
- TypeExpr visitEmptyStatement(EmptyStatement node) => null;
+ TypeExpr? visitEmptyStatement(EmptyStatement node) => null;
@override
- TypeExpr visitExpressionStatement(ExpressionStatement node) {
+ TypeExpr? visitExpressionStatement(ExpressionStatement node) {
_visit(node.expression);
return null;
}
@override
- TypeExpr visitForInStatement(ForInStatement node) {
+ TypeExpr? visitForInStatement(ForInStatement node) {
_visit(node.iterable);
// TODO(alexmarkov): try to infer more precise type from 'iterable'
_declareVariableWithStaticType(node.variable);
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final stateAfterLoop = _cloneVariableValues(_variableValues);
- _visit(node.body);
+ _visitWithoutResult(node.body);
_mergeVariableValuesToJoins(_variableValues, joins);
_variableValues = stateAfterLoop;
return null;
}
@override
- TypeExpr visitForStatement(ForStatement node) {
+ TypeExpr? visitForStatement(ForStatement node) {
node.variables.forEach(visitVariableDeclaration);
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
if (node.condition != null) {
- _visitCondition(node.condition, trueState, falseState);
+ _visitCondition(node.condition!, trueState, falseState);
}
_variableValues = trueState;
- _visit(node.body);
+ _visitWithoutResult(node.body);
node.updates.forEach(_visit);
_mergeVariableValuesToJoins(_variableValues, joins);
// Kernel represents 'break;' as a BreakStatement referring to a
@@ -2032,7 +2019,7 @@
}
@override
- TypeExpr visitFunctionDeclaration(FunctionDeclaration node) {
+ TypeExpr? visitFunctionDeclaration(FunctionDeclaration node) {
// TODO(alexmarkov): support function types.
node.variable.annotations.forEach(_visit);
_declareVariableWithStaticType(node.variable);
@@ -2041,18 +2028,18 @@
}
@override
- TypeExpr visitIfStatement(IfStatement node) {
+ TypeExpr? visitIfStatement(IfStatement node) {
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
_visitCondition(node.condition, trueState, falseState);
_variableValues = trueState;
- _visit(node.then);
+ _visitWithoutResult(node.then);
final stateAfter = _variableValues;
_variableValues = falseState;
if (node.otherwise != null) {
- _visit(node.otherwise);
+ _visitWithoutResult(node.otherwise!);
}
_mergeVariableValues(stateAfter, _variableValues);
@@ -2061,8 +2048,8 @@
}
@override
- TypeExpr visitLabeledStatement(LabeledStatement node) {
- _visit(node.body);
+ TypeExpr? visitLabeledStatement(LabeledStatement node) {
+ _visitWithoutResult(node.body);
final state = _variableValuesAfterLabeledStatements?.remove(node);
if (state != null) {
_mergeVariableValues(_variableValues, state);
@@ -2071,34 +2058,35 @@
}
@override
- TypeExpr visitReturnStatement(ReturnStatement node) {
- TypeExpr ret =
- (node.expression != null) ? _visit(node.expression) : _nullType;
- if (_returnValue != null) {
- _returnValue.values.add(ret);
- }
+ TypeExpr? visitReturnStatement(ReturnStatement node) {
+ final expression = node.expression;
+ TypeExpr ret = (expression != null) ? _visit(expression) : _nullType;
+ _returnValue?.values.add(ret);
_variableValues = _makeEmptyVariableValues();
return null;
}
@override
- TypeExpr visitSwitchStatement(SwitchStatement node) {
+ TypeExpr? visitSwitchStatement(SwitchStatement node) {
_visit(node.expression);
// Insert joins at each case in case there are 'continue' statements.
final stateOnEntry = _variableValues;
- final variableValuesAtCaseEntry = <SwitchCase, List<TypeExpr>>{};
- _joinsAtSwitchCases ??= <SwitchCase, List<Join>>{};
+ final variableValuesAtCaseEntry = <SwitchCase, List<TypeExpr?>>{};
+ Map<SwitchCase, List<Join?>>? joinsAtSwitchCases = _joinsAtSwitchCases;
+ if (joinsAtSwitchCases == null) {
+ _joinsAtSwitchCases = joinsAtSwitchCases = <SwitchCase, List<Join?>>{};
+ }
for (var switchCase in node.cases) {
_variableValues = _cloneVariableValues(stateOnEntry);
- _joinsAtSwitchCases[switchCase] =
+ joinsAtSwitchCases[switchCase] =
_insertJoinsForModifiedVariables(node, false);
variableValuesAtCaseEntry[switchCase] = _variableValues;
}
bool hasDefault = false;
for (var switchCase in node.cases) {
- _variableValues = variableValuesAtCaseEntry[switchCase];
+ _variableValues = variableValuesAtCaseEntry[switchCase]!;
switchCase.expressions.forEach(_visit);
- _visit(switchCase.body);
+ _visitWithoutResult(switchCase.body);
hasDefault = hasDefault || switchCase.isDefault;
}
if (!hasDefault) {
@@ -2108,21 +2096,21 @@
}
@override
- TypeExpr visitTryCatch(TryCatch node) {
+ TypeExpr? visitTryCatch(TryCatch node) {
final joins = _insertJoinsForModifiedVariables(node, true);
final stateAfterTry = _cloneVariableValues(_variableValues);
- _visit(node.body);
+ _visitWithoutResult(node.body);
_restoreVariableCellsAfterTry(joins);
- List<TypeExpr> stateAfterCatch;
+ List<TypeExpr?>? stateAfterCatch;
for (var catchClause in node.catches) {
_variableValues = _cloneVariableValues(stateAfterTry);
if (catchClause.exception != null) {
- _declareVariableWithStaticType(catchClause.exception);
+ _declareVariableWithStaticType(catchClause.exception!);
}
if (catchClause.stackTrace != null) {
- _declareVariableWithStaticType(catchClause.stackTrace);
+ _declareVariableWithStaticType(catchClause.stackTrace!);
}
- _visit(catchClause.body);
+ _visitWithoutResult(catchClause.body);
if (stateAfterCatch == null) {
stateAfterCatch = _variableValues;
} else {
@@ -2130,38 +2118,39 @@
}
}
_variableValues = stateAfterTry;
- _mergeVariableValues(_variableValues, stateAfterCatch);
+ _mergeVariableValues(_variableValues, stateAfterCatch!);
return null;
}
@override
- TypeExpr visitTryFinally(TryFinally node) {
+ TypeExpr? visitTryFinally(TryFinally node) {
final joins = _insertJoinsForModifiedVariables(node, true);
final stateAfterTry = _cloneVariableValues(_variableValues);
- _visit(node.body);
+ _visitWithoutResult(node.body);
_restoreVariableCellsAfterTry(joins);
_variableValues = stateAfterTry;
- _visit(node.finalizer);
+ _visitWithoutResult(node.finalizer);
return null;
}
@override
- TypeExpr visitVariableDeclaration(VariableDeclaration node) {
+ TypeExpr? visitVariableDeclaration(VariableDeclaration node) {
node.annotations.forEach(_visit);
+ final initializer = node.initializer;
final TypeExpr initialValue =
- node.initializer == null ? _nullType : _visit(node.initializer);
+ initializer == null ? _nullType : _visit(initializer);
_declareVariable(node, initialValue);
return null;
}
@override
- TypeExpr visitWhileStatement(WhileStatement node) {
- final List<Join> joins = _insertJoinsForModifiedVariables(node, false);
+ TypeExpr? visitWhileStatement(WhileStatement node) {
+ final List<Join?> joins = _insertJoinsForModifiedVariables(node, false);
final trueState = _cloneVariableValues(_variableValues);
final falseState = _cloneVariableValues(_variableValues);
_visitCondition(node.condition, trueState, falseState);
_variableValues = trueState;
- _visit(node.body);
+ _visitWithoutResult(node.body);
_mergeVariableValuesToJoins(_variableValues, joins);
// Kernel represents 'break;' as a BreakStatement referring to a
// LabeledStatement. We are therefore guaranteed to always have the
@@ -2172,15 +2161,15 @@
}
@override
- TypeExpr visitYieldStatement(YieldStatement node) {
+ TypeExpr? visitYieldStatement(YieldStatement node) {
_visit(node.expression);
return null;
}
@override
- TypeExpr visitFieldInitializer(FieldInitializer node) {
+ TypeExpr? visitFieldInitializer(FieldInitializer node) {
final value = _visit(node.value);
- final args = new Args<TypeExpr>([_receiver, value]);
+ final args = new Args<TypeExpr>([_receiver!, value]);
_makeCall(
node,
new DirectSelector(node.field,
@@ -2190,17 +2179,17 @@
}
@override
- TypeExpr visitRedirectingInitializer(RedirectingInitializer node) {
+ TypeExpr? visitRedirectingInitializer(RedirectingInitializer node) {
final args = _visitArguments(_receiver, node.arguments);
_makeCall(node, new DirectSelector(node.target), args);
return null;
}
@override
- TypeExpr visitSuperInitializer(SuperInitializer node) {
+ TypeExpr? visitSuperInitializer(SuperInitializer node) {
final args = _visitArguments(_receiver, node.arguments);
- Constructor target = null;
+ Constructor? target = null;
if (kPartialMixinResolution) {
// Re-resolve target due to partial mixin resolution.
for (var replacement in _superclass.constructors) {
@@ -2212,27 +2201,26 @@
} else {
target = node.target;
}
- assert(target != null);
- _makeCall(node, new DirectSelector(target), args);
+ _makeCall(node, new DirectSelector(target!), args);
return null;
}
@override
- TypeExpr visitLocalInitializer(LocalInitializer node) {
+ TypeExpr? visitLocalInitializer(LocalInitializer node) {
visitVariableDeclaration(node.variable);
return null;
}
@override
- TypeExpr visitAssertInitializer(AssertInitializer node) {
+ TypeExpr? visitAssertInitializer(AssertInitializer node) {
if (!kRemoveAsserts) {
- _visit(node.statement);
+ _visitWithoutResult(node.statement);
}
return null;
}
@override
- TypeExpr visitInvalidInitializer(InvalidInitializer node) {
+ TypeExpr? visitInvalidInitializer(InvalidInitializer node) {
return null;
}
@@ -2244,21 +2232,21 @@
class RuntimeTypeTranslatorImpl extends DartTypeVisitor<TypeExpr>
implements RuntimeTypeTranslator {
- final Summary summary;
- final Map<TypeParameter, TypeExpr> functionTypeVariables;
+ final CoreTypes coreTypes;
+ final Summary? summary;
+ final Map<TypeParameter, TypeExpr>? functionTypeVariables;
final Map<DartType, TypeExpr> typesCache = <DartType, TypeExpr>{};
- final TypeExpr receiver;
+ final TypeExpr? receiver;
final GenericInterfacesInfo genericInterfacesInfo;
- final SummaryCollector summaryCollector;
- RuntimeTypeTranslatorImpl(this.summaryCollector, this.summary, this.receiver,
+ RuntimeTypeTranslatorImpl(this.coreTypes, this.summary, this.receiver,
this.functionTypeVariables, this.genericInterfacesInfo) {}
// Create a type translator which can be used only for types with no free type
// variables.
- RuntimeTypeTranslatorImpl.forClosedTypes(this.genericInterfacesInfo)
- : summaryCollector = null,
- summary = null,
+ RuntimeTypeTranslatorImpl.forClosedTypes(
+ this.coreTypes, this.genericInterfacesInfo)
+ : summary = null,
functionTypeVariables = null,
receiver = null {}
@@ -2271,8 +2259,7 @@
final substitution = Substitution.fromPairs(klass.typeParameters, typeArgs);
final flattenedTypeArgs =
genericInterfacesInfo.flattenedTypeArgumentsFor(klass);
- final flattenedTypeExprs =
- new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
+ final flattenedTypeExprs = <TypeExpr>[];
bool createConcreteType = true;
bool allUnknown = true;
@@ -2281,7 +2268,7 @@
translate(substitution.substituteType(flattenedTypeArgs[i]));
if (typeExpr is! UnknownType) allUnknown = false;
if (typeExpr is Statement) createConcreteType = false;
- flattenedTypeExprs[i] = typeExpr;
+ flattenedTypeExprs.add(typeExpr);
}
if (allUnknown) return type;
@@ -2291,7 +2278,7 @@
type.cls, new List<Type>.from(flattenedTypeExprs));
} else {
final instantiate = new CreateConcreteType(type.cls, flattenedTypeExprs);
- summary.add(instantiate);
+ summary!.add(instantiate);
return instantiate;
}
}
@@ -2341,8 +2328,7 @@
type.classNode.typeParameters, type.typeArguments);
final flattenedTypeArgs =
genericInterfacesInfo.flattenedTypeArgumentsFor(type.classNode);
- final flattenedTypeExprs =
- new List<TypeExpr>.filled(flattenedTypeArgs.length, null);
+ final flattenedTypeExprs = <TypeExpr>[];
bool createRuntimeType = true;
for (var i = 0; i < flattenedTypeArgs.length; ++i) {
@@ -2350,7 +2336,7 @@
translate(substitution.substituteType(flattenedTypeArgs[i]));
if (typeExpr == const UnknownType()) return const UnknownType();
if (typeExpr is! RuntimeType) createRuntimeType = false;
- flattenedTypeExprs[i] = typeExpr;
+ flattenedTypeExprs.add(typeExpr);
}
if (createRuntimeType) {
@@ -2360,7 +2346,7 @@
} else {
final instantiate = new CreateRuntimeType(
type.classNode, type.nullability, flattenedTypeExprs);
- summary.add(instantiate);
+ summary!.add(instantiate);
return instantiate;
}
}
@@ -2375,32 +2361,32 @@
<RuntimeType>[typeArg]);
} else {
final instantiate = new CreateRuntimeType(
- summaryCollector._environment.coreTypes.deprecatedFutureOrClass,
+ coreTypes.deprecatedFutureOrClass,
type.nullability,
<TypeExpr>[typeArg]);
- summary.add(instantiate);
+ summary!.add(instantiate);
return instantiate;
}
}
@override
visitTypeParameterType(TypeParameterType type) {
+ final functionTypeVariables = this.functionTypeVariables;
if (functionTypeVariables != null) {
final result = functionTypeVariables[type.parameter];
if (result != null) return result;
}
if (type.parameter.parent is! Class) return const UnknownType();
final interfaceClass = type.parameter.parent as Class;
- assert(receiver != null);
// Undetermined nullability is equivalent to nonNullable when
// instantiating type parameter, so convert it right away.
Nullability nullability = type.nullability;
if (nullability == Nullability.undetermined) {
nullability = Nullability.nonNullable;
}
- final extract = new Extract(receiver, interfaceClass,
+ final extract = new Extract(receiver!, interfaceClass,
interfaceClass.typeParameters.indexOf(type.parameter), nullability);
- summary.add(extract);
+ summary!.add(extract);
return extract;
}
}
@@ -2420,7 +2406,7 @@
Type _getStaticType(Constant constant) =>
summaryCollector._typesBuilder.fromStaticType(
- constant.getType(summaryCollector._staticTypeContext), false);
+ constant.getType(summaryCollector._staticTypeContext!), false);
@override
defaultConstant(Constant constant) {
@@ -2467,7 +2453,7 @@
for (final Constant entry in constant.entries) {
typeFor(entry);
}
- final Class concreteClass = summaryCollector.target
+ final Class? concreteClass = summaryCollector.target
.concreteConstListLiteralClass(summaryCollector._environment.coreTypes);
if (concreteClass != null) {
return new ConcreteType(
diff --git a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
index f1901e7..0080748 100644
--- a/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
+++ b/pkg/vm/lib/transformations/type_flow/table_selector_assigner.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'utils.dart' show UnionFind;
@@ -18,7 +16,7 @@
final Map<Class, Map<Name, int>> _methodOrSetterMemberIds = {};
final UnionFind _unionFind = UnionFind();
- List<int> _selectorIdForMemberId;
+ late List<int?> _selectorIdForMemberId;
TableSelectorAssigner(Component component) {
for (Library library in component.libraries) {
@@ -44,20 +42,21 @@
}
}
- Map<Name, int> _memberIdsForClass(Class cls, {bool getter}) {
+ Map<Name, int> _memberIdsForClass(Class? cls, {required bool getter}) {
if (cls == null) return {};
final cache = getter ? _getterMemberIds : _methodOrSetterMemberIds;
// Already computed for this class?
- Map<Name, int> memberIds = cache[cls];
- if (memberIds != null) return memberIds;
+ final cachedMemberIds = cache[cls];
+ if (cachedMemberIds != null) return cachedMemberIds;
// Merge maps from supertypes.
- memberIds = Map.from(_memberIdsForClass(cls.superclass, getter: getter));
+ final memberIds =
+ Map<Name, int>.from(_memberIdsForClass(cls.superclass, getter: getter));
for (Supertype impl in cls.implementedTypes) {
_memberIdsForClass(impl.classNode, getter: getter).forEach((name, id) {
- final int firstId = memberIds[name];
+ final int? firstId = memberIds[name];
if (firstId == null) {
memberIds[name] = id;
} else if (firstId != id) {
@@ -99,9 +98,9 @@
return cache[cls] = memberIds;
}
- int _selectorIdForMember(Member member, {bool getter}) {
+ int _selectorIdForMember(Member member, {required bool getter}) {
final map = getter ? _getterMemberIds : _methodOrSetterMemberIds;
- int memberId = map[member.enclosingClass][member.name];
+ int? memberId = map[member.enclosingClass!]![member.name];
if (memberId == null) {
assert(member is Procedure &&
((identical(map, _getterMemberIds) &&
@@ -115,7 +114,7 @@
return ProcedureAttributesMetadata.kInvalidSelectorId;
}
memberId = _unionFind.find(memberId);
- int selectorId = _selectorIdForMemberId[memberId];
+ int? selectorId = _selectorIdForMemberId[memberId];
if (selectorId == null) {
_selectorIdForMemberId[memberId] = selectorId = metadata.addSelector();
}
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index feb185d..82bebec 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Transformations based on type flow analysis.
-library vm.transformations.type_flow.transformer;
import 'dart:core' hide Type;
@@ -14,7 +11,8 @@
import 'package:kernel/ast.dart' as ast show Statement;
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/class_hierarchy.dart'
+ show ClassHierarchy, ClosedWorldClassHierarchy;
import 'package:kernel/library_index.dart' show LibraryIndex;
import 'package:kernel/type_environment.dart';
@@ -43,16 +41,18 @@
/// Assumes strong mode and closed world.
Component transformComponent(
Target target, CoreTypes coreTypes, Component component,
- {PragmaAnnotationParser matcher,
+ {PragmaAnnotationParser? matcher,
bool treeShakeSignatures: true,
bool treeShakeWriteOnlyFields: true,
bool treeShakeProtobufs: false}) {
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
final hierarchy = new ClassHierarchy(component, coreTypes,
- onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+ onAmbiguousSupertypes: ignoreAmbiguousSupertypes)
+ as ClosedWorldClassHierarchy;
final types = new TypeEnvironment(coreTypes, hierarchy);
final libraryIndex = new LibraryIndex.all(component);
- final genericInterfacesInfo = new GenericInterfacesInfoImpl(hierarchy);
+ final genericInterfacesInfo =
+ new GenericInterfacesInfoImpl(coreTypes, hierarchy);
final protobufHandler = treeShakeProtobufs
? ProtobufHandler.forComponent(component, coreTypes)
: null;
@@ -73,7 +73,7 @@
protobufHandler,
matcher);
- Procedure main = component.mainMethod;
+ Procedure? main = component.mainMethod;
// `main` can be null, roots can also come from @pragma("vm:entry-point").
if (main != null) {
@@ -149,7 +149,7 @@
if (!f.isStatic &&
!f.isLate &&
f.initializer != null &&
- mayHaveSideEffects(f.initializer))
+ mayHaveSideEffects(f.initializer!))
f
];
if (fields.isEmpty) return;
@@ -173,7 +173,7 @@
};
final List<Initializer> newInitializers = [];
for (Field f in fields) {
- Expression initExpr = f.initializer;
+ Expression initExpr = f.initializer!;
if (!isFirst) {
initExpr = CloneVisitorNotMembers().clone(initExpr);
}
@@ -204,7 +204,7 @@
class CleanupAnnotations extends RecursiveVisitor {
final Class externalNameClass;
final Class pragmaClass;
- final ProtobufHandler protobufHandler;
+ final ProtobufHandler? protobufHandler;
CleanupAnnotations(
CoreTypes coreTypes, LibraryIndex index, this.protobufHandler)
@@ -238,7 +238,7 @@
return (cls == externalNameClass) ||
(cls == pragmaClass) ||
(protobufHandler != null &&
- protobufHandler.usesAnnotationClass(cls));
+ protobufHandler!.usesAnnotationClass(cls));
}
}
return false;
@@ -255,11 +255,11 @@
: super(_typeFlowAnalysis.environment.coreTypes, component, hierarchy);
@override
- DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
+ DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
{bool setter = false}) {
final callSite = _typeFlowAnalysis.callSite(node);
if (callSite != null) {
- final Member singleTarget = fieldMorpher
+ final Member? singleTarget = fieldMorpher
.getMorphedMember(callSite.monomorphicTarget, isSetter: setter);
if (singleTarget != null) {
return new DirectCallMetadata(
@@ -283,12 +283,13 @@
final UnboxingInfoMetadataRepository _unboxingInfoMetadata;
final UnboxingInfoManager _unboxingInfo;
final Class _intClass;
- Constant _nullConstant;
+ late final Constant _nullConstant = NullConstant();
AnnotateKernel(Component component, this._typeFlowAnalysis, this.fieldMorpher,
this._tableSelectorAssigner, this._unboxingInfo)
: _directCallMetadataRepository =
- component.metadata[DirectCallMetadataRepository.repositoryTag],
+ component.metadata[DirectCallMetadataRepository.repositoryTag]
+ as DirectCallMetadataRepository,
_inferredTypeMetadata = new InferredTypeMetadataRepository(),
_unreachableNodeMetadata = new UnreachableNodeMetadataRepository(),
_procedureAttributesMetadata =
@@ -308,12 +309,10 @@
return _directCallMetadataRepository.mapping.containsKey(node);
}
- InferredType _convertType(Type type,
+ InferredType? _convertType(Type type,
{bool skipCheck: false, bool receiverNotInt: false}) {
- assert(type != null);
-
- Class concreteClass;
- Constant constantValue;
+ Class? concreteClass;
+ Constant? constantValue;
bool isInt = false;
final nullable = type is NullableType;
@@ -324,7 +323,7 @@
if (nullable && type == const EmptyType()) {
concreteClass =
_typeFlowAnalysis.environment.coreTypes.deprecatedNullClass;
- constantValue = _nullConstant ??= new NullConstant();
+ constantValue = _nullConstant;
} else {
concreteClass = type.getConcreteClass(_typeFlowAnalysis.hierarchyCache);
@@ -337,9 +336,9 @@
}
}
- List<DartType> typeArgs;
+ List<DartType?>? typeArgs;
if (type is ConcreteType && type.typeArgs != null) {
- typeArgs = type.typeArgs
+ typeArgs = type.typeArgs!
.take(type.numImmediateTypeArgs)
.map((t) =>
t is UnknownType ? null : (t as RuntimeType).representedType)
@@ -374,7 +373,7 @@
_unreachableNodeMetadata.mapping[node] = const UnreachableNode();
}
- void _annotateCallSite(TreeNode node, Member interfaceTarget) {
+ void _annotateCallSite(TreeNode node, Member? interfaceTarget) {
final callSite = _typeFlowAnalysis.callSite(node);
if (callSite == null) return;
if (!callSite.isReachable) {
@@ -405,7 +404,7 @@
if (interfaceTarget == null ||
_typeFlowAnalysis.hierarchyCache.hierarchy.isSubtypeOf(
_typeFlowAnalysis.hierarchyCache.coreTypes.intClass,
- interfaceTarget.enclosingClass)) {
+ interfaceTarget.enclosingClass!)) {
markReceiverNotInt = true;
}
}
@@ -446,35 +445,33 @@
void _annotateMember(Member member) {
if (_typeFlowAnalysis.isMemberUsed(member)) {
if (member is Field) {
- _setInferredType(member, _typeFlowAnalysis.fieldType(member));
+ _setInferredType(member, _typeFlowAnalysis.fieldType(member)!);
} else {
- Args<Type> argTypes = _typeFlowAnalysis.argumentTypes(member);
+ Args<Type> argTypes = _typeFlowAnalysis.argumentTypes(member)!;
final uncheckedParameters =
_typeFlowAnalysis.uncheckedParameters(member);
- assert(argTypes != null);
final int firstParamIndex =
numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final positionalParams = member.function.positionalParameters;
+ final positionalParams = member.function!.positionalParameters;
assert(argTypes.positionalCount ==
firstParamIndex + positionalParams.length);
for (int i = 0; i < positionalParams.length; i++) {
_setInferredType(
positionalParams[i], argTypes.values[firstParamIndex + i],
- skipCheck: uncheckedParameters.contains(positionalParams[i]));
+ skipCheck: uncheckedParameters!.contains(positionalParams[i]));
}
// TODO(dartbug.com/32292): make sure parameters are sorted in kernel
// AST and iterate parameters in parallel, without lookup.
final names = argTypes.names;
for (int i = 0; i < names.length; i++) {
- final param = findNamedParameter(member.function, names[i]);
- assert(param != null);
+ final param = findNamedParameter(member.function!, names[i])!;
_setInferredType(param,
argTypes.values[firstParamIndex + positionalParams.length + i],
- skipCheck: uncheckedParameters.contains(param));
+ skipCheck: uncheckedParameters!.contains(param));
}
// TODO(alexmarkov): figure out how to pass receiver type.
@@ -521,7 +518,7 @@
// interface target, and table dispatch calls need selector IDs for all
// interface targets.
if (member.isInstanceMember) {
- final original = fieldMorpher.getOriginalMember(member);
+ final original = fieldMorpher.getOriginalMember(member)!;
final attrs = new ProcedureAttributesMetadata(
methodOrSetterCalledDynamically:
_typeFlowAnalysis.isCalledDynamically(original),
@@ -689,11 +686,11 @@
final Set<Member> _usedMembers = new Set<Member>();
final Set<Extension> _usedExtensions = new Set<Extension>();
final Set<Typedef> _usedTypedefs = new Set<Typedef>();
- FieldMorpher fieldMorpher;
- _TreeShakerTypeVisitor typeVisitor;
- _TreeShakerConstantVisitor constantVisitor;
- _TreeShakerPass1 _pass1;
- _TreeShakerPass2 _pass2;
+ late final FieldMorpher fieldMorpher;
+ late final _TreeShakerTypeVisitor typeVisitor;
+ late final _TreeShakerConstantVisitor constantVisitor;
+ late final _TreeShakerPass1 _pass1;
+ late final _TreeShakerPass2 _pass2;
TreeShaker(Component component, this.typeFlowAnalysis,
{this.treeShakeWriteOnlyFields: true}) {
@@ -734,7 +731,7 @@
(!f.isStatic &&
f.initializer != null &&
isFieldInitializerReachable(f) &&
- mayHaveSideEffects(f.initializer)) ||
+ mayHaveSideEffects(f.initializer!)) ||
(f.isLate && f.isFinal)) ||
isMemberReferencedFromNativeCode(f) ||
_isInstanceFieldOfAllocatedEnum(f);
@@ -745,8 +742,8 @@
bool _isInstanceFieldOfAllocatedEnum(Field node) =>
!node.isStatic &&
node.enclosingClass != null &&
- node.enclosingClass.isEnum &&
- isClassAllocated(node.enclosingClass);
+ node.enclosingClass!.isEnum &&
+ isClassAllocated(node.enclosingClass!);
void addClassUsedInType(Class c) {
if (_classesUsedInType.add(c)) {
@@ -777,7 +774,7 @@
_usedClasses.add(enclosingClass);
}
- FunctionNode func = null;
+ FunctionNode? func = null;
if (m is Field) {
m.type.accept(typeVisitor);
} else if (m is Procedure) {
@@ -786,19 +783,19 @@
m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
m.concreteForwardingStubTarget,
isSetter: m.isSetter);
- addUsedMember(m.concreteForwardingStubTarget);
+ addUsedMember(m.concreteForwardingStubTarget!);
}
if (m.abstractForwardingStubTarget != null) {
m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
m.abstractForwardingStubTarget,
isSetter: m.isSetter);
- addUsedMember(m.abstractForwardingStubTarget);
+ addUsedMember(m.abstractForwardingStubTarget!);
}
if (m.memberSignatureOrigin != null) {
m.stubTarget = fieldMorpher.adjustInstanceCallTarget(
m.memberSignatureOrigin,
isSetter: m.isSetter);
- addUsedMember(m.memberSignatureOrigin);
+ addUsedMember(m.memberSignatureOrigin!);
}
} else if (m is Constructor) {
func = m.function;
@@ -821,8 +818,7 @@
final extension = m.enclosingLibrary.extensions.firstWhere((extension) {
return extension.members
.any((descriptor) => descriptor.member.asMember == m);
- }, orElse: () => null);
- assert(extension != null);
+ });
// Ensure we retain the [Extension] itself (though members might be
// shaken)
@@ -844,7 +840,7 @@
if (_usedExtensions.add(node)) {
node.annotations = const <Expression>[];
_pass1.transformTypeParameterList(node.typeParameters, node);
- node.onType?.accept(typeVisitor);
+ node.onType.accept(typeVisitor);
}
}
@@ -898,7 +894,7 @@
isAbstract: true, fileUri: field.fileUri);
}
accessor.fileOffset = field.fileOffset;
- field.enclosingClass.addProcedure(accessor);
+ field.enclosingClass!.addProcedure(accessor);
_removedFields[accessor] = field;
shaker.addUsedMember(accessor);
return accessor;
@@ -908,7 +904,7 @@
/// If necessary, creates a getter or setter as a replacement if target is a
/// field which is going to be removed by the tree shaker.
/// This method is used during tree shaker pass 1.
- Member adjustInstanceCallTarget(Member target, {bool isSetter = false}) {
+ Member? adjustInstanceCallTarget(Member? target, {bool isSetter = false}) {
if (target is Field && !shaker.retainField(target)) {
final targets =
isSetter ? _settersForRemovedFields : _gettersForRemovedFields;
@@ -923,9 +919,9 @@
/// Return a member which replaced [target] in instance calls.
/// This method can be used after tree shaking to discover replacement.
- Member getMorphedMember(Member target, {bool isSetter = false}) {
- if (target == null) {
- return null;
+ Member? getMorphedMember(Member? target, {bool isSetter = false}) {
+ if (target is! Field) {
+ return target;
}
final targets =
isSetter ? _settersForRemovedFields : _gettersForRemovedFields;
@@ -934,7 +930,7 @@
/// Return original member which was replaced by [target] in instance calls.
/// This method can be used after tree shaking.
- Member getOriginalMember(Member target) {
+ Member? getOriginalMember(Member? target) {
if (target == null) {
return null;
}
@@ -994,16 +990,15 @@
final TreeShaker shaker;
final FieldMorpher fieldMorpher;
final TypeEnvironment environment;
- Procedure _unsafeCast;
- StaticTypeContext _staticTypeContext;
- Member _currentMember;
+ StaticTypeContext? _staticTypeContext;
+ Member? _currentMember;
StaticTypeContext get staticTypeContext =>
_staticTypeContext ??= StaticTypeContext(currentMember, environment);
- Member get currentMember => _currentMember;
- set currentMember(Member m) {
+ Member get currentMember => _currentMember!;
+ set currentMember(Member? m) {
_currentMember = m;
_staticTypeContext = null;
}
@@ -1022,7 +1017,7 @@
}
List<Expression> _flattenArguments(Arguments arguments,
- {Expression receiver}) {
+ {Expression? receiver}) {
final args = <Expression>[];
if (receiver != null) {
args.add(receiver);
@@ -1035,9 +1030,9 @@
bool _isThrowExpression(Expression expr) {
for (;;) {
if (expr is Let) {
- expr = (expr as Let).body;
+ expr = expr.body;
} else if (expr is BlockExpression) {
- expr = (expr as BlockExpression).value;
+ expr = expr.value;
} else {
break;
}
@@ -1068,7 +1063,7 @@
return BlockExpression(Block(statements), value);
}
- TreeNode _makeUnreachableCall(List<Expression> args) {
+ Expression _makeUnreachableCall(List<Expression> args) {
Expression node;
final int last = args.indexWhere(_isThrowExpression);
if (last >= 0) {
@@ -1090,12 +1085,12 @@
new VariableDeclaration(null, initializer: _makeUnreachableCall(args)));
}
- NarrowNotNull _getNullTest(TreeNode node) =>
+ NarrowNotNull? _getNullTest(TreeNode node) =>
shaker.typeFlowAnalysis.nullTest(node);
- TreeNode _visitAssertNode(TreeNode node, TreeNode removalSentinel) {
+ TreeNode _visitAssertNode(TreeNode node, TreeNode? removalSentinel) {
if (kRemoveAsserts) {
- return removalSentinel;
+ return removalSentinel!;
} else {
node.transformOrRemoveChildren(this);
return node;
@@ -1103,31 +1098,31 @@
}
@override
- DartType visitDartType(DartType node, DartType removalSentinel) {
+ DartType visitDartType(DartType node, DartType? removalSentinel) {
node.accept(shaker.typeVisitor);
return node;
}
@override
- Supertype visitSupertype(Supertype node, Supertype removalSentinel) {
+ Supertype visitSupertype(Supertype node, Supertype? removalSentinel) {
node.accept(shaker.typeVisitor);
return node;
}
@override
- TreeNode visitTypedef(Typedef node, TreeNode removalSentinel) {
+ TreeNode visitTypedef(Typedef node, TreeNode? removalSentinel) {
return node; // Do not go deeper.
}
@override
- Extension visitExtension(Extension node, TreeNode removalSentinel) {
+ TreeNode visitExtension(Extension node, TreeNode? removalSentinel) {
// The extension can be considered a weak node, we'll only retain it if
// normal code references any of it's members.
return node;
}
@override
- TreeNode visitClass(Class node, TreeNode removalSentinel) {
+ TreeNode visitClass(Class node, TreeNode? removalSentinel) {
if (shaker.isClassAllocated(node) ||
shaker.isClassReferencedFromNativeCode(node)) {
shaker.addClassUsedInType(node);
@@ -1140,7 +1135,7 @@
}
@override
- TreeNode defaultMember(Member node, TreeNode removalSentinel) {
+ TreeNode defaultMember(Member node, TreeNode? removalSentinel) {
currentMember = node;
if (shaker.isMemberBodyReachable(node)) {
if (kPrintTrace) {
@@ -1160,7 +1155,7 @@
}
@override
- TreeNode visitField(Field node, TreeNode removalSentinel) {
+ TreeNode visitField(Field node, TreeNode? removalSentinel) {
currentMember = node;
if (shaker.retainField(node)) {
if (kPrintTrace) {
@@ -1185,21 +1180,21 @@
@override
TreeNode visitInstanceInvocation(
- InstanceInvocation node, TreeNode removalSentinel) {
+ InstanceInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
_flattenArguments(node.arguments, receiver: node.receiver));
}
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
@override
TreeNode visitDynamicInvocation(
- DynamicInvocation node, TreeNode removalSentinel) {
+ DynamicInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
@@ -1210,7 +1205,7 @@
@override
TreeNode visitLocalFunctionInvocation(
- LocalFunctionInvocation node, TreeNode removalSentinel) {
+ LocalFunctionInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
@@ -1220,7 +1215,7 @@
@override
TreeNode visitFunctionInvocation(
- FunctionInvocation node, TreeNode removalSentinel) {
+ FunctionInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(
@@ -1230,24 +1225,24 @@
}
@override
- TreeNode visitEqualsCall(EqualsCall node, TreeNode removalSentinel) {
+ TreeNode visitEqualsCall(EqualsCall node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.left, node.right]);
}
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
@override
- TreeNode visitEqualsNull(EqualsNull node, TreeNode removalSentinel) {
+ TreeNode visitEqualsNull(EqualsNull node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.expression]);
}
- final nullTest = _getNullTest(node);
+ final nullTest = _getNullTest(node)!;
if (nullTest.isAlwaysNull || nullTest.isAlwaysNotNull) {
return _evaluateArguments([node.expression],
BoolLiteral(nullTest.isAlwaysNull)..fileOffset = node.fileOffset);
@@ -1256,13 +1251,13 @@
}
@override
- TreeNode visitInstanceGet(InstanceGet node, TreeNode removalSentinel) {
+ TreeNode visitInstanceGet(InstanceGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
} else {
node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget)!;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
@@ -1270,20 +1265,20 @@
@override
TreeNode visitInstanceTearOff(
- InstanceTearOff node, TreeNode removalSentinel) {
+ InstanceTearOff node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
} else {
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
}
@override
- TreeNode visitDynamicGet(DynamicGet node, TreeNode removalSentinel) {
+ TreeNode visitDynamicGet(DynamicGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
@@ -1294,7 +1289,7 @@
@override
TreeNode visitFunctionTearOff(
- FunctionTearOff node, TreeNode removalSentinel) {
+ FunctionTearOff node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver]);
@@ -1304,20 +1299,20 @@
}
@override
- TreeNode visitInstanceSet(InstanceSet node, TreeNode removalSentinel) {
+ TreeNode visitInstanceSet(InstanceSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver, node.value]);
} else {
node.interfaceTarget = fieldMorpher
- .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
+ .adjustInstanceCallTarget(node.interfaceTarget, isSetter: true)!;
shaker.addUsedMember(node.interfaceTarget);
return node;
}
}
@override
- TreeNode visitDynamicSet(DynamicSet node, TreeNode removalSentinel) {
+ TreeNode visitDynamicSet(DynamicSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.receiver, node.value]);
@@ -1328,15 +1323,15 @@
@override
TreeNode visitSuperMethodInvocation(
- SuperMethodInvocation node, TreeNode removalSentinel) {
+ SuperMethodInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
} else {
- node.interfaceTarget =
- fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
+ node.interfaceTarget = fieldMorpher
+ .adjustInstanceCallTarget(node.interfaceTarget) as Procedure?;
if (node.interfaceTarget != null) {
- shaker.addUsedMember(node.interfaceTarget);
+ shaker.addUsedMember(node.interfaceTarget!);
}
return node;
}
@@ -1344,7 +1339,7 @@
@override
TreeNode visitSuperPropertyGet(
- SuperPropertyGet node, TreeNode removalSentinel) {
+ SuperPropertyGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([]);
@@ -1352,7 +1347,7 @@
node.interfaceTarget =
fieldMorpher.adjustInstanceCallTarget(node.interfaceTarget);
if (node.interfaceTarget != null) {
- shaker.addUsedMember(node.interfaceTarget);
+ shaker.addUsedMember(node.interfaceTarget!);
}
return node;
}
@@ -1360,7 +1355,7 @@
@override
TreeNode visitSuperPropertySet(
- SuperPropertySet node, TreeNode removalSentinel) {
+ SuperPropertySet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.value]);
@@ -1368,7 +1363,7 @@
node.interfaceTarget = fieldMorpher
.adjustInstanceCallTarget(node.interfaceTarget, isSetter: true);
if (node.interfaceTarget != null) {
- shaker.addUsedMember(node.interfaceTarget);
+ shaker.addUsedMember(node.interfaceTarget!);
}
return node;
}
@@ -1376,7 +1371,7 @@
@override
TreeNode visitStaticInvocation(
- StaticInvocation node, TreeNode removalSentinel) {
+ StaticInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
@@ -1390,7 +1385,7 @@
}
@override
- TreeNode visitStaticGet(StaticGet node, TreeNode removalSentinel) {
+ TreeNode visitStaticGet(StaticGet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([]);
@@ -1405,13 +1400,13 @@
}
@override
- Constant visitConstant(Constant node, Constant removalSentinel) {
+ Constant visitConstant(Constant node, Constant? removalSentinel) {
shaker.constantVisitor.analyzeConstant(node);
return node;
}
@override
- TreeNode visitStaticSet(StaticSet node, TreeNode removalSentinel) {
+ TreeNode visitStaticSet(StaticSet node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall([node.value]);
@@ -1428,7 +1423,7 @@
@override
TreeNode visitConstructorInvocation(
- ConstructorInvocation node, TreeNode removalSentinel) {
+ ConstructorInvocation node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableCall(_flattenArguments(node.arguments));
@@ -1444,7 +1439,7 @@
@override
TreeNode visitRedirectingInitializer(
- RedirectingInitializer node, TreeNode removalSentinel) {
+ RedirectingInitializer node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer(_flattenArguments(node.arguments));
@@ -1457,7 +1452,7 @@
@override
TreeNode visitSuperInitializer(
- SuperInitializer node, TreeNode removalSentinel) {
+ SuperInitializer node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer(_flattenArguments(node.arguments));
@@ -1469,7 +1464,7 @@
@override
TreeNode visitFieldInitializer(
- FieldInitializer node, TreeNode removalSentinel) {
+ FieldInitializer node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
if (_isUnreachable(node)) {
return _makeUnreachableInitializer([node.value]);
@@ -1482,7 +1477,7 @@
return LocalInitializer(
VariableDeclaration(null, initializer: node.value));
} else {
- return removalSentinel;
+ return removalSentinel!;
}
}
return node;
@@ -1491,18 +1486,18 @@
@override
TreeNode visitAssertStatement(
- AssertStatement node, TreeNode removalSentinel) {
+ AssertStatement node, TreeNode? removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
- TreeNode visitAssertBlock(AssertBlock node, TreeNode removalSentinel) {
+ TreeNode visitAssertBlock(AssertBlock node, TreeNode? removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@override
TreeNode visitAssertInitializer(
- AssertInitializer node, TreeNode removalSentinel) {
+ AssertInitializer node, TreeNode? removalSentinel) {
return _visitAssertNode(node, removalSentinel);
}
@@ -1520,21 +1515,21 @@
// Returns Block corresponding to the given extended bool literal,
// or null if the expression is a simple bool literal.
- Block _getExtendedBoolLiteralBlock(Expression expr) =>
+ Block? _getExtendedBoolLiteralBlock(Expression expr) =>
(expr is BoolLiteral) ? null : (expr as BlockExpression).body;
@override
- TreeNode visitIfStatement(IfStatement node, TreeNode removalSentinel) {
+ TreeNode visitIfStatement(IfStatement node, TreeNode? removalSentinel) {
final condition = transform(node.condition);
if (_isExtendedBoolLiteral(condition)) {
final bool conditionValue = _getExtendedBoolLiteralValue(condition);
- final Block conditionBlock = _getExtendedBoolLiteralBlock(condition);
- ast.Statement body;
+ final Block? conditionBlock = _getExtendedBoolLiteralBlock(condition);
+ ast.Statement? body;
if (conditionValue) {
body = transform(node.then);
} else {
if (node.otherwise != null) {
- body = transformOrRemoveStatement(node.otherwise);
+ body = transformOrRemoveStatement(node.otherwise!);
}
}
if (conditionBlock != null) {
@@ -1549,7 +1544,7 @@
node.condition = condition..parent = node;
node.then = transform(node.then)..parent = node;
if (node.otherwise != null) {
- node.otherwise = transformOrRemoveStatement(node.otherwise);
+ node.otherwise = transformOrRemoveStatement(node.otherwise!);
node.otherwise?.parent = node;
}
return node;
@@ -1557,7 +1552,7 @@
@override
visitConditionalExpression(
- ConditionalExpression node, TreeNode removalSentinel) {
+ ConditionalExpression node, TreeNode? removalSentinel) {
final condition = transform(node.condition);
if (_isExtendedBoolLiteral(condition)) {
final bool value = _getExtendedBoolLiteralValue(condition);
@@ -1578,7 +1573,7 @@
}
@override
- TreeNode visitNot(Not node, TreeNode removalSentinel) {
+ TreeNode visitNot(Not node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
final operand = node.operand;
if (_isExtendedBoolLiteral(operand)) {
@@ -1595,7 +1590,7 @@
@override
TreeNode visitLogicalExpression(
- LogicalExpression node, TreeNode removalSentinel) {
+ LogicalExpression node, TreeNode? removalSentinel) {
final left = transform(node.left);
final operatorEnum = node.operatorEnum;
if (_isExtendedBoolLiteral(left)) {
@@ -1621,8 +1616,8 @@
}
@override
- TreeNode visitIsExpression(IsExpression node, TreeNode removalSentinel) {
- TypeCheck check = shaker.typeFlowAnalysis.isTest(node);
+ TreeNode visitIsExpression(IsExpression node, TreeNode? removalSentinel) {
+ TypeCheck? check = shaker.typeFlowAnalysis.isTest(node);
if (check != null && (check.alwaysFail || check.alwaysPass)) {
final operand = transform(node.operand);
final result = BoolLiteral(!check.alwaysFail)
@@ -1634,9 +1629,9 @@
}
@override
- TreeNode visitAsExpression(AsExpression node, TreeNode removalSentinel) {
+ TreeNode visitAsExpression(AsExpression node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
- TypeCheck check = shaker.typeFlowAnalysis.explicitCast(node);
+ TypeCheck? check = shaker.typeFlowAnalysis.explicitCast(node);
if (check != null && check.alwaysPass) {
return StaticInvocation(
unsafeCast, Arguments([node.operand], types: [node.type]))
@@ -1646,9 +1641,9 @@
}
@override
- TreeNode visitNullCheck(NullCheck node, TreeNode removalSentinel) {
+ TreeNode visitNullCheck(NullCheck node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
- final nullTest = _getNullTest(node);
+ final nullTest = _getNullTest(node)!;
if (nullTest.isAlwaysNotNull) {
return StaticInvocation(
unsafeCast,
@@ -1659,12 +1654,9 @@
return node;
}
- Procedure get unsafeCast {
- _unsafeCast ??= shaker.typeFlowAnalysis.environment.coreTypes.index
- .getTopLevelMember('dart:_internal', 'unsafeCast');
- assert(_unsafeCast != null);
- return _unsafeCast;
- }
+ late final Procedure unsafeCast = shaker
+ .typeFlowAnalysis.environment.coreTypes.index
+ .getTopLevelProcedure('dart:_internal', 'unsafeCast');
}
/// The second pass of [TreeShaker]. It is called after set of used
@@ -1680,7 +1672,7 @@
void transformComponent(Component component) {
component.transformOrRemoveChildren(this);
for (Source source in component.uriToSource.values) {
- source?.constantCoverageConstructors?.removeWhere((Reference reference) {
+ source.constantCoverageConstructors?.removeWhere((Reference reference) {
Member node = reference.asMember;
return !shaker.isMemberUsed(node);
});
@@ -1688,7 +1680,7 @@
}
@override
- TreeNode visitLibrary(Library node, TreeNode removalSentinel) {
+ TreeNode visitLibrary(Library node, TreeNode? removalSentinel) {
node.transformOrRemoveChildren(this);
// The transformer API does not iterate over `Library.additionalExports`,
// so we manually delete the references to shaken nodes.
@@ -1708,12 +1700,12 @@
}
@override
- Typedef visitTypedef(Typedef node, TreeNode removalSentinel) {
- return shaker.isTypedefUsed(node) ? node : removalSentinel;
+ TreeNode visitTypedef(Typedef node, TreeNode? removalSentinel) {
+ return shaker.isTypedefUsed(node) ? node : removalSentinel!;
}
@override
- Class visitClass(Class node, TreeNode removalSentinel) {
+ TreeNode visitClass(Class node, TreeNode? removalSentinel) {
if (!shaker.isClassUsed(node)) {
debugPrint('Dropped class ${node.name}');
// Ensure that kernel file writer will not be able to
@@ -1724,7 +1716,7 @@
"been repurposed for ${node.reference.node}.");
node.reference.canonicalName?.unbind();
Statistics.classesDropped++;
- return removalSentinel; // Remove the class.
+ return removalSentinel!; // Remove the class.
}
if (!shaker.isClassUsedInType(node)) {
@@ -1755,7 +1747,7 @@
}
@override
- Member defaultMember(Member node, TreeNode removalSentinel) {
+ TreeNode defaultMember(Member node, TreeNode? removalSentinel) {
if (!shaker.isMemberUsed(node)) {
// Ensure that kernel file writer will not be able to
// write a dangling reference to the deleted member.
@@ -1767,10 +1759,10 @@
node.getterReference.canonicalName?.unbind();
if (node.hasSetter) {
assert(
- node.setterReference.node == node,
+ node.setterReference!.node == node,
"Trying to remove canonical name from reference on $node which "
- "has been repurposed for ${node.setterReference.node}.");
- node.setterReference.canonicalName?.unbind();
+ "has been repurposed for ${node.setterReference!.node}.");
+ node.setterReference!.canonicalName?.unbind();
}
} else {
assert(
@@ -1780,13 +1772,13 @@
node.reference.canonicalName?.unbind();
}
Statistics.membersDropped++;
- return removalSentinel;
+ return removalSentinel!;
}
if (!shaker.isMemberBodyReachable(node)) {
if (node is Procedure) {
// Remove body of unused member.
- if (!node.isStatic && node.enclosingClass.isAbstract) {
+ if (!node.isStatic && node.enclosingClass!.isAbstract) {
node.isAbstract = true;
node.function.body = null;
} else {
@@ -1829,7 +1821,7 @@
}
@override
- Extension visitExtension(Extension node, TreeNode removalSentinel) {
+ TreeNode visitExtension(Extension node, TreeNode? removalSentinel) {
if (shaker.isExtensionUsed(node)) {
int writeIndex = 0;
for (int i = 0; i < node.members.length; ++i) {
@@ -1840,7 +1832,7 @@
// member was already removed or it will be removed later.
final Reference memberReference = descriptor.member;
final bool isBound = memberReference.node != null;
- if (isBound && shaker.isMemberUsed(memberReference.node)) {
+ if (isBound && shaker.isMemberUsed(memberReference.asMember)) {
node.members[writeIndex++] = descriptor;
}
}
@@ -1850,7 +1842,7 @@
assert(node.members.length > 0);
return node;
}
- return removalSentinel;
+ return removalSentinel!;
}
void _makeUnreachableBody(FunctionNode function) {
@@ -1871,7 +1863,7 @@
}
@override
- TreeNode defaultTreeNode(TreeNode node, TreeNode removalSentinel) {
+ TreeNode defaultTreeNode(TreeNode node, TreeNode? removalSentinel) {
return node; // Do not traverse into other nodes.
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 588512c..3ed7b9b 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -2,10 +2,7 @@
// 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.
-// @dart=2.9
-
/// Declares the type system used by global type flow analysis.
-library vm.transformations.type_flow.types;
import 'dart:core' hide Type;
@@ -138,10 +135,7 @@
/// values can flow through the program.
Type specializeTypeCone(TFClass base, {bool allowWideCone = false});
- Type _cachedIntType;
- Type get intType {
- return _cachedIntType ??= fromStaticType(coreTypes.intLegacyRawType, true);
- }
+ late final Type intType = fromStaticType(coreTypes.intLegacyRawType, true);
}
/// Base class for type expressions.
@@ -151,7 +145,7 @@
/// Returns computed type of this type expression.
/// [types] is the list of types computed for the statements in the summary.
- Type getComputedType(List<Type> types);
+ Type getComputedType(List<Type?> types);
}
/// Kind of a subtype test: subtype/cast/'as' test or instance check/'is' test.
@@ -174,7 +168,7 @@
/// Create a type representing arbitrary nullable object (`dynamic`).
factory Type.nullableAny() => new NullableType(const AnyType());
- Class getConcreteClass(TypeHierarchy typeHierarchy) => null;
+ Class? getConcreteClass(TypeHierarchy typeHierarchy) => null;
bool isSubtypeOf(TypeHierarchy typeHierarchy, Class cls) => false;
@@ -185,7 +179,7 @@
RuntimeType runtimeType, SubtypeTestKind kind);
@override
- Type getComputedType(List<Type> types) => this;
+ Type getComputedType(List<Type?> types) => this;
/// Order of precedence for evaluation of union/intersection.
int get order;
@@ -260,7 +254,6 @@
final Type baseType;
NullableType(this.baseType) {
- assert(baseType != null);
assert(baseType is! NullableType);
}
@@ -387,7 +380,9 @@
class SetType extends Type {
/// List of concrete types, sorted by classId.
final List<ConcreteType> types;
- int _hashCode;
+
+ @override
+ late final int hashCode = _computeHashCode();
/// Creates a new SetType using list of concrete types sorted by classId.
SetType(this.types) {
@@ -395,9 +390,6 @@
assert(isSorted(types));
}
- @override
- int get hashCode => _hashCode ??= _computeHashCode();
-
int _computeHashCode() {
int hash = 1237;
for (var t in types) {
@@ -470,8 +462,8 @@
return types;
}
- static List<ConcreteType> _intersectLists(
- List<ConcreteType> types1, List<ConcreteType> types2) {
+ static List<ConcreteType> _intersectLists(List<ConcreteType> types1,
+ List<ConcreteType> types2, TypeHierarchy typeHierarchy) {
int i1 = 0;
int i2 = 0;
List<ConcreteType> types = <ConcreteType>[];
@@ -491,9 +483,9 @@
t2.constant == null) {
types.add(t1);
} else {
- final intersect = t1.intersection(t2, null);
+ final intersect = t1.intersection(t2, typeHierarchy);
if (intersect is! EmptyType) {
- types.add(intersect);
+ types.add(intersect as ConcreteType);
}
}
++i1;
@@ -558,7 +550,8 @@
return other.intersection(this, typeHierarchy);
}
if (other is SetType) {
- List<ConcreteType> list = _intersectLists(types, other.types);
+ List<ConcreteType> list =
+ _intersectLists(types, other.types, typeHierarchy);
final size = list.length;
if (size == 0) {
return const EmptyType();
@@ -594,7 +587,7 @@
ConeType(this.cls);
@override
- Class getConcreteClass(TypeHierarchy typeHierarchy) => typeHierarchy
+ Class? getConcreteClass(TypeHierarchy typeHierarchy) => typeHierarchy
.specializeTypeCone(cls, allowWideCone: true)
.getConcreteClass(typeHierarchy);
@@ -696,7 +689,7 @@
WideConeType(TFClass cls) : super(cls);
@override
- Class getConcreteClass(TypeHierarchy typeHierarchy) => null;
+ Class? getConcreteClass(TypeHierarchy typeHierarchy) => null;
@override
int get hashCode => (cls.id + 41) & kHashMask;
@@ -783,7 +776,9 @@
/// or `null` object).
class ConcreteType extends Type implements Comparable<ConcreteType> {
final TFClass cls;
- int _hashCode;
+
+ @override
+ late final int hashCode = _computeHashCode();
// May be null if there are no type arguments constraints. The type arguments
// should represent type sets, i.e. `UnknownType` or `RuntimeType`. The type
@@ -796,19 +791,19 @@
// 'numImmediateTypeArgs' is the length of the prefix of 'typeArgs' which
// holds the type arguments to the class itself.
final int numImmediateTypeArgs;
- final List<Type> typeArgs;
+ final List<Type>? typeArgs;
// May be null if constant value is not inferred.
- final Constant constant;
+ final Constant? constant;
- ConcreteType(this.cls, [List<Type> typeArgs_, this.constant])
+ ConcreteType(this.cls, [List<Type>? typeArgs_, this.constant])
: typeArgs = typeArgs_,
numImmediateTypeArgs =
typeArgs_ != null ? cls.classNode.typeParameters.length : 0 {
// TODO(alexmarkov): support closures
assert(!cls.classNode.isAbstract);
assert(typeArgs == null || cls.classNode.typeParameters.isNotEmpty);
- assert(typeArgs == null || typeArgs.any((t) => t is RuntimeType));
+ assert(typeArgs == null || typeArgs!.any((t) => t is RuntimeType));
}
ConcreteType get raw => cls.concreteType;
@@ -839,7 +834,7 @@
if (rhs.typeArguments.isEmpty) return true;
- List<Type> usableTypeArgs = typeArgs;
+ List<Type>? usableTypeArgs = typeArgs;
if (usableTypeArgs == null) {
if (cls.classNode.typeParameters.isEmpty) {
usableTypeArgs =
@@ -862,7 +857,7 @@
}
assert(ta is RuntimeType);
if (!ta.isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[i], SubtypeTestKind.Subtype)) {
+ typeHierarchy, runtimeType.typeArgs![i], SubtypeTestKind.Subtype)) {
return false;
}
}
@@ -877,29 +872,26 @@
} else {
final interfaceOffset = typeHierarchy.genericInterfaceOffsetFor(
cls.classNode, typeHierarchy.coreTypes.futureClass);
- typeArg = typeArgs[interfaceOffset];
+ typeArg = typeArgs![interfaceOffset];
}
final RuntimeType lhs =
typeArg is RuntimeType ? typeArg : RuntimeType(DynamicType(), null);
return lhs.isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
} else {
return isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
}
}
return false;
}
- @override
- int get hashCode => _hashCode ??= _computeHashCode();
-
int _computeHashCode() {
int hash = cls.hashCode ^ 0x1234 & kHashMask;
// We only need to hash the first type arguments vector, since the type
// arguments of the implemented interfaces are implied by it.
for (int i = 0; i < numImmediateTypeArgs; ++i) {
- hash = (((hash * 31) & kHashMask) + typeArgs[i].hashCode) & kHashMask;
+ hash = (((hash * 31) & kHashMask) + typeArgs![i].hashCode) & kHashMask;
}
hash = ((hash * 31) & kHashMask) + constant.hashCode;
return hash;
@@ -915,7 +907,7 @@
}
if (this.typeArgs != null) {
for (int i = 0; i < numImmediateTypeArgs; ++i) {
- if (this.typeArgs[i] != other.typeArgs[i]) {
+ if (this.typeArgs![i] != other.typeArgs![i]) {
return false;
}
}
@@ -942,10 +934,10 @@
final StringBuffer buf = new StringBuffer();
buf.write("_T (${cls}");
if (typeArgs != null) {
- buf.write("<${typeArgs.take(numImmediateTypeArgs).join(', ')}>");
+ buf.write("<${typeArgs!.take(numImmediateTypeArgs).join(', ')}>");
}
if (constant != null) {
- buf.write(", ${nodeToText(constant)}");
+ buf.write(", ${nodeToText(constant!)}");
}
buf.write(")");
return buf.toString();
@@ -997,17 +989,21 @@
return this;
}
- List<Type> mergedTypeArgs;
- if (typeArgs == null) {
- mergedTypeArgs = other.typeArgs;
- } else if (other.typeArgs == null) {
- mergedTypeArgs = typeArgs;
+ List<Type>? mergedTypeArgs;
+ final thisTypeArgs = this.typeArgs;
+ final otherTypeArgs = other.typeArgs;
+ if (thisTypeArgs == null) {
+ mergedTypeArgs = otherTypeArgs;
+ } else if (otherTypeArgs == null) {
+ mergedTypeArgs = thisTypeArgs;
} else {
- mergedTypeArgs = new List<Type>.filled(typeArgs.length, null);
+ assert(thisTypeArgs.length == otherTypeArgs.length);
+ mergedTypeArgs =
+ new List<Type>.filled(thisTypeArgs.length, const EmptyType());
bool hasRuntimeType = false;
- for (int i = 0; i < typeArgs.length; ++i) {
+ for (int i = 0; i < thisTypeArgs.length; ++i) {
final merged =
- typeArgs[i].intersection(other.typeArgs[i], typeHierarchy);
+ thisTypeArgs[i].intersection(otherTypeArgs[i], typeHierarchy);
if (merged is EmptyType) {
return const EmptyType();
} else if (merged is RuntimeType) {
@@ -1020,7 +1016,7 @@
}
}
- Constant mergedConstant;
+ Constant? mergedConstant;
if (constant == null) {
mergedConstant = other.constant;
} else if (other.constant == null || constant == other.constant) {
@@ -1062,7 +1058,7 @@
final DartType _type; // Doesn't contain type args.
final int numImmediateTypeArgs;
- final List<RuntimeType> typeArgs;
+ final List<RuntimeType>? typeArgs;
RuntimeType(DartType type, this.typeArgs)
: _type = type,
@@ -1070,14 +1066,12 @@
? type.classNode.typeParameters.length
: (type is FutureOrType ? 1 : 0) {
if (_type is InterfaceType && numImmediateTypeArgs > 0) {
- assert(typeArgs != null);
- assert(typeArgs.length >= numImmediateTypeArgs);
+ assert(typeArgs!.length >= numImmediateTypeArgs);
assert((_type as InterfaceType)
.typeArguments
.every((t) => t == const DynamicType()));
} else if (_type is FutureOrType) {
- assert(typeArgs != null);
- assert(typeArgs.length >= numImmediateTypeArgs);
+ assert(typeArgs!.length >= numImmediateTypeArgs);
DartType typeArgument = (_type as FutureOrType).typeArgument;
assert(typeArgument == const DynamicType());
} else {
@@ -1098,25 +1092,27 @@
final type = _type;
if (type is InterfaceType && typeArgs != null) {
final klass = type.classNode;
- final typeArguments = typeArgs
+ final typeArguments = typeArgs!
.take(klass.typeParameters.length)
.map((pt) => pt.representedType)
.toList();
return new InterfaceType(klass, type.nullability, typeArguments);
} else if (type is FutureOrType) {
- return new FutureOrType(typeArgs[0].representedType, type.nullability);
+ return new FutureOrType(typeArgs![0].representedType, type.nullability);
} else {
return type;
}
}
@override
- int get hashCode {
+ late final int hashCode = _computeHashCode();
+
+ int _computeHashCode() {
int hash = _type.hashCode ^ 0x1234 & kHashMask;
// Only hash by the type arguments of the class. The type arguments of
// supertypes are are implied by them.
for (int i = 0; i < numImmediateTypeArgs; ++i) {
- hash = (((hash * 31) & kHashMask) + typeArgs[i].hashCode) & kHashMask;
+ hash = (((hash * 31) & kHashMask) + typeArgs![i].hashCode) & kHashMask;
}
return hash;
}
@@ -1127,7 +1123,7 @@
if (other is RuntimeType) {
if (other._type != _type) return false;
assert(numImmediateTypeArgs == other.numImmediateTypeArgs);
- return typeArgs == null || listEquals(typeArgs, other.typeArgs);
+ return typeArgs == null || listEquals(typeArgs!, other.typeArgs!);
}
return false;
}
@@ -1139,7 +1135,7 @@
: "${nodeToText(_type)}";
final typeArgsStrs = (numImmediateTypeArgs == 0)
? ""
- : "<${typeArgs.take(numImmediateTypeArgs).map((t) => "$t").join(", ")}>";
+ : "<${typeArgs!.take(numImmediateTypeArgs).map((t) => "$t").join(", ")}>";
final nullability = _type.nullability.suffix;
return "$head$typeArgsStrs$nullability";
}
@@ -1200,15 +1196,15 @@
if (_type is InterfaceType) {
Class thisClass = (_type as InterfaceType).classNode;
if (thisClass == typeHierarchy.coreTypes.futureClass) {
- return typeArgs[0].isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ return typeArgs![0].isSubtypeOfRuntimeType(
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
} else {
return isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
}
} else if (_type is FutureOrType) {
- return typeArgs[0].isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[0], SubtypeTestKind.Subtype);
+ return typeArgs![0].isSubtypeOfRuntimeType(
+ typeHierarchy, runtimeType.typeArgs![0], SubtypeTestKind.Subtype);
}
}
@@ -1236,7 +1232,7 @@
return true;
}
- List<Type> usableTypeArgs = typeArgs;
+ List<Type>? usableTypeArgs = typeArgs;
if (usableTypeArgs == null) {
assert(thisClass.typeParameters.isEmpty);
usableTypeArgs =
@@ -1248,7 +1244,7 @@
runtimeType.numImmediateTypeArgs);
for (int i = 0; i < runtimeType.numImmediateTypeArgs; ++i) {
if (!usableTypeArgs[interfaceOffset + i].isSubtypeOfRuntimeType(
- typeHierarchy, runtimeType.typeArgs[i], SubtypeTestKind.Subtype)) {
+ typeHierarchy, runtimeType.typeArgs![i], SubtypeTestKind.Subtype)) {
return false;
}
}
diff --git a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
index 723e673..682cf58 100644
--- a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
+++ b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
@@ -2,8 +2,6 @@
// 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.
-// @dart=2.9
-
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/external_name.dart' show getExternalName;
@@ -30,12 +28,12 @@
_coreTypes = typeFlowAnalysis.environment.coreTypes,
_nativeCodeOracle = typeFlowAnalysis.nativeCodeOracle;
- UnboxingInfoMetadata getUnboxingInfoOfMember(Member member) {
- final UnboxingInfoMetadata info = _memberInfo[member];
+ UnboxingInfoMetadata? getUnboxingInfoOfMember(Member member) {
+ final UnboxingInfoMetadata? info = _memberInfo[member];
if (member is Procedure && member.isGetter) {
// Remove placeholder parameter info slot for setters that the getter is
// grouped with.
- return UnboxingInfoMetadata(0)..returnInfo = info.returnInfo;
+ return UnboxingInfoMetadata(0)..returnInfo = info!.returnInfo;
}
return info;
}
@@ -81,8 +79,8 @@
? (member.hasSetter ? 1 : 0)
: member is Procedure && member.isGetter
? 1
- : member.function.requiredParameterCount;
- UnboxingInfoMetadata info;
+ : member.function!.requiredParameterCount;
+ UnboxingInfoMetadata? info;
if (member.isInstanceMember) {
int selectorId =
member is Field || member is Procedure && member.isGetter
@@ -121,20 +119,18 @@
void _updateUnboxingInfoOfMember(
Member member, TypeFlowAnalysis typeFlowAnalysis) {
if (typeFlowAnalysis.isMemberUsed(member)) {
- final UnboxingInfoMetadata unboxingInfo = _memberInfo[member];
+ final UnboxingInfoMetadata unboxingInfo = _memberInfo[member]!;
if (_cannotUnbox(member)) {
unboxingInfo.unboxedArgsInfo.length = 0;
unboxingInfo.returnInfo = UnboxingInfoMetadata.kBoxed;
return;
}
if (member is Procedure || member is Constructor) {
- final Args<Type> argTypes = typeFlowAnalysis.argumentTypes(member);
- assert(argTypes != null);
-
+ final Args<Type> argTypes = typeFlowAnalysis.argumentTypes(member)!;
final int firstParamIndex =
numTypeParams(member) + (hasReceiverArg(member) ? 1 : 0);
- final positionalParams = member.function.positionalParameters;
+ final positionalParams = member.function!.positionalParameters;
assert(argTypes.positionalCount ==
firstParamIndex + positionalParams.length);
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index b04e69e..c85dfc7 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -2,12 +2,11 @@
// 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.
-// @dart=2.9
-
/// Declares miscellaneous utility functions and constants for type flow
/// analysis.
library vm.transformations.type_flow.utils;
+import 'package:collection/collection.dart' show IterableExtension;
import 'package:kernel/ast.dart';
import 'package:kernel/src/printer.dart';
@@ -123,9 +122,8 @@
return true;
}
-VariableDeclaration findNamedParameter(FunctionNode function, String name) {
- return function.namedParameters
- .firstWhere((p) => p.name == name, orElse: () => null);
+VariableDeclaration? findNamedParameter(FunctionNode function, String name) {
+ return function.namedParameters.firstWhereOrNull((p) => p.name == name);
}
class Histogram<K> {
@@ -143,7 +141,7 @@
print(
'-------------------------------------------------------------------');
List<K> keys = values.keys.toList();
- keys.sort((k1, k2) => values[k1].compareTo(values[k2]));
+ keys.sort((k1, k2) => values[k1]!.compareTo(values[k2]!));
final cut = keys.length < n ? 0 : keys.length - n;
for (int i = keys.length - 1; i >= cut; --i) {
final k = keys[i];
@@ -376,7 +374,7 @@
};
extension NullabilitySuffix on Nullability {
- String get suffix => nullabilitySuffix[this];
+ String get suffix => nullabilitySuffix[this]!;
}
bool mayHaveSideEffects(Expression node) {
diff --git a/pkg/vm/pubspec.yaml b/pkg/vm/pubspec.yaml
index f57cf389..0e78a09 100644
--- a/pkg/vm/pubspec.yaml
+++ b/pkg/vm/pubspec.yaml
@@ -18,6 +18,7 @@
meta:
path: ../meta
package_config: any
+ collection: ^1.15.0
dev_dependencies:
expect:
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index f9ea8d7..2e25344 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -60,7 +60,7 @@
void recordMemberCalledViaThis(Member target) {}
@override
- void recordTearOff(Procedure target) {}
+ void recordTearOff(Member target) {}
}
class PrintSummaries extends RecursiveVisitor {
@@ -78,7 +78,7 @@
typesBuilder,
new NativeCodeOracle(
null, new ConstantPragmaAnnotationParser(coreTypes)),
- new GenericInterfacesInfoImpl(hierarchy),
+ new GenericInterfacesInfoImpl(coreTypes, hierarchy),
/*_protobufHandler=*/ null);
}