Migrate pkg/vm to null safety, part 2

TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/46620

Change-Id: I18bab8755bfa937b6de07a738e3f22309240da22
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207365
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Alexander Markov 2021-07-22 17:30:49 +00:00 committed by commit-bot@chromium.org
parent b89c35472f
commit 3a96674d3d
13 changed files with 177 additions and 208 deletions

View file

@ -1403,7 +1403,7 @@ class KernelDiagnosticReporter
KernelDiagnosticReporter(this.loader);
void report(Message message, int charOffset, int length, Uri fileUri,
void report(Message message, int charOffset, int length, Uri? fileUri,
{List<LocatedMessage>? context}) {
loader.addProblem(message, charOffset, noLength, fileUri, context: context);
}

View file

@ -74,7 +74,7 @@ Target? getTarget(String name, TargetFlags flags) {
}
abstract class DiagnosticReporter<M, C> {
void report(M message, int charOffset, int length, Uri fileUri,
void report(M message, int charOffset, int length, Uri? fileUri,
{List<C> context});
}

View file

@ -2,18 +2,16 @@
// 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
class Vertex<T extends Vertex<T>> {
// Input: vertices directly reachable from this vertex.
final List<T> successors = <T>[];
// Output: the nearest vertex that all paths from the root must go through to
// reach this vertex.
T dominator;
T? dominator;
bool isDominatedBy(T other) {
var d = this;
Vertex<T>? d = this;
while (d != null) {
if (d == other) {
return true;
@ -26,17 +24,17 @@ class Vertex<T extends Vertex<T>> {
// Temporaries. See Lengauer and Tarjan.
final List<T> _predecessors = <T>[];
int _semi = 0;
T _label;
T _ancestor;
T _parent;
List<T> _bucket;
T? _label;
T? _ancestor;
T? _parent;
List<T>? _bucket;
}
// T. Lengauer and R. E. Tarjan. "A Fast Algorithm for Finding Dominators
// in a Flowgraph."
computeDominators<T extends Vertex<T>>(T root) {
// Lengauer and Tarjan Step 1.
final vertex = <T>[];
final vertex = <T?>[];
vertex.add(null);
var n = 0;
@ -60,33 +58,35 @@ computeDominators<T extends Vertex<T>>(T root) {
dfs(root);
forestCompress(T v) {
if (v._ancestor._ancestor != null) {
forestCompress(v._ancestor);
if (v._ancestor._label._semi < v._label._semi) {
v._label = v._ancestor._label;
T ancestor = v._ancestor!;
if (ancestor._ancestor != null) {
forestCompress(ancestor);
ancestor = v._ancestor!;
if (ancestor._label!._semi < v._label!._semi) {
v._label = ancestor._label;
}
v._ancestor = v._ancestor._ancestor;
v._ancestor = ancestor._ancestor;
}
}
forestEval(T v) {
T forestEval(T v) {
if (v._ancestor == null) {
return v;
} else {
forestCompress(v);
return v._label;
return v._label!;
}
}
forestLink(T v, T w) {
forestLink(T? v, T w) {
w._ancestor = v;
}
for (var i = vertex.length - 1; i > 1; i--) {
Vertex<T> w = vertex[i];
final T w = vertex[i]!;
// Lengauer and Tarjan Step 2.
for (Vertex<T> v in w._predecessors) {
for (T v in w._predecessors) {
if (v._semi == 0) continue; // Unreachable
final u = forestEval(v);
@ -95,7 +95,7 @@ computeDominators<T extends Vertex<T>>(T root) {
}
}
Vertex<T> z = vertex[w._semi];
Vertex<T> z = vertex[w._semi]!;
var b = z._bucket;
if (b == null) {
z._bucket = b = <T>[];
@ -104,8 +104,7 @@ computeDominators<T extends Vertex<T>>(T root) {
forestLink(w._parent, w);
// Lengauer and Tarjan Step 3.
z = w._parent;
assert(z != null);
z = w._parent!;
b = z._bucket;
z._bucket = null;
if (b != null) {
@ -118,9 +117,9 @@ computeDominators<T extends Vertex<T>>(T root) {
// Lengauer and Tarjan Step 4.
for (var i = 2; i < vertex.length; i++) {
final w = vertex[i];
final T w = vertex[i]!;
if (w.dominator != vertex[w._semi]) {
w.dominator = w.dominator.dominator;
w.dominator = w.dominator!.dominator;
}
}
}

View file

@ -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 'dart:async';
import 'dart:io' as io;
@ -66,7 +64,7 @@ class HttpFileSystemEntity implements FileSystemEntity {
}
Future<T> connectAndRun<T>(Future<T> body(io.HttpClient httpClient)) async {
io.HttpClient httpClient;
io.HttpClient? httpClient;
try {
httpClient = new io.HttpClient();
// Set timeout to be shorter than anticipated OS default

View file

@ -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
library vm.transformations.deferred_loading;
import 'package:kernel/ast.dart';
@ -11,15 +9,15 @@ import '../dominators.dart';
import '../metadata/loading_units.dart';
class _LoadingUnitBuilder {
int id;
late int id;
final _LibraryVertex root;
final List<Library> members = <Library>[];
final List<_LoadingUnitBuilder> children = <_LoadingUnitBuilder>[];
_LoadingUnitBuilder(this.root);
_LoadingUnitBuilder get parent => root.dominator?.loadingUnit;
int get parentId => parent == null ? 0 : parent.id;
_LoadingUnitBuilder? get parent => root.dominator?.loadingUnit;
int get parentId => parent == null ? 0 : parent!.id;
LoadingUnit asLoadingUnit() {
return new LoadingUnit(
@ -33,7 +31,7 @@ class _LoadingUnitBuilder {
class _LibraryVertex extends Vertex<_LibraryVertex> {
final Library library;
bool isLoadingRoot = true;
_LoadingUnitBuilder loadingUnit;
_LoadingUnitBuilder? loadingUnit;
_LibraryVertex(this.library);
String toString() => "_LibraryVertex(${library.importUri})";
@ -47,11 +45,11 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
}
for (final vertex in map.values) {
for (final dep in vertex.library.dependencies) {
final target = map[dep.targetLibrary];
final target = map[dep.targetLibrary]!;
vertex.successors.add(target);
}
}
final root = map[component.mainMethod.parent as Library];
final root = map[component.mainMethod!.enclosingLibrary]!;
// Fake imports from root library to every core library so they end up in
// the same loading unit attributed to the user's root library.
@ -73,7 +71,7 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
if (dep.isDeferred) {
continue;
}
var importee = map[dep.targetLibrary];
var importee = map[dep.targetLibrary]!;
if (importer.isDominatedBy(importee)) {
continue;
}
@ -82,7 +80,7 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
}
assert(root.isLoadingRoot);
var loadingUnits = <_LoadingUnitBuilder>[];
final List<_LoadingUnitBuilder> loadingUnits = <_LoadingUnitBuilder>[];
for (var vertex in map.values) {
if (vertex.isLoadingRoot) {
var unit = new _LoadingUnitBuilder(vertex);
@ -101,11 +99,11 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
if (dom == null) {
continue; // Unreachable library.
}
while (dom.loadingUnit == null) {
while (dom!.loadingUnit == null) {
dom = dom.dominator;
}
vertex.loadingUnit = dom.loadingUnit;
vertex.loadingUnit.members.add(vertex.library);
vertex.loadingUnit!.members.add(vertex.library);
}
// 4. Sort loading units so parents are before children. Normally this order
@ -119,7 +117,7 @@ List<LoadingUnit> computeLoadingUnits(Component component) {
}
var index = 0;
loadingUnits.clear();
loadingUnits.add(root.loadingUnit);
loadingUnits.add(root.loadingUnit!);
while (index < loadingUnits.length) {
var unit = loadingUnits[index];
unit.id = ++index;

View file

@ -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
library vm.transformations.cha_devirtualization;
import 'package:kernel/ast.dart';
@ -18,7 +16,8 @@ import '../metadata/direct_call.dart';
Component transformComponent(CoreTypes coreTypes, Component component) {
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
ClosedWorldClassHierarchy hierarchy = new ClassHierarchy(component, coreTypes,
onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
onAmbiguousSupertypes: ignoreAmbiguousSupertypes)
as ClosedWorldClassHierarchy;
final hierarchySubtypes = hierarchy.computeSubtypesInformation();
new CHADevirtualization(coreTypes, component, hierarchy, hierarchySubtypes)
.visitComponent(component);
@ -34,14 +33,14 @@ abstract class Devirtualization extends RecursiveVisitor {
static const _trace = const bool.fromEnvironment('trace.devirtualization');
final DirectCallMetadataRepository _metadata;
Set<Name> _objectMemberNames;
final Set<Name> _objectMemberNames;
Devirtualization(
CoreTypes coreTypes, Component component, ClassHierarchy hierarchy)
: _metadata = new DirectCallMetadataRepository() {
_objectMemberNames = new Set<Name>.from(hierarchy
.getInterfaceMembers(coreTypes.objectClass)
.map((Member m) => m.name));
: _metadata = new DirectCallMetadataRepository(),
_objectMemberNames = new Set<Name>.from(hierarchy
.getInterfaceMembers(coreTypes.objectClass)
.map((Member m) => m.name)) {
component.addMetadataRepository(_metadata);
}
@ -51,7 +50,7 @@ abstract class Devirtualization extends RecursiveVisitor {
(member is Field) || ((member is Procedure) && member.isGetter);
bool isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
final FunctionNode func = target.function;
final FunctionNode func = target.function!;
final positionalArgs = arguments.positional.length;
if ((positionalArgs < func.requiredParameterCount) ||
@ -84,10 +83,10 @@ abstract class Devirtualization extends RecursiveVisitor {
directCall.checkReceiverForNull &&
_objectMemberNames.contains(directCall.target.name);
DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
{bool setter = false});
makeDirectCall(TreeNode node, Member target, DirectCallMetadata directCall) {
makeDirectCall(TreeNode node, Member? target, DirectCallMetadata directCall) {
if (_trace) {
print("[devirt] Resolving ${target} to ${directCall.target}"
" at ${node.location}");
@ -104,12 +103,12 @@ abstract class Devirtualization extends RecursiveVisitor {
}
void _handleMethodInvocation(
TreeNode node, Member target, Arguments arguments) {
TreeNode node, Member? target, Arguments arguments) {
if (target != null && !isMethod(target)) {
return;
}
final DirectCallMetadata directCall = getDirectCall(node, target);
final DirectCallMetadata? directCall = getDirectCall(node, target);
// TODO(alexmarkov): Convert _isLegalTargetForMethodInvocation()
// check into an assertion once front-end implements all override checks.
@ -138,18 +137,18 @@ abstract class Devirtualization extends RecursiveVisitor {
super.visitEqualsCall(node);
final target = node.interfaceTarget;
final DirectCallMetadata directCall = getDirectCall(node, target);
final DirectCallMetadata? directCall = getDirectCall(node, target);
if (directCall != null && !directCall.checkReceiverForNull) {
makeDirectCall(node, target, directCall);
}
}
void _handlePropertyGet(TreeNode node, Member target) {
void _handlePropertyGet(TreeNode node, Member? target) {
if (target != null && !isFieldOrGetter(target)) {
return;
}
final DirectCallMetadata directCall = getDirectCall(node, target);
final DirectCallMetadata? directCall = getDirectCall(node, target);
if ((directCall != null) &&
isFieldOrGetter(directCall.target) &&
@ -170,8 +169,8 @@ abstract class Devirtualization extends RecursiveVisitor {
_handlePropertyGet(node, null);
}
void _handlePropertySet(TreeNode node, Member target) {
final DirectCallMetadata directCall =
void _handlePropertySet(TreeNode node, Member? target) {
final DirectCallMetadata? directCall =
getDirectCall(node, target, setter: true);
if (directCall != null) {
makeDirectCall(node, target, directCall);
@ -200,12 +199,12 @@ class CHADevirtualization extends Devirtualization {
: super(coreTypes, component, hierarchy);
@override
DirectCallMetadata getDirectCall(TreeNode node, Member interfaceTarget,
DirectCallMetadata? getDirectCall(TreeNode node, Member? interfaceTarget,
{bool setter = false}) {
if (interfaceTarget == null) {
return null;
}
Member singleTarget = _hierarchySubtype
Member? singleTarget = _hierarchySubtype
.getSingleTargetForInterfaceInvocation(interfaceTarget, setter: setter);
if (singleTarget == null) {
return null;

View file

@ -292,7 +292,9 @@ class FfiTransformer extends Transformer {
/// Classes corresponding to [NativeType], indexed by [NativeType].
final List<Class> nativeTypesClasses;
Library? currentLibrary;
Library? _currentLibrary;
Library get currentLibrary => _currentLibrary!;
IndexedLibrary? currentLibraryIndex;
FfiTransformer(this.index, this.coreTypes, this.hierarchy,
@ -459,11 +461,11 @@ class FfiTransformer extends Transformer {
@override
TreeNode visitLibrary(Library node) {
assert(currentLibrary == null);
currentLibrary = node;
assert(_currentLibrary == null);
_currentLibrary = node;
currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
final result = super.visitLibrary(node);
currentLibrary = null;
_currentLibrary = null;
return result;
}

View file

@ -2,10 +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
library vm.transformations.ffi_definitions;
import 'dart:math' as math;
import 'package:front_end/src/api_unstable/vm.dart'
@ -71,8 +67,8 @@ void transformLibraries(
ClassHierarchy hierarchy,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
ReferenceFromIndex referenceFromIndex,
ChangedStructureNotifier changedStructureNotifier) {
ReferenceFromIndex? referenceFromIndex,
ChangedStructureNotifier? changedStructureNotifier) {
final LibraryIndex index = LibraryIndex(component,
const ["dart:core", "dart:ffi", "dart:_internal", "dart:typed_data"]);
if (!index.containsLibrary("dart:ffi")) {
@ -96,7 +92,7 @@ class CompoundDependencyGraph<T> implements Graph<T> {
CompoundDependencyGraph(this.map);
Iterable<T> get vertices => map.keys;
Iterable<T> neighborsOf(T vertex) => map[vertex];
Iterable<T> neighborsOf(T vertex) => map[vertex]!;
}
/// Checks and elaborates the dart:ffi compounds and their fields.
@ -109,16 +105,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
Set<Class> transformCompoundsInvalid = {};
Map<Class, NativeTypeCfe> compoundCache = {};
ChangedStructureNotifier changedStructureNotifier;
IndexedLibrary currentLibraryIndex;
ChangedStructureNotifier? changedStructureNotifier;
_FfiDefinitionTransformer(
this.index,
CoreTypes coreTypes,
ClassHierarchy hierarchy,
DiagnosticReporter diagnosticReporter,
ReferenceFromIndex referenceFromIndex,
ReferenceFromIndex? referenceFromIndex,
this.changedStructureNotifier)
: super(index, coreTypes, hierarchy, diagnosticReporter,
referenceFromIndex) {}
@ -185,7 +179,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
report = true;
}
if (component.length == 1) {
if (dependencyGraph.map[component.single].contains(component.single)) {
if (dependencyGraph.map[component.single]!.contains(component.single)) {
// Direct cycle.
report = true;
}
@ -193,7 +187,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
if (report) {
component.forEach((Class e) {
diagnosticReporter.report(
templateFfiFieldCyclic.withArguments(e.superclass.name, e.name,
templateFfiFieldCyclic.withArguments(e.superclass!.name, e.name,
component.map((e) => e.name).toList()),
e.fileOffset,
e.name.length,
@ -232,12 +226,6 @@ class _FfiDefinitionTransformer extends FfiTransformer {
});
}
@override
visitLibrary(Library node) {
currentLibraryIndex = referenceFromIndex?.lookupLibrary(node);
return super.visitLibrary(node);
}
@override
visitExtension(Extension node) {
// The extension and it's members are only metadata.
@ -262,9 +250,12 @@ class _FfiDefinitionTransformer extends FfiTransformer {
final packing = _checkCompoundClass(node);
final indexedClass = currentLibraryIndex?.lookupIndexedClass(node.name);
final IndexedClass? indexedClass =
currentLibraryIndex?.lookupIndexedClass(node.name);
_checkConstructors(node, indexedClass);
indexedCompoundClasses[node] = indexedClass;
if (indexedClass != null) {
indexedCompoundClasses[node] = indexedClass;
}
final fieldsValid = _checkFieldAnnotations(node, packing);
if (fieldsValid) {
@ -278,14 +269,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
}
/// Returns packing if any.
int _checkCompoundClass(Class node) {
int? _checkCompoundClass(Class node) {
if (node.typeParameters.length > 0) {
diagnosticReporter.report(
templateFfiStructGeneric.withArguments(
node.superclass.name, node.name),
node.superclass!.name, node.name),
node.fileOffset,
1,
node.location.file);
node.location!.file);
}
if (node.superclass != structClass && node.superclass != unionClass) {
@ -301,7 +292,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
templateFfiPackedAnnotation.withArguments(node.name),
node.fileOffset,
node.name.length,
node.location.file);
node.location!.file);
}
if (packingAnnotations.isNotEmpty) {
final packing = packingAnnotations.first;
@ -311,7 +302,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
packing == 8 ||
packing == 16)) {
diagnosticReporter.report(messageFfiPackedAnnotationAlignment,
node.fileOffset, node.name.length, node.location.file);
node.fileOffset, node.name.length, node.location!.file);
}
return packing;
}
@ -354,14 +345,14 @@ class _FfiDefinitionTransformer extends FfiTransformer {
if (member is Field) {
return member.type;
}
final Procedure p = member;
final p = member as Procedure;
if (p.isGetter) {
return p.function.returnType;
}
return p.function.positionalParameters.single.type;
}
bool _checkFieldAnnotations(Class node, int packing) {
bool _checkFieldAnnotations(Class node, int? packing) {
bool success = true;
final membersWithAnnotations =
_compoundFieldMembers(node, includeSetters: false);
@ -445,9 +436,9 @@ class _FfiDefinitionTransformer extends FfiTransformer {
success = false;
} else {
final DartType nativeType = InterfaceType(
nativeTypesClasses[_getFieldType(nativeTypeAnnos.first).index],
nativeTypesClasses[_getFieldType(nativeTypeAnnos.first)!.index],
Nullability.legacy);
final DartType shouldBeDartType = convertNativeTypeToDartType(
final DartType? shouldBeDartType = convertNativeTypeToDartType(
nativeType,
allowCompounds: true,
allowHandle: false);
@ -455,11 +446,11 @@ class _FfiDefinitionTransformer extends FfiTransformer {
!env.isSubtypeOf(type, shouldBeDartType,
SubtypeCheckMode.ignoringNullabilities)) {
diagnosticReporter.report(
templateFfiTypeMismatch.withArguments(type, shouldBeDartType,
templateFfiTypeMismatch.withArguments(type, shouldBeDartType!,
nativeType, node.enclosingLibrary.isNonNullableByDefault),
f.fileOffset,
1,
f.location.file);
f.location!.file);
// This class is invalid, but continue reporting other errors on it.
success = false;
}
@ -468,7 +459,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
return success;
}
void _checkPacking(Class outerClass, int outerClassPacking, Class fieldClass,
void _checkPacking(Class outerClass, int? outerClassPacking, Class fieldClass,
Member errorNode) {
if (outerClassPacking == null) {
// Outer struct has no packing, nesting anything is fine.
@ -497,7 +488,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
}
}
void _checkConstructors(Class node, IndexedClass indexedClass) {
void _checkConstructors(Class node, IndexedClass? indexedClass) {
final toRemove = <Initializer>[];
// Constructors cannot have initializers because initializers refer to
@ -510,13 +501,13 @@ class _FfiDefinitionTransformer extends FfiTransformer {
templateFfiFieldInitializer.withArguments(i.field.name.text),
i.fileOffset,
1,
i.location.file);
i.location!.file);
}
}
}
// Remove initializers referring to fields to prevent cascading errors.
for (final Initializer i in toRemove) {
final Constructor c = i.parent;
final c = i.parent as Constructor;
c.initializers.remove(i);
}
@ -565,7 +556,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
final dartType = _compoundMemberType(m);
// Nullable.
NativeTypeCfe type;
NativeTypeCfe? type;
if (isArrayType(dartType)) {
final sizeAnnotations = _getArraySizeAnnotations(m).toList();
if (sizeAnnotations.length == 1) {
@ -584,7 +575,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
final nativeTypeAnnos = _getNativeTypeAnnotations(m).toList();
if (nativeTypeAnnos.length == 1) {
final clazz = nativeTypeAnnos.first;
final nativeType = _getFieldType(clazz);
final nativeType = _getFieldType(clazz)!;
type = PrimitiveNativeTypeCfe(nativeType, clazz);
}
}
@ -635,17 +626,18 @@ class _FfiDefinitionTransformer extends FfiTransformer {
///
/// Returns the total size of the compound (for all ABIs).
void _replaceFields(
Class node, IndexedClass indexedClass, CompoundData compoundData) {
Class node, IndexedClass? indexedClass, CompoundData compoundData) {
final compoundType = compoundData.compoundType as CompoundNativeTypeCfe;
final compoundLayout = compoundType.layout;
_annoteCompoundWithFields(node, compoundType.members, compoundData.packing);
if (compoundType.members.isEmpty) {
diagnosticReporter.report(
templateFfiEmptyStruct.withArguments(node.superclass.name, node.name),
templateFfiEmptyStruct.withArguments(
node.superclass!.name, node.name),
node.fileOffset,
node.name.length,
node.location.file);
node.location!.file);
}
final unalignedAccess = compoundData.packing != null;
@ -653,9 +645,9 @@ class _FfiDefinitionTransformer extends FfiTransformer {
int i = 0;
for (final compoundField in compoundData.compoundFields) {
NativeTypeCfe type = compoundField.type;
Field field = compoundField.field;
Procedure getter = compoundField.getter;
Procedure setter = compoundField.setter;
Field? field = compoundField.field;
Procedure? getter = compoundField.getter;
Procedure? setter = compoundField.setter;
final fieldOffsets = compoundLayout
.map((Abi abi, CompoundLayout v) => MapEntry(abi, v.offsets[i]));
@ -693,7 +685,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
static const vmFfiStructFields = "vm:ffi:struct-fields";
// return value is nullable.
InstanceConstant _compoundAnnotatedFields(Class node) {
InstanceConstant? _compoundAnnotatedFields(Class node) {
for (final annotation in node.annotations) {
if (annotation is ConstantExpression) {
final constant = annotation.constant;
@ -701,7 +693,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
constant.classNode == pragmaClass &&
constant.fieldValues[pragmaName.getterReference] ==
StringConstant(vmFfiStructFields)) {
return constant.fieldValues[pragmaOptions.getterReference];
return constant.fieldValues[pragmaOptions.getterReference]
as InstanceConstant?;
}
}
}
@ -726,7 +719,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
/// Must only be called if all the depencies are already in the cache.
CompoundNativeTypeCfe _compoundAnnotatedNativeTypeCfe(Class compoundClass) {
final layoutConstant = _compoundAnnotatedFields(compoundClass);
final layoutConstant = _compoundAnnotatedFields(compoundClass)!;
final fieldTypes = layoutConstant
.fieldValues[ffiStructLayoutTypesField.getterReference] as ListConstant;
final members = <NativeTypeCfe>[];
@ -763,7 +756,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
// packing is `int?`.
void _annoteCompoundWithFields(
Class node, List<NativeTypeCfe> types, int packing) {
Class node, List<NativeTypeCfe> types, int? packing) {
List<Constant> constants =
types.map((t) => t.generateConstant(this)).toList();
@ -782,7 +775,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
}
void _generateMethodsForField(Class node, Field field, NativeTypeCfe type,
Map<Abi, int> offsets, bool unalignedAccess, IndexedClass indexedClass) {
Map<Abi, int> offsets, bool unalignedAccess, IndexedClass? indexedClass) {
// TODO(johnniwinther): Avoid passing [indexedClass]. When compiling
// incrementally, [field] should already carry the references from
// [indexedClass].
@ -802,7 +795,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
node.addProcedure(getter);
if (!field.isFinal) {
Reference setterReference =
Reference? setterReference =
indexedClass?.lookupSetterReference(field.name) ??
field.setterReference;
assert(setterReference == field.setterReference,
@ -832,8 +825,8 @@ class _FfiDefinitionTransformer extends FfiTransformer {
///
/// If sizes are not supplied still emits a field so that the use site
/// transformer can still rewrite to it.
void _addSizeOfField(Class compound, IndexedClass indexedClass,
[Map<Abi, int> sizes = null]) {
void _addSizeOfField(Class compound, IndexedClass? indexedClass,
[Map<Abi, int>? sizes = null]) {
if (sizes == null) {
sizes = Map.fromEntries(Abi.values.map((abi) => MapEntry(abi, 0)));
}
@ -859,7 +852,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
compound.addProcedure(getter);
}
NativeType _getFieldType(Class c) {
NativeType? _getFieldType(Class c) {
final fieldType = getType(c);
if (fieldType == NativeType.kVoid) {
@ -928,10 +921,7 @@ class _FfiDefinitionTransformer extends FfiTransformer {
class CompoundData {
final List<CompoundField> compoundFields;
// Nullable.
final int packing;
final int? packing;
final NativeTypeCfe compoundType;
CompoundData(this.compoundFields, this.packing, this.compoundType);
@ -939,15 +929,9 @@ class CompoundData {
class CompoundField {
final NativeTypeCfe type;
// Nullable.
final Field field;
// Nullable.
final Procedure getter;
// Nullable.
final Procedure setter;
final Field? field;
final Procedure? getter;
final Procedure? setter;
CompoundField(this.type, this.field, this.getter, this.setter);
}
@ -974,11 +958,11 @@ class CompoundLayout {
/// intimately to AST nodes such as [Class].
abstract class NativeTypeCfe {
factory NativeTypeCfe(FfiTransformer transformer, DartType dartType,
{List<int> arrayDimensions,
{List<int>? arrayDimensions,
Map<Class, NativeTypeCfe> compoundCache = const {}}) {
if (transformer.isPrimitiveType(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
final nativeType = transformer.getType(clazz);
final nativeType = transformer.getType(clazz)!;
return PrimitiveNativeTypeCfe(nativeType, clazz);
}
if (transformer.isPointerType(dartType)) {
@ -987,7 +971,7 @@ abstract class NativeTypeCfe {
if (transformer.isCompoundSubtype(dartType)) {
final clazz = (dartType as InterfaceType).classNode;
if (compoundCache.containsKey(clazz)) {
return compoundCache[clazz];
return compoundCache[clazz]!;
} else {
throw "Class '$clazz' not found in compoundCache.";
}
@ -1094,8 +1078,8 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
}
@override
Map<Abi, int> get alignment => Map.fromEntries(Abi.values.map(
(abi) => MapEntry(abi, nonSizeAlignment[abi][nativeType] ?? size[abi])));
Map<Abi, int> get alignment => Map.fromEntries(Abi.values.map((abi) =>
MapEntry(abi, nonSizeAlignment[abi]![nativeType] ?? size[abi]!)));
@override
Constant generateConstant(FfiTransformer transformer) =>
@ -1107,8 +1091,8 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
bool isUnaligned(Map<Abi, int> offsets) {
final alignments = alignment;
for (final abi in offsets.keys) {
final offset = offsets[abi];
final alignment = alignments[abi];
final offset = offsets[abi]!;
final alignment = alignments[abi]!;
if (offset % alignment != 0) {
return true;
}
@ -1131,7 +1115,7 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
ReturnStatement(StaticInvocation(
(unalignedAccess && isFloat
? transformer.loadUnalignedMethods
: transformer.loadMethods)[nativeType],
: transformer.loadMethods)[nativeType]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@ -1155,7 +1139,7 @@ class PrimitiveNativeTypeCfe implements NativeTypeCfe {
ReturnStatement(StaticInvocation(
(unalignedAccess && isFloat
? transformer.storeUnalignedMethods
: transformer.storeMethods)[nativeType],
: transformer.storeMethods)[nativeType]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@ -1176,7 +1160,7 @@ class PointerNativeTypeCfe implements NativeTypeCfe {
Constant generateConstant(FfiTransformer transformer) => TypeLiteralConstant(
InterfaceType(transformer.pointerClass, Nullability.nonNullable, [
InterfaceType(
transformer.pointerClass.superclass, Nullability.nonNullable)
transformer.pointerClass.superclass!, Nullability.nonNullable)
]));
/// Sample output for `Pointer<Int8> get x =>`:
@ -1195,7 +1179,7 @@ class PointerNativeTypeCfe implements NativeTypeCfe {
transformer.fromAddressInternal,
Arguments([
StaticInvocation(
transformer.loadMethods[NativeType.kIntptr],
transformer.loadMethods[NativeType.kIntptr]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@ -1221,7 +1205,7 @@ class PointerNativeTypeCfe implements NativeTypeCfe {
VariableDeclaration argument,
FfiTransformer transformer) =>
ReturnStatement(StaticInvocation(
transformer.storeMethods[NativeType.kIntptr],
transformer.storeMethods[NativeType.kIntptr]!,
Arguments([
transformer.getCompoundTypedDataBaseField(
ThisExpression(), fileOffset),
@ -1312,10 +1296,10 @@ abstract class CompoundNativeTypeCfe implements NativeTypeCfe {
class StructNativeTypeCfe extends CompoundNativeTypeCfe {
// Nullable int.
final int packing;
final int? packing;
factory StructNativeTypeCfe(Class clazz, List<NativeTypeCfe> members,
{int packing}) {
{int? packing}) {
final layout = Map.fromEntries(Abi.values
.map((abi) => MapEntry(abi, _calculateLayout(members, packing, abi))));
return StructNativeTypeCfe._(clazz, members, packing, layout);
@ -1328,13 +1312,13 @@ class StructNativeTypeCfe extends CompoundNativeTypeCfe {
// Keep consistent with runtime/vm/compiler/ffi/native_type.cc
// NativeStructType::FromNativeTypes.
static CompoundLayout _calculateLayout(
List<NativeTypeCfe> types, int packing, Abi abi) {
List<NativeTypeCfe> types, int? packing, Abi abi) {
int offset = 0;
final offsets = <int>[];
int structAlignment = 1;
for (int i = 0; i < types.length; i++) {
final int size = types[i].size[abi];
int alignment = types[i].alignment[abi];
final int size = types[i].size[abi]!;
int alignment = types[i].alignment[abi]!;
if (packing != null && packing < alignment) {
alignment = packing;
}
@ -1367,8 +1351,8 @@ class UnionNativeTypeCfe extends CompoundNativeTypeCfe {
int unionSize = 1;
int unionAlignment = 1;
for (int i = 0; i < types.length; i++) {
final int size = types[i].size[abi];
int alignment = types[i].alignment[abi];
final int size = types[i].size[abi]!;
int alignment = types[i].alignment[abi]!;
unionSize = math.max(unionSize, size);
unionAlignment = math.max(unionAlignment, alignment);
}

View file

@ -14,7 +14,9 @@ import 'package:front_end/src/api_unstable/vm.dart'
/// Transform @FfiNative annotated functions into FFI native function pointer
/// functions.
void transformLibraries(Component component, List<Library> libraries,
void transformLibraries(
Component component,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
ReferenceFromIndex? referenceFromIndex) {
final index = LibraryIndex(component, ['dart:ffi']);
@ -22,8 +24,8 @@ void transformLibraries(Component component, List<Library> libraries,
if (index.tryGetClass('dart:ffi', 'FfiNative') == null) {
return;
}
final transformer = FfiNativeTransformer(index, diagnosticReporter,
referenceFromIndex);
final transformer =
FfiNativeTransformer(index, diagnosticReporter, referenceFromIndex);
libraries.forEach(transformer.visitLibrary);
}
@ -41,8 +43,8 @@ class FfiNativeTransformer extends Transformer {
final Procedure asFunctionProcedure;
final Procedure fromAddressInternal;
FfiNativeTransformer(LibraryIndex index, this.diagnosticReporter,
this.referenceFromIndex)
FfiNativeTransformer(
LibraryIndex index, this.diagnosticReporter, this.referenceFromIndex)
: ffiNativeClass = index.getClass('dart:ffi', 'FfiNative'),
nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
ffiNativeNameField =
@ -169,11 +171,8 @@ class FfiNativeTransformer extends Transformer {
}
if (!node.isStatic) {
diagnosticReporter.report(
messageFfiNativeAnnotationMustAnnotateStatic,
node.fileOffset,
1,
node.location!.file);
diagnosticReporter.report(messageFfiNativeAnnotationMustAnnotateStatic,
node.fileOffset, 1, node.location!.file);
}
node.isExternal = false;

View file

@ -2,10 +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
library vm.transformations.ffi_use_sites;
import 'package:front_end/src/api_unstable/vm.dart'
show
messageFfiExceptionalReturnNull,
@ -46,7 +42,7 @@ void transformLibraries(
ClassHierarchy hierarchy,
List<Library> libraries,
DiagnosticReporter diagnosticReporter,
ReferenceFromIndex referenceFromIndex) {
ReferenceFromIndex? referenceFromIndex) {
final index = new LibraryIndex(
component, ["dart:ffi", "dart:_internal", "dart:typed_data"]);
if (!index.containsLibrary("dart:ffi")) {
@ -66,7 +62,7 @@ void transformLibraries(
/// Checks and replaces calls to dart:ffi compound fields and methods.
class _FfiUseSiteTransformer extends FfiTransformer {
StaticTypeContext _staticTypeContext;
StaticTypeContext? _staticTypeContext;
bool get isFfiLibrary => currentLibrary == ffiLibrary;
@ -79,7 +75,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
CoreTypes coreTypes,
ClassHierarchy hierarchy,
DiagnosticReporter diagnosticReporter,
ReferenceFromIndex referenceFromIndex)
ReferenceFromIndex? referenceFromIndex)
: super(index, coreTypes, hierarchy, diagnosticReporter,
referenceFromIndex) {}
@ -176,7 +172,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
if (nativeType is InterfaceType) {
Expression inlineSizeOf = _inlineSizeOf(nativeType);
Expression? inlineSizeOf = _inlineSizeOf(nativeType);
if (inlineSizeOf != null) {
return inlineSizeOf;
}
@ -206,7 +202,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
return replacement;
} else if (target == asFunctionMethod) {
final dartType = node.arguments.types[1];
final DartType nativeType = InterfaceType(
final InterfaceType nativeType = InterfaceType(
nativeFunctionClass, Nullability.legacy, [node.arguments.types[0]]);
_ensureNativeTypeValid(nativeType, node);
@ -214,10 +210,9 @@ class _FfiUseSiteTransformer extends FfiTransformer {
_ensureIsLeafIsConst(node);
_ensureLeafCallDoesNotUseHandles(nativeType, node);
final DartType nativeSignature =
(nativeType as InterfaceType).typeArguments[0];
final DartType nativeSignature = nativeType.typeArguments[0];
bool isLeaf = _getIsLeafBoolean(node);
bool? isLeaf = _getIsLeafBoolean(node);
if (isLeaf == null) {
isLeaf = false;
}
@ -243,7 +238,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
final DartType nativeType = InterfaceType(
nativeFunctionClass, Nullability.legacy, [node.arguments.types[0]]);
final Expression func = node.arguments.positional[0];
final DartType dartType = func.getStaticType(_staticTypeContext);
final DartType dartType = func.getStaticType(_staticTypeContext!);
_ensureIsStaticFunction(func);
@ -257,7 +252,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
((node.arguments.types[0] as FunctionType).returnType
as InterfaceType)
.classNode;
final NativeType expectedReturn = getType(expectedReturnClass);
final NativeType? expectedReturn = getType(expectedReturnClass);
if (expectedReturn == NativeType.kVoid ||
expectedReturn == NativeType.kPointer ||
@ -309,7 +304,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
}
final DartType returnType =
exceptionalReturn.getStaticType(_staticTypeContext);
exceptionalReturn.getStaticType(_staticTypeContext!);
if (!env.isSubtypeOf(returnType, funcType.returnType,
SubtypeCheckMode.ignoringNullabilities)) {
@ -339,7 +334,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
// Inline the body to get rid of a generic invocation of sizeOf.
// TODO(http://dartbug.com/39964): Add `allignmentOf<T>()` call.
Expression sizeInBytes = _inlineSizeOf(nativeType);
Expression? sizeInBytes = _inlineSizeOf(nativeType as InterfaceType);
if (sizeInBytes != null) {
if (node.arguments.positional.length == 2) {
sizeInBytes = multiply(node.arguments.positional[1], sizeInBytes);
@ -401,9 +396,9 @@ class _FfiUseSiteTransformer extends FfiTransformer {
.distinct()
.fold(nestedExpression, _invokeCompoundConstructor);
Expression _inlineSizeOf(InterfaceType nativeType) {
Expression? _inlineSizeOf(InterfaceType nativeType) {
final Class nativeClass = nativeType.classNode;
final NativeType nt = getType(nativeClass);
final NativeType? nt = getType(nativeClass);
if (nt == null) {
// User-defined compounds.
final Procedure sizeOfGetter = nativeClass.procedures
@ -457,7 +452,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
.substituteType(lookupFunctionType.withoutTypeParameters)
as FunctionType);
bool isLeaf = _getIsLeafBoolean(node);
bool? isLeaf = _getIsLeafBoolean(node);
if (isLeaf == null) {
isLeaf = false;
}
@ -518,7 +513,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
pointer,
offsetByMethod.name,
Arguments([
multiply(node.arguments.positional[1], _inlineSizeOf(dartType))
multiply(node.arguments.positional[1], _inlineSizeOf(dartType)!)
]),
interfaceTarget: offsetByMethod,
functionType:
@ -536,8 +531,8 @@ class _FfiUseSiteTransformer extends FfiTransformer {
final typedDataBasePrime = typedDataBaseOffset(
getArrayTypedDataBaseField(NullCheck(node.arguments.positional[0])),
multiply(node.arguments.positional[1], _inlineSizeOf(dartType)),
_inlineSizeOf(dartType),
multiply(node.arguments.positional[1], _inlineSizeOf(dartType)!),
_inlineSizeOf(dartType)!,
dartType,
node.fileOffset);
@ -600,7 +595,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
final singleElementSizeVar = VariableDeclaration("#singleElementSize",
initializer: _inlineSizeOf(elementType),
initializer: _inlineSizeOf(elementType as InterfaceType),
type: coreTypes.intNonNullableRawType)
..fileOffset = node.fileOffset;
final elementSizeVar = VariableDeclaration("#elementSize",
@ -684,12 +679,12 @@ class _FfiUseSiteTransformer extends FfiTransformer {
try {
if (target == elementAtMethod) {
final DartType pointerType =
node.receiver.getStaticType(_staticTypeContext);
final DartType nativeType = _pointerTypeGetTypeArg(pointerType);
node.receiver.getStaticType(_staticTypeContext!);
final DartType nativeType = _pointerTypeGetTypeArg(pointerType)!;
_ensureNativeTypeValid(nativeType, node, allowCompounds: true);
Expression inlineSizeOf = _inlineSizeOf(nativeType);
Expression? inlineSizeOf = _inlineSizeOf(nativeType as InterfaceType);
if (inlineSizeOf != null) {
// Generates `receiver.offsetBy(inlineSizeOfExpression)`.
return InstanceInvocation(
@ -714,7 +709,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
return node;
}
DartType _pointerTypeGetTypeArg(DartType pointerType) {
DartType? _pointerTypeGetTypeArg(DartType pointerType) {
return pointerType is InterfaceType ? pointerType.typeArguments[0] : null;
}
@ -724,7 +719,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
final DartType correspondingDartType = convertNativeTypeToDartType(
nativeType,
allowCompounds: true,
allowHandle: allowHandle);
allowHandle: allowHandle)!;
if (dartType == correspondingDartType) return;
if (env.isSubtypeOf(correspondingDartType, dartType,
SubtypeCheckMode.ignoringNullabilities)) {
@ -787,7 +782,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
/// Returns the class that should not be implemented or extended.
///
/// If the superclass is not sealed, returns `null`.
Class _extendsOrImplementsSealedClass(Class klass) {
Class? _extendsOrImplementsSealedClass(Class klass) {
// Classes in dart:ffi themselves can extend FFI classes.
if (klass == arrayClass ||
klass == arraySizeClass ||
@ -824,7 +819,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
}
void _ensureNotExtendsOrImplementsSealedClass(Class klass) {
final Class extended = _extendsOrImplementsSealedClass(klass);
final Class? extended = _extendsOrImplementsSealedClass(klass);
if (extended != null) {
diagnosticReporter.report(
templateFfiExtendsOrImplementsSealedClass
@ -840,7 +835,7 @@ class _FfiUseSiteTransformer extends FfiTransformer {
// - `true` if leaf
// - `false` if not leaf
// - `null` if the expression is not valid (e.g. non-const bool, null)
bool _getIsLeafBoolean(StaticInvocation node) {
bool? _getIsLeafBoolean(StaticInvocation node) {
for (final named in node.arguments.named) {
if (named.name == 'isLeaf') {
final expr = named.value;
@ -893,8 +888,8 @@ class _FfiUseSiteTransformer extends FfiTransformer {
}
}
// Check if any of the argument types are Handle.
for (InterfaceType param in functionType.positionalParameters) {
if (param.classNode == handleClass) {
for (DartType param in functionType.positionalParameters) {
if ((param as InterfaceType).classNode == handleClass) {
diagnosticReporter.report(messageFfiLeafCallMustNotTakeHandle,
node.fileOffset, 1, node.location?.file);
}

View file

@ -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:front_end/src/api_unstable/vm.dart'
show isRedirectingFactoryField;
import 'package:kernel/ast.dart';
@ -24,23 +22,24 @@ class ListLiteralsLowering {
final Procedure _defaultFactory;
// Specialized _GrowableList._literalN(e1, ..., eN) factories.
final List<Procedure> _specializedFactories =
List<Procedure>.filled(numSpecializedFactories, null);
final List<Procedure?> _specializedFactories =
List<Procedure?>.filled(numSpecializedFactories, null);
ListLiteralsLowering(this.coreTypes)
: _defaultFactory =
coreTypes.index.getMember('dart:core', '_GrowableList', '');
coreTypes.index.getProcedure('dart:core', '_GrowableList', '');
Procedure getSpecializedFactory(int length) =>
(_specializedFactories[length - 1] ??= coreTypes.index
.getMember('dart:core', '_GrowableList', '_literal$length'));
.getProcedure('dart:core', '_GrowableList', '_literal$length'));
Expression transformListLiteral(ListLiteral node) {
if (node.isConst) {
throw 'Unexpected constant ListLiteral node'
' (such nodes should be converted to ConstantExpression): $node';
}
if (node.parent is Field && isRedirectingFactoryField(node.parent)) {
final parent = node.parent;
if (parent is Field && isRedirectingFactoryField(parent)) {
// Do not transform list literals which are used to represent
// redirecting factories.
return node;

View file

@ -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/class_hierarchy.dart' show ClassHierarchy;
import 'package:kernel/core_types.dart' show CoreTypes;
@ -39,8 +37,8 @@ class _Lowering extends Transformer {
final FactorySpecializer factorySpecializer;
final ListLiteralsLowering listLiteralsLowering;
Member _currentMember;
StaticTypeContext _cachedStaticTypeContext;
Member? _currentMember;
StaticTypeContext? _cachedStaticTypeContext;
_Lowering(CoreTypes coreTypes, ClassHierarchy hierarchy, this.nullSafety)
: env = TypeEnvironment(coreTypes, hierarchy),
@ -49,7 +47,7 @@ class _Lowering extends Transformer {
listLiteralsLowering = ListLiteralsLowering(coreTypes);
StaticTypeContext get _staticTypeContext =>
_cachedStaticTypeContext ??= StaticTypeContext(_currentMember, env);
_cachedStaticTypeContext ??= StaticTypeContext(_currentMember!, env);
@override
defaultMember(Member node) {

View file

@ -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:expect/expect.dart';
import 'package:vm/dominators.dart';