[dart2js] Migrate interceptor_data.dart to null safety.

Change-Id: I0c3f767cad1ae372d116a13b408affb967a56f2a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/260245
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Auto-Submit: Nate Biggs <natebiggs@google.com>
This commit is contained in:
Nate Biggs 2022-09-21 19:56:01 +00:00
parent 3a7e7430dc
commit 76169b54a8

View file

@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a // 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. // BSD-style license that can be found in the LICENSE file.
// @dart = 2.10
library js_backend.interceptor_data; library js_backend.interceptor_data;
import '../common/elements.dart' import '../common/elements.dart'
@ -176,18 +174,13 @@ class InterceptorDataImpl implements InterceptorData {
@override @override
bool isInterceptedMixinSelector( bool isInterceptedMixinSelector(
Selector selector, AbstractValue mask, JClosedWorld closedWorld) { Selector selector, AbstractValue? mask, JClosedWorld closedWorld) {
Set<MemberEntity> elements = Set<MemberEntity> elements = _interceptedMixinElements[selector.name] ??=
_interceptedMixinElements.putIfAbsent(selector.name, () { (interceptedMembers[selector.name]
Set<MemberEntity> elements = interceptedMembers[selector.name]; ?.where((element) => classesMixedIntoInterceptedClasses
if (elements == null) return null; .contains(element.enclosingClass))
return elements .toSet() ??
.where((element) => classesMixedIntoInterceptedClasses const {});
.contains(element.enclosingClass))
.toSet();
});
if (elements == null) return false;
if (elements.isEmpty) return false; if (elements.isEmpty) return false;
return elements.any((element) { return elements.any((element) {
return selector.applies(element) && return selector.applies(element) &&
@ -216,21 +209,21 @@ class InterceptorDataImpl implements InterceptorData {
@override @override
Set<ClassEntity> getInterceptedClassesOn( Set<ClassEntity> getInterceptedClassesOn(
String name, JClosedWorld closedWorld) { String name, JClosedWorld closedWorld) {
Set<MemberEntity> intercepted = interceptedMembers[name]; final intercepted = interceptedMembers[name];
if (intercepted == null) return _noClasses; if (intercepted == null) return _noClasses;
return _interceptedClassesCache.putIfAbsent(name, () { return _interceptedClassesCache.putIfAbsent(name, () {
// Populate the cache by running through all the elements and // Populate the cache by running through all the elements and
// determine if the given selector applies to them. // determine if the given selector applies to them.
Set<ClassEntity> result = {}; Set<ClassEntity> result = {};
for (MemberEntity element in intercepted) { for (MemberEntity element in intercepted) {
ClassEntity classElement = element.enclosingClass; final classElement = element.enclosingClass!;
if (_isCompileTimeOnlyClass(classElement)) continue; if (_isCompileTimeOnlyClass(classElement)) continue;
if (_nativeData.isNativeOrExtendsNative(classElement) || if (_nativeData.isNativeOrExtendsNative(classElement) ||
interceptedClasses.contains(classElement)) { interceptedClasses.contains(classElement)) {
result.add(classElement); result.add(classElement);
} }
if (classesMixedIntoInterceptedClasses.contains(classElement)) { if (classesMixedIntoInterceptedClasses.contains(classElement)) {
Set<ClassEntity> nativeSubclasses = final nativeSubclasses =
nativeSubclassesOfMixin(classElement, closedWorld); nativeSubclassesOfMixin(classElement, closedWorld);
if (nativeSubclasses != null) result.addAll(nativeSubclasses); if (nativeSubclasses != null) result.addAll(nativeSubclasses);
} }
@ -239,16 +232,15 @@ class InterceptorDataImpl implements InterceptorData {
}); });
} }
Set<ClassEntity> nativeSubclassesOfMixin( Set<ClassEntity>? nativeSubclassesOfMixin(
ClassEntity mixin, JClosedWorld closedWorld) { ClassEntity mixin, JClosedWorld closedWorld) {
Iterable<ClassEntity> uses = closedWorld.mixinUsesOf(mixin); Iterable<ClassEntity> uses = closedWorld.mixinUsesOf(mixin);
Set<ClassEntity> result = null; Set<ClassEntity>? result;
for (ClassEntity use in uses) { for (ClassEntity use in uses) {
closedWorld.classHierarchy.forEachStrictSubclassOf(use, closedWorld.classHierarchy.forEachStrictSubclassOf(use,
(ClassEntity subclass) { (ClassEntity subclass) {
if (_nativeData.isNativeOrExtendsNative(subclass)) { if (_nativeData.isNativeOrExtendsNative(subclass)) {
if (result == null) result = {}; (result ??= {}).add(subclass);
result.add(subclass);
} }
return IterationStep.CONTINUE; return IterationStep.CONTINUE;
}); });
@ -257,7 +249,7 @@ class InterceptorDataImpl implements InterceptorData {
} }
@override @override
bool isInterceptedClass(ClassEntity element) { bool isInterceptedClass(ClassEntity? element) {
if (element == null) return false; if (element == null) return false;
if (_nativeData.isNativeOrExtendsNative(element)) return true; if (_nativeData.isNativeOrExtendsNative(element)) return true;
if (interceptedClasses.contains(element)) return true; if (interceptedClasses.contains(element)) return true;
@ -276,7 +268,7 @@ class InterceptorDataImpl implements InterceptorData {
if (!closedWorld.dartTypes.treatAsRawType(type)) return false; if (!closedWorld.dartTypes.treatAsRawType(type)) return false;
if (type is FutureOrType) return false; if (type is FutureOrType) return false;
InterfaceType interfaceType = type; final interfaceType = type as InterfaceType;
ClassEntity classElement = interfaceType.element; ClassEntity classElement = interfaceType.element;
if (isInterceptedClass(classElement)) return false; if (isInterceptedClass(classElement)) return false;
return closedWorld.classHierarchy.hasOnlySubclasses(classElement); return closedWorld.classHierarchy.hasOnlySubclasses(classElement);
@ -321,7 +313,7 @@ class InterceptorDataBuilderImpl implements InterceptorDataBuilder {
if (member.name == Identifiers.call) return; if (member.name == Identifiers.call) return;
// All methods on [Object] are shadowed by [Interceptor]. // All methods on [Object] are shadowed by [Interceptor].
if (cls == _commonElements.objectClass) return; if (cls == _commonElements.objectClass) return;
Set<MemberEntity> set = _interceptedElements[member.name] ??= {}; final set = _interceptedElements[member.name!] ??= {};
set.add(member); set.add(member);
}); });
@ -338,7 +330,7 @@ class InterceptorDataBuilderImpl implements InterceptorDataBuilder {
(ClassEntity cls, MemberEntity member) { (ClassEntity cls, MemberEntity member) {
// All methods on [Object] are shadowed by [Interceptor]. // All methods on [Object] are shadowed by [Interceptor].
if (cls == _commonElements.objectClass) return; if (cls == _commonElements.objectClass) return;
Set<MemberEntity> set = _interceptedElements[member.name] ??= {}; final set = _interceptedElements[member.name!] ??= {};
set.add(member); set.add(member);
}); });
} }
@ -391,7 +383,7 @@ class OneShotInterceptorData {
return namer.nameForOneShotInterceptor(selector, classes); return namer.nameForOneShotInterceptor(selector, classes);
} }
void registerSpecializedGetInterceptor(Set<ClassEntity> classes) { void registerSpecializedGetInterceptor(Iterable<ClassEntity> classes) {
if (classes.contains(_commonElements.jsInterceptorClass)) { if (classes.contains(_commonElements.jsInterceptorClass)) {
// We can't use a specialized [getInterceptorMethod], so we make // We can't use a specialized [getInterceptorMethod], so we make
// sure we emit the one with all checks. // sure we emit the one with all checks.