[dart2js] Enable core lints.

Change-Id: Id5a14797e3e5eb8b68bd009d65b474748902fbe0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400162
Reviewed-by: Nate Biggs <natebiggs@google.com>
This commit is contained in:
Mayank Patke
2024-12-13 11:24:50 -08:00
committed by Commit Queue
parent 49076fe6f4
commit 017bda44cf
119 changed files with 612 additions and 529 deletions
+2
View File
@@ -12,6 +12,8 @@ analyzer:
strict-inference: true
strict-raw-types: true
include: package:lints/core.yaml
linter:
rules:
- always_declare_return_types
-6
View File
@@ -272,12 +272,6 @@ class ClosureRepresentationInfo extends ScopeInfo {
/// The signature method for [callMethod] if needed.
FunctionEntity? get signatureMethod => null;
/// List of locals that this closure class has created corresponding field
/// entities for.
@deprecated
List<Local> getCreatedFieldEntities(KernelToLocalsMap localsMap) =>
const <Local>[];
/// As shown in the example in the comments at the top of this class, we
/// create fields in the closure class for each captured variable. This is an
/// accessor the [local] for which [field] was created.
+1 -1
View File
@@ -308,7 +308,7 @@ class CodegenRegistry {
@override
String toString() => 'CodegenRegistry for $_currentElement';
@deprecated
@Deprecated("Use StaticUse for precise registration of statically known use")
void registerInstantiatedClass(ClassEntity element) {
registerInstantiation(_elementEnvironment.getRawType(element));
}
+16 -16
View File
@@ -97,67 +97,67 @@ abstract class CommonElements {
/// The dart:core library.
late final LibraryEntity coreLibrary =
_env.lookupLibrary(Uris.dart_core, required: true)!;
_env.lookupLibrary(Uris.dartCore, required: true)!;
/// The dart:async library.
late final LibraryEntity? asyncLibrary = _env.lookupLibrary(Uris.dart_async);
late final LibraryEntity? asyncLibrary = _env.lookupLibrary(Uris.dartAsync);
/// The dart:collection library.
late final LibraryEntity? collectionLibrary =
_env.lookupLibrary(Uris.dart_collection);
_env.lookupLibrary(Uris.dartCollection);
/// The dart:mirrors library.
/// Null if the program doesn't access dart:mirrors.
late final LibraryEntity? mirrorsLibrary =
_env.lookupLibrary(Uris.dart_mirrors);
_env.lookupLibrary(Uris.dartMirrors);
/// The dart:typed_data library.
late final LibraryEntity typedDataLibrary =
_env.lookupLibrary(Uris.dart__native_typed_data, required: true)!;
_env.lookupLibrary(Uris.dartNativeTypedData, required: true)!;
/// The dart:_js_shared_embedded_names library.
late final LibraryEntity sharedEmbeddedNamesLibrary =
_env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true)!;
_env.lookupLibrary(Uris.dartJSSharedEmbeddedNames, required: true)!;
/// The dart:_js_helper library.
late final LibraryEntity? jsHelperLibrary =
_env.lookupLibrary(Uris.dart__js_helper);
_env.lookupLibrary(Uris.dartJSHelper);
/// The dart:_late_helper library
late final LibraryEntity? lateHelperLibrary =
_env.lookupLibrary(Uris.dart__late_helper);
_env.lookupLibrary(Uris.dartLateHelper);
/// The dart:_interceptors library.
late final LibraryEntity? interceptorsLibrary =
_env.lookupLibrary(Uris.dart__interceptors);
_env.lookupLibrary(Uris.dartInterceptors);
/// The dart:_foreign_helper library.
late final LibraryEntity? foreignLibrary =
_env.lookupLibrary(Uris.dart__foreign_helper);
_env.lookupLibrary(Uris.dartForeignHelper);
/// The dart:_rti library.
late final LibraryEntity rtiLibrary =
_env.lookupLibrary(Uris.dart__rti, required: true)!;
_env.lookupLibrary(Uris.dartRti, required: true)!;
/// The dart:_internal library.
late final LibraryEntity internalLibrary =
_env.lookupLibrary(Uris.dart__internal, required: true)!;
_env.lookupLibrary(Uris.dartInternal, required: true)!;
/// The dart:js_util library.
late final LibraryEntity? dartJsUtilLibrary =
_env.lookupLibrary(Uris.dart_js_util);
_env.lookupLibrary(Uris.dartJSUtil);
/// The package:js library.
late final LibraryEntity? packageJsLibrary =
_env.lookupLibrary(Uris.package_js);
_env.lookupLibrary(Uris.packageJS);
/// The dart:_js_annotations library.
late final LibraryEntity? dartJsAnnotationsLibrary =
_env.lookupLibrary(Uris.dart__js_annotations);
_env.lookupLibrary(Uris.dartJSAnnotations);
/// The dart:js_interop library.
late final LibraryEntity? dartJsInteropLibrary =
_env.lookupLibrary(Uris.dart__js_interop);
_env.lookupLibrary(Uris.dartJSInterop);
/// The `NativeTypedData` class from dart:typed_data.
ClassEntity get typedDataClass =>
+29 -30
View File
@@ -159,7 +159,7 @@ class Selectors {
///
/// These objects are shared between different runs in batch-mode and must
/// thus remain in the [Selector.canonicalizedValues] map.
static final List<Selector> ALL = <Selector>[
static final List<Selector> all = <Selector>[
cancel,
current,
iterator,
@@ -189,94 +189,93 @@ class Selectors {
/// [Uri]s commonly used.
class Uris {
/// The URI for 'dart:async'.
static final Uri dart_async = Uri(scheme: 'dart', path: 'async');
static final Uri dartAsync = Uri(scheme: 'dart', path: 'async');
/// The URI for 'dart:collection'.
static final Uri dart_collection = Uri(scheme: 'dart', path: 'collection');
static final Uri dartCollection = Uri(scheme: 'dart', path: 'collection');
/// The URI for 'dart:core'.
static final Uri dart_core = Uri(scheme: 'dart', path: 'core');
static final Uri dartCore = Uri(scheme: 'dart', path: 'core');
/// The URI for 'dart:html'.
static final Uri dart_html = Uri(scheme: 'dart', path: 'html');
static final Uri dartHtml = Uri(scheme: 'dart', path: 'html');
/// The URI for 'dart:html_common'.
static final Uri dart_html_common = Uri(scheme: 'dart', path: 'html_common');
static final Uri dartHtmlCommon = Uri(scheme: 'dart', path: 'html_common');
/// The URI for 'dart:indexed_db'.
static final Uri dart_indexed_db = Uri(scheme: 'dart', path: 'indexed_db');
static final Uri dartIndexedDB = Uri(scheme: 'dart', path: 'indexed_db');
/// The URI for 'dart:isolate'.
static final Uri dart_isolate = Uri(scheme: 'dart', path: 'isolate');
static final Uri dartIsolate = Uri(scheme: 'dart', path: 'isolate');
/// The URI for 'dart:math'.
static final Uri dart_math = Uri(scheme: 'dart', path: 'math');
static final Uri dartMath = Uri(scheme: 'dart', path: 'math');
/// The URI for 'dart:mirrors'.
static final Uri dart_mirrors = Uri(scheme: 'dart', path: 'mirrors');
static final Uri dartMirrors = Uri(scheme: 'dart', path: 'mirrors');
/// The URI for 'dart:_internal'.
static final Uri dart__internal = Uri(scheme: 'dart', path: '_internal');
static final Uri dartInternal = Uri(scheme: 'dart', path: '_internal');
/// The URI for 'dart:_native_typed_data'.
static final Uri dart__native_typed_data =
static final Uri dartNativeTypedData =
Uri(scheme: 'dart', path: '_native_typed_data');
/// The URI for 'dart:typed_data'.
static final Uri dart_typed_data = Uri(scheme: 'dart', path: 'typed_data');
static final Uri dartTypedData = Uri(scheme: 'dart', path: 'typed_data');
/// The URI for 'dart:svg'.
static final Uri dart_svg = Uri(scheme: 'dart', path: 'svg');
static final Uri dartSvg = Uri(scheme: 'dart', path: 'svg');
/// The URI for 'dart:web_audio'.
static final Uri dart_web_audio = Uri(scheme: 'dart', path: 'web_audio');
static final Uri dartWebAudio = Uri(scheme: 'dart', path: 'web_audio');
/// The URI for 'dart:web_gl'.
static final Uri dart_web_gl = Uri(scheme: 'dart', path: 'web_gl');
static final Uri dartWebGL = Uri(scheme: 'dart', path: 'web_gl');
/// The URI for 'dart:_js_helper'.
static final Uri dart__js_helper = Uri(scheme: 'dart', path: '_js_helper');
static final Uri dartJSHelper = Uri(scheme: 'dart', path: '_js_helper');
/// The URI for 'dart:_late_helper'.
static final Uri dart__late_helper =
Uri(scheme: 'dart', path: '_late_helper');
static final Uri dartLateHelper = Uri(scheme: 'dart', path: '_late_helper');
/// The URI for 'dart:_rti'.
static final Uri dart__rti = Uri(scheme: 'dart', path: '_rti');
static final Uri dartRti = Uri(scheme: 'dart', path: '_rti');
/// The URI for 'dart:_interceptors'.
static final Uri dart__interceptors =
static final Uri dartInterceptors =
Uri(scheme: 'dart', path: '_interceptors');
/// The URI for 'dart:_foreign_helper'.
static final Uri dart__foreign_helper =
static final Uri dartForeignHelper =
Uri(scheme: 'dart', path: '_foreign_helper');
/// The URI for 'dart:_js_names'.
static final Uri dart__js_names = Uri(scheme: 'dart', path: '_js_names');
static final Uri dartJSNames = Uri(scheme: 'dart', path: '_js_names');
/// The URI for 'dart:_js_embedded_names'.
static final Uri dart__js_embedded_names =
static final Uri dartJSEmbeddedNames =
Uri(scheme: 'dart', path: '_js_embedded_names');
/// The URI for 'dart:_js_shared_embedded_names'.
static final Uri dart__js_shared_embedded_names =
static final Uri dartJSSharedEmbeddedNames =
Uri(scheme: 'dart', path: '_js_shared_embedded_names');
/// The URI for 'dart:js_util'.
static final Uri dart_js_util = Uri(scheme: 'dart', path: 'js_util');
static final Uri dartJSUtil = Uri(scheme: 'dart', path: 'js_util');
/// The URI for 'package:js'.
static final Uri package_js = Uri(scheme: 'package', path: 'js/js.dart');
static final Uri packageJS = Uri(scheme: 'package', path: 'js/js.dart');
/// The URI for 'dart:_js_annotations'.
static final Uri dart__js_annotations =
static final Uri dartJSAnnotations =
Uri(scheme: 'dart', path: '_js_annotations');
/// The URI for 'dart:js_interop'.
static final Uri dart__js_interop = Uri(scheme: 'dart', path: 'js_interop');
static final Uri dartJSInterop = Uri(scheme: 'dart', path: 'js_interop');
/// The URI for 'package:meta/dart2js.dart'.
static final Uri package_meta_dart2js =
static final Uri packageMetaDart2js =
Uri(scheme: 'package', path: 'meta/dart2js.dart');
}
@@ -15,6 +15,8 @@
/// number may have a lot more variability depending on system conditions.
/// Our goal with this number is not so much to be exact, but to have a good
/// metric we can track overtime and use to detect improvements and regressions.
library;
import 'dart:developer';
import 'package:vm_service/vm_service_io.dart' as vm_service_io;
+4
View File
@@ -245,9 +245,13 @@ class Measurer {
final bool enableTaskMeasurements;
static int _hashCodeGenerator = 197;
@override
final int hashCode = _hashCodeGenerator++;
@override
bool operator ==(other) => identical(this, other);
Measurer({this.enableTaskMeasurements = false});
/// The currently running task, that is, the task whose [Stopwatch] is
+1 -1
View File
@@ -328,7 +328,7 @@ class Compiler {
StaticUse.clearCache();
// The selector objects held in static fields must remain canonical.
for (Selector selector in Selectors.ALL) {
for (Selector selector in Selectors.all) {
Selector.canonicalizedValues
.putIfAbsent(selector.hashCode, () => <Selector>[])
.add(selector);
+7 -7
View File
@@ -30,7 +30,7 @@ const String OUTPUT_LANGUAGE_DART = 'Dart';
/// an aid in reproducing bug reports.
///
/// The actual string is rewritten by a wrapper script when included in the sdk.
String? BUILD_ID;
String? buildID;
/// The data passed to the [HandleOption] callback is either a single
/// string argument, or the arguments iterator for multiple arguments
@@ -165,8 +165,8 @@ Future<api.CompilationResult> compile(List<String> argv,
void passThrough(String argument) => options.add(argument);
void ignoreOption(String argument) {}
if (BUILD_ID != null) {
passThrough("--build-id=$BUILD_ID");
if (buildID != null) {
passThrough("--build-id=$buildID");
}
Uri extractResolvedFileUri(String argument) {
@@ -1177,7 +1177,7 @@ be removed in a future version:
void helpAndExit(bool wantHelp, bool wantVersion, bool verbose) {
if (wantVersion) {
var version = (BUILD_ID == null) ? '<non-SDK build>' : BUILD_ID;
var version = (buildID == null) ? '<non-SDK build>' : buildID;
print('Dart-to-JavaScript compiler (dart2js) version: $version');
}
if (wantHelp) {
@@ -1212,14 +1212,14 @@ Future<void> main(List<String> arguments) async {
// file and expanding them into the resulting argument list.
//
// TODO: Remove when internal tooling targets bazelMain instead of this.
if (arguments.length > 0 && arguments.last.startsWith('@')) {
if (arguments.isNotEmpty && arguments.last.startsWith('@')) {
var extra = _readLines(arguments.last.substring(1));
arguments = arguments.take(arguments.length - 1).followedBy(extra).toList();
}
// Since the sdk/bin/dart2js script adds its own arguments in front of
// user-supplied arguments we search for '--batch' at the end of the list.
if (arguments.length > 0 && arguments.last == "--batch") {
if (arguments.isNotEmpty && arguments.last == "--batch") {
batchMain(arguments.sublist(0, arguments.length - 1));
return;
}
@@ -1227,7 +1227,7 @@ Future<void> main(List<String> arguments) async {
}
Future<String?> bazelMain(List<String> arguments) async {
if (arguments.length > 0 && arguments.last.startsWith('@')) {
if (arguments.isNotEmpty && arguments.last.startsWith('@')) {
var extra = _readLines(arguments.last.substring(1));
arguments = arguments.take(arguments.length - 1).followedBy(extra).toList();
}
@@ -49,7 +49,7 @@ class MemberEntityData extends EntityData<MemberEntity> {
class LocalFunctionEntityData extends EntityData<Local> {
@override
void accept(EntityDataVisitor) {}
void accept(EntityDataVisitor _) {}
// Note: local functions are not updated recursively because the
// dependencies are already visited as dependencies of the enclosing member.
@@ -407,8 +407,8 @@ class ImportDescription {
/// Returns the filename for the output-unit named [name].
///
/// The filename is of the form "<main output file>_<name>.part.js".
/// If [addExtension] is false, the ".part.js" suffix is left out.
/// The filename is of the form `<main output file>_<name>.part.js`.
/// If [addExtension] is false, the `.part.js` suffix is left out.
String deferredPartFileName(CompilerOptions options, String name,
{bool addExtension = true}) {
assert(name != "");
@@ -11,12 +11,12 @@ import 'spannable.dart';
///
/// This flag is automatically set to true if helper methods like, [debugPrint],
/// [debugWrapPrint], [trace], and [reportHere] are called.
bool DEBUG_MODE = false;
bool debugMode = false;
/// Assert that [DEBUG_MODE] is `true` and provide [message] as part of the
/// Assert that [debugMode] is `true` and provide [message] as part of the
/// error message.
void assertDebugMode(String message) {
assert(DEBUG_MODE,
assert(debugMode,
failedAt(NO_LOCATION_SPANNABLE, 'Debug mode is not enabled: $message'));
}
+9 -7
View File
@@ -85,8 +85,8 @@ class DumpInfoJsAstRegistry {
void registerConstantAst(ConstantValue constant, jsAst.Node code) {
if (_disabled) return;
assert(!_constantRegistry.containsKey(constant) ||
_constantRegistry[constant] == code);
assert(!_constantRegistry.containsValue(constant) ||
_constantRegistry[code] == constant);
_constantRegistry[code] = constant;
}
@@ -854,8 +854,9 @@ class KernelInfoCollector {
}
ClassInfo? visitClass(ir.Class clazz, {required ClassEntity classEntity}) {
if (state.entityToInfo[classEntity] != null)
if (state.entityToInfo[classEntity] != null) {
return state.entityToInfo[classEntity] as ClassInfo?;
}
final supers = <ClassInfo>[];
clazz.supers.forEach((supertype) {
@@ -979,10 +980,10 @@ class KernelInfoCollector {
type: functionType.toStringInternal());
final functionParent = function.parent;
if (functionParent is ir.Member)
if (functionParent is ir.Member) {
_addClosureInfo(info, functionParent,
libraryEntity: functionEntity.library, memberEntity: functionEntity);
else {
} else {
// This branch is only reached when function is a 'call' method.
// TODO(markzipan): Ensure call methods never have children.
info.closures = [];
@@ -1349,7 +1350,7 @@ class DumpInfoAnnotator {
kFunctionInfos.length <= 1,
'Ambiguous function resolution. '
'Expected single or none, found $kFunctionInfos');
if (kFunctionInfos.length == 0) return null;
if (kFunctionInfos.isEmpty) return null;
final kFunctionInfo = kFunctionInfos.first;
kernelInfo.state.entityToInfo[function] = kFunctionInfo;
@@ -1861,8 +1862,9 @@ class LocalFunctionInfoCollector extends ir.RecursiveVisitor {
@override
void visitLocalFunctionInvocation(ir.LocalFunctionInvocation node) {
if (localFunctions[node.localFunction] == null)
if (localFunctions[node.localFunction] == null) {
visitFunctionDeclaration(node.localFunction);
}
localFunctions[node.localFunction]!.isInvoked = true;
}
}
@@ -156,8 +156,9 @@ String? constructOperatorNameOrNull(String op, bool isUnary) {
String constructOperatorName(String op, bool isUnary) {
String? operatorName = constructOperatorNameOrNull(op, isUnary);
if (operatorName == null)
if (operatorName == null) {
throw 'Unhandled operator: $op';
else
} else {
return operatorName;
}
}
+1 -1
View File
@@ -60,7 +60,7 @@ abstract class Name {
Uri? get uri;
/// Returns `true` when [s] is private if used as an identifier.
static bool isPrivateName(String s) => !s.isEmpty && s.codeUnitAt(0) == $_;
static bool isPrivateName(String s) => s.isNotEmpty && s.codeUnitAt(0) == $_;
/// Returns `true` when [s] is public if used as an identifier.
static bool isPublicName(String s) => !isPrivateName(s);
+21 -12
View File
@@ -17,12 +17,12 @@ import 'entities.dart';
/// This hierarchy is a super hierarchy of the use-case specific hierarchies
/// used in different parts of the compiler. This hierarchy abstracts details
/// not generally needed or required for the Dart type hierarchy. For instance,
/// the hierarchy in 'resolution_types.dart' has properties supporting lazy
/// computation (like computeAlias) and distinctions between 'Foo' and
/// 'Foo<dynamic>', features that are not needed for code generation and not
/// the hierarchy in `resolution_types.dart` has properties supporting lazy
/// computation (like computeAlias) and distinctions between `Foo` and
/// `Foo<dynamic>`, features that are not needed for code generation and not
/// supported from kernel.
///
/// Current only 'resolution_types.dart' implement this hierarchy but when the
/// Current only `resolution_types.dart` implement this hierarchy but when the
/// compiler moves to use [Entity] instead of [Element] this hierarchy can be
/// implemented directly but other entity systems, for instance based directly
/// on kernel ir without the need for [Element].
@@ -348,12 +348,11 @@ class InterfaceType extends DartType {
@override
bool get isObject =>
element.name == 'Object' &&
element.library.canonicalUri == Uris.dart_core;
element.name == 'Object' && element.library.canonicalUri == Uris.dartCore;
@override
bool get isNull =>
element.name == 'Null' && element.library.canonicalUri == Uris.dart_core;
element.name == 'Null' && element.library.canonicalUri == Uris.dartCore;
@override
bool get containsTypeVariables =>
@@ -515,7 +514,7 @@ class TypeVariableType extends DartType {
/// A type variable declared on a function type.
///
/// For instance `T` in
/// void Function<T>(T t)
/// `void Function<T>(T t)`
///
/// Such a type variable is different from a [TypeVariableType] because it
/// doesn't have a unique identity; is equal to any other
@@ -554,6 +553,9 @@ class FunctionTypeVariable extends DartType {
@override
int get hashCode => index * 113; // ignore bound which can have cycles.
@override
bool operator ==(other) => identical(this, other);
@override
bool _equals(DartType other, _Assumptions? assumptions) {
if (identical(this, other)) return true;
@@ -1074,7 +1076,9 @@ class _LegacyErasureVisitor extends DartTypeVisitor<DartType, Null> {
identical(parameterTypes, type.parameterTypes) &&
identical(optionalParameterTypes, type.optionalParameterTypes) &&
identical(namedParameterTypes, type.namedParameterTypes) &&
erasableTypeVariables.isEmpty) return type;
erasableTypeVariables.isEmpty) {
return type;
}
// TODO(48820): Can we avoid the cast?
return _dartTypes.subst(
@@ -2025,7 +2029,9 @@ abstract class DartTypes {
if (env != null &&
s is FunctionTypeVariable &&
t is FunctionTypeVariable &&
env.isAssumed(s, t)) return true;
env.isAssumed(s, t)) {
return true;
}
if (s is AnyType) return true;
@@ -2221,8 +2227,9 @@ abstract class DartTypes {
!useLegacySubtyping && tRequiredNamed.contains(tName);
if (sIsRequired && !tIsRequired) return false;
if (!_isSubtype(
tNamedTypes[tIndex], sNamedTypes[sIndex - 1], env))
tNamedTypes[tIndex], sNamedTypes[sIndex - 1], env)) {
return false;
}
break;
}
}
@@ -2261,7 +2268,9 @@ abstract class DartTypes {
break;
case Variance.invariant:
if (!_isSubtype(sArgs[i], tArgs[i], env) ||
!_isSubtype(tArgs[i], sArgs[i], env)) return false;
!_isSubtype(tArgs[i], sArgs[i], env)) {
return false;
}
break;
}
}
+1 -1
View File
@@ -1350,7 +1350,7 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
/// Returns `true` for constructors of typed arrays.
bool _isConstructorOfTypedArraySubclass(ConstructorEntity constructor) {
ClassEntity cls = constructor.enclosingClass;
return cls.library.canonicalUri == Uris.dart__native_typed_data &&
return cls.library.canonicalUri == Uris.dartNativeTypedData &&
_closedWorld.nativeData.isNativeClass(cls) &&
_closedWorld.classHierarchy
.isSubtypeOf(cls, _closedWorld.commonElements.typedDataClass) &&
+2 -2
View File
@@ -8,5 +8,5 @@ library compiler.src.inferrer.debug;
const bool VERBOSE = false;
const bool PRINT_SUMMARY = false;
const bool ANOMALY_WARN = false;
bool PRINT_GRAPH = false;
bool PRINT_GRAPH_ALL_NODES = false; // Include useless nodes?
bool printGraph = false;
bool printGraphAllNodes = false; // Include useless nodes?
+2 -3
View File
@@ -133,7 +133,7 @@ class InferrerEngine {
memberHierarchyBuilder = MemberHierarchyBuilder(closedWorld),
// Ensure `_MAX_CHANGE_COUNT` conforms to TypeInformation flag encoding.
assert(_MAX_CHANGE_COUNT.bitLength <
64 - TypeInformation.NUM_TYPE_INFO_FLAGS);
64 - TypeInformation.numTypeInfoFlags);
/// Applies [f] to all elements in the universe that match [selector] and
/// [mask]. If [f] returns false, aborts the iteration.
@@ -340,8 +340,7 @@ class InferrerEngine {
_initMemberHierarchy();
metrics.analyze.measure(_analyzeAllElements);
final dump =
debug.PRINT_GRAPH ? TypeGraphDump(_compilerOutput, this) : null;
final dump = debug.printGraph ? TypeGraphDump(_compilerOutput, this) : null;
dump?.beforeAnalysis();
_buildWorkQueue();
@@ -161,7 +161,7 @@ abstract class TracerVisitor implements TypeInformationVisitor<void> {
// Collect the [TypeInformation] where the list can flow in,
// as well as the operations done on all these [TypeInformation]s.
addNewEscapeInformation(tracedType);
while (!workList.isEmpty) {
while (workList.isNotEmpty) {
final user = currentUser = workList.removeLast();
if (_wouldBeTooManyUsers(user.users)) {
bailout('Too many users');
@@ -171,16 +171,16 @@ abstract class TracerVisitor implements TypeInformationVisitor<void> {
analyzedElements.add(info.owner);
info.accept(this);
}
while (!listsToAnalyze.isEmpty) {
while (listsToAnalyze.isNotEmpty) {
analyzeStoredIntoList(listsToAnalyze.removeLast());
}
while (setsToAnalyze.isNotEmpty) {
analyzeStoredIntoSet(setsToAnalyze.removeLast());
}
while (!mapsToAnalyze.isEmpty) {
while (mapsToAnalyze.isNotEmpty) {
analyzeStoredIntoMap(mapsToAnalyze.removeLast());
}
while (!recordsToAnalyze.isEmpty) {
while (recordsToAnalyze.isNotEmpty) {
analyzeStoredIntoRecord(recordsToAnalyze.removeLast());
}
if (!continueAnalyzing) break;
@@ -307,8 +307,9 @@ class PowersetBitsDomain {
AbstractBool isExact(int value) => AbstractBool.Maybe;
AbstractBool isEmpty(int value) {
if (value & interceptorDomainMask == powersetBottom)
if (value & interceptorDomainMask == powersetBottom) {
return AbstractBool.True;
}
if (value & boolNullOtherMask == powersetBottom) return AbstractBool.True;
if (isPrecise(value)) return AbstractBool.False;
return AbstractBool.Maybe;
@@ -46,7 +46,7 @@ class TypeGraphDump {
void beforeAnalysis() {
for (TypeInformation node in inferrer.types.allTypes) {
Set<TypeInformation> copy = node.inputs.toSet();
if (!copy.isEmpty) {
if (copy.isNotEmpty) {
assignmentsBeforeAnalysis[node] = copy;
}
}
@@ -56,7 +56,7 @@ class TypeGraphDump {
void beforeTracing() {
for (TypeInformation node in inferrer.types.allTypes) {
Set<TypeInformation> copy = node.inputs.toSet();
if (!copy.isEmpty) {
if (copy.isNotEmpty) {
assignmentsBeforeTracing[node] = copy;
}
}
@@ -310,7 +310,7 @@ class _GraphGenerator extends TypeInformationVisitor<void> {
}
}
}
if (PRINT_GRAPH_ALL_NODES) {
if (printGraphAllNodes) {
for (TypeInformation user in node.users) {
if (!isExternal(user)) {
visit(user);
@@ -322,7 +322,7 @@ class _GraphGenerator extends TypeInformationVisitor<void> {
@override
void visitNarrowTypeInformation(NarrowTypeInformation info) {
// Omit unused Narrows.
if (!PRINT_GRAPH_ALL_NODES && info.users.isEmpty) return;
if (!printGraphAllNodes && info.users.isEmpty) return;
addNode(info, 'Narrow\n${formatType(info.typeAnnotation)}',
color: narrowColor);
}
@@ -330,7 +330,7 @@ class _GraphGenerator extends TypeInformationVisitor<void> {
@override
void visitPhiElementTypeInformation(PhiElementTypeInformation info) {
// Omit unused Phis.
if (!PRINT_GRAPH_ALL_NODES && info.users.isEmpty) return;
if (!printGraphAllNodes && info.users.isEmpty) return;
addNode(info, 'Phi ${info.variable?.name ?? ''}', color: phiColor);
}
@@ -97,7 +97,7 @@ enum _Flag {
/// changes.
abstract class TypeInformation {
// This will be treated as effectively constant by the VM.
static final int NUM_TYPE_INFO_FLAGS = _Flag.values.length;
static final int numTypeInfoFlags = _Flag.values.length;
Set<TypeInformation> users;
ParameterInputs _inputs;
@@ -117,9 +117,9 @@ abstract class TypeInformation {
/// We abandon inference in certain cases (complex cyclic flow, native
/// behaviours, etc.). In some case, we might resume inference in the
/// closure tracer, which is handled by checking whether [inputs] has
/// been set to [STOP_TRACKING_INPUTS_MARKER].
/// been set to [stopTrackingInputsMarker].
bool get abandonInferencing => _flags.contains(_Flag.abandonInferencing);
bool get mightResume => !identical(inputs, STOP_TRACKING_INPUTS_MARKER);
bool get mightResume => !identical(inputs, stopTrackingInputsMarker);
/// Whether this [TypeInformation] is currently in the inferrer's
/// work queue.
@@ -160,13 +160,13 @@ abstract class TypeInformation {
EnumSet<_Flag> _flags = EnumSet.empty();
/// Number of times this [TypeInformation] has changed type.
int get refineCount => _flags.mask.bits >> NUM_TYPE_INFO_FLAGS;
int get refineCount => _flags.mask.bits >> numTypeInfoFlags;
void incrementRefineCount() => _flags =
EnumSet.fromRawBits(_flags.mask.bits + (1 << NUM_TYPE_INFO_FLAGS));
void incrementRefineCount() =>
_flags = EnumSet.fromRawBits(_flags.mask.bits + (1 << numTypeInfoFlags));
void clearRefineCount() => _flags =
EnumSet.fromRawBits(_flags.mask.bits & ((1 << NUM_TYPE_INFO_FLAGS) - 1));
EnumSet.fromRawBits(_flags.mask.bits & ((1 << numTypeInfoFlags) - 1));
void addUser(TypeInformation user) {
assert(!user.isConcrete);
@@ -184,11 +184,10 @@ abstract class TypeInformation {
// The below is not a compile time constant to make it differentiable
// from other empty lists of [TypeInformation].
static final STOP_TRACKING_INPUTS_MARKER =
_BasicParameterInputs(List.empty());
static final stopTrackingInputsMarker = _BasicParameterInputs(List.empty());
bool areInputsTracked() {
return inputs != STOP_TRACKING_INPUTS_MARKER;
return inputs != stopTrackingInputsMarker;
}
void addInput(TypeInformation input) {
@@ -232,13 +231,13 @@ abstract class TypeInformation {
// Do not remove [this] as a user of nodes in [inputs],
// because our tracing analysis could be interested in tracing
// this node.
if (clearInputs) _inputs = STOP_TRACKING_INPUTS_MARKER;
if (clearInputs) _inputs = stopTrackingInputsMarker;
// Do not remove users because our tracing analysis could be
// interested in tracing the users of this node.
}
void clear() {
_inputs = STOP_TRACKING_INPUTS_MARKER;
_inputs = stopTrackingInputsMarker;
users = const {};
}
@@ -274,7 +273,7 @@ abstract class TypeInformation {
removeAndClearReferences(inferrer);
// Do not remove users because the tracing analysis could be interested
// in tracing the users of this node.
_inputs = STOP_TRACKING_INPUTS_MARKER;
_inputs = stopTrackingInputsMarker;
_flags = _flags.add(_Flag.abandonInferencing);
_flags = _flags.add(_Flag.isStable);
}
@@ -742,11 +741,6 @@ class FactoryConstructorTypeInformation extends MemberTypeInformation {
AbstractValue mask, InferrerEngine inferrer) {
return _narrowType(inferrer.abstractValueDomain, mask, _type);
}
@override
bool hasStableType(InferrerEngine inferrer) {
return super.hasStableType(inferrer);
}
}
class GenerativeConstructorTypeInformation extends MemberTypeInformation {
@@ -1258,7 +1252,7 @@ class DynamicCallSiteTypeInformation<T extends ir.Node>
}
if (!selector.isCall && !selector.isOperator) return null;
final args = arguments!;
if (!args.named.isEmpty) return null;
if (args.named.isNotEmpty) return null;
if (args.positional.length > 1) return null;
bool isInt(TypeInformation info) =>
@@ -1489,7 +1483,7 @@ class DynamicCallSiteTypeInformation<T extends ir.Node>
String toString() => 'Call site $debugName on ${receiver.type} $type';
@override
T accept<T>(TypeInformationVisitor<T> visitor) {
S accept<S>(TypeInformationVisitor<S> visitor) {
return visitor.visitDynamicCallSiteTypeInformation(this);
}
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// A [TypeMask] for a specific allocation site of a container (currently only
/// List) that will get specialized once the [TypeGraphInferrer] phase finds an
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// A [DictionaryTypeMask] is a [TypeMask] for a specific allocation
/// site of a map (currently only internal Map class) that is used as
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
enum FlatTypeMaskKind { empty, exact, subclass, subtype }
@@ -293,8 +293,9 @@ class FlatTypeMask extends TypeMask {
// TODO(herhut): Add check whether flatOther.base is superclass of
// all subclasses of this.base.
if (flatOther.isSubclass) {
if (isSubtype)
if (isSubtype) {
return (otherBase == closedWorld.commonElements.objectClass);
}
return closedWorld.classHierarchy.isSubclassOf(base!, otherBase!);
}
assert(flatOther.isSubtype);
@@ -718,8 +719,9 @@ class FlatTypeMask extends TypeMask {
MemberEntity? locateSingleMember(Selector selector, CommonMasks domain) {
if (isEmptyOrSpecial) return null;
JClosedWorld closedWorld = domain._closedWorld;
if (closedWorld.includesClosureCallInDomain(selector, this, domain))
if (closedWorld.includesClosureCallInDomain(selector, this, domain)) {
return null;
}
Iterable<MemberEntity> targets =
closedWorld.locateMembersInDomain(selector, this, domain);
if (targets.length != 1) return null;
@@ -742,8 +744,9 @@ class FlatTypeMask extends TypeMask {
if (closedWorld.classHierarchy.isSubclassOf(thisBase, enclosing)) {
return result;
}
if (closedWorld.isSubclassOfMixinUseOf(thisBase, enclosing))
if (closedWorld.isSubclassOfMixinUseOf(thisBase, enclosing)) {
return result;
}
}
return null;
}
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// A type mask that wraps another one, and delegates all its
/// implementation methods to it.
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// A [MapTypeMask] is a [TypeMask] for a specific allocation
/// site of a map (currently only internal Map class) that will get specialized
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// A [TypeMask] representing the type of a record or the union of multiple
/// records with the same shape.
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// A [SetTypeMask] is a [TypeMask] for a specific allocation site of a set
/// (currently only the internal Set class) that will get specialized once the
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
/// An implementation of a [UniverseSelectorConstraints] that is consists if an
/// only increasing set of [TypeMask]s, that is, once a mask is added it cannot
@@ -395,13 +395,6 @@ abstract class TypeMask implements AbstractValue {
bool containsOnlyString(JClosedWorld closedWorld);
bool containsOnly(ClassEntity cls);
/// Compares two [TypeMask] objects for structural equality.
///
/// Note: This may differ from semantic equality in the set containment sense.
/// Use [containsMask] and [isInMask] for that, instead.
@override
bool operator ==(other);
/// If this returns `true`, [other] is guaranteed to be a supertype of this
/// mask, i.e., this mask is in [other]. However, the inverse does not hold.
/// Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
class UnionTypeMask extends TypeMask {
/// Tag used for identifying serialized [UnionTypeMask] objects in a
@@ -74,17 +74,19 @@ class UnionTypeMask extends TypeMask {
bool isNullable = masks.any((TypeMask mask) => mask.isNullable);
bool hasLateSentinel = masks.any((TypeMask mask) => mask.hasLateSentinel);
unionOfHelper(masks, disjoint, domain);
if (disjoint.isEmpty)
if (disjoint.isEmpty) {
return isNullable
? TypeMask.empty(hasLateSentinel: hasLateSentinel)
: TypeMask.nonNullEmpty(hasLateSentinel: hasLateSentinel);
}
if (disjoint.length > MAX_UNION_LENGTH) {
return flatten(disjoint, domain,
includeNull: isNullable, includeLateSentinel: hasLateSentinel);
}
if (disjoint.length == 1)
if (disjoint.length == 1) {
return disjoint.single.withSpecialValues(
isNullable: isNullable, hasLateSentinel: hasLateSentinel);
}
UnionTypeMask union = UnionTypeMask._compose(
disjoint,
isNullable: isNullable,
@@ -2,7 +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.
part of masks;
part of 'masks.dart';
class ValueTypeMask extends ForwardingTypeMask {
/// Tag used for identifying serialized [ValueTypeMask] objects in a
+2 -2
View File
@@ -312,11 +312,11 @@ class WrappedAbstractValueDomain with AbstractValueDomain {
@override
AbstractValue unionOfMany(covariant Iterable<AbstractValue> values) {
List<AbstractValue> unwrapped_Values = values
List<AbstractValue> unwrappedValues = values
.map((element) => (element as WrappedAbstractValue)._abstractValue)
.toList();
return WrappedAbstractValue(
_abstractValueDomain.unionOfMany(unwrapped_Values));
_abstractValueDomain.unionOfMany(unwrappedValues));
}
@override
+2 -2
View File
@@ -115,14 +115,14 @@ class _SourceLocationsImpl implements SourceLocations {
assert(name == other.name);
if (_closed) throw UnsupportedError('SourceLocations already closed.');
int length = codeOutput.length;
if (other.markers.length > 0) {
if (other.markers.isNotEmpty) {
other.markers
.forEach((int targetOffset, List<SourceLocation> sourceLocations) {
(markers[length + targetOffset] ??= []).addAll(sourceLocations);
});
}
if (other.frameMarkers.length > 0) {
if (other.frameMarkers.isNotEmpty) {
other.frameMarkers.forEach((int targetOffset, List<FrameEntry> frames) {
(frameMarkers[length + targetOffset] ??= []).addAll(frames);
});
@@ -145,7 +145,7 @@ class SourceInformationBuilder {
null;
/// Generate [SourceInformation] for the generic [node].
@deprecated
@Deprecated("Use SourceInformationFactory")
SourceInformation? buildGeneric(ir.Node node) => null;
/// Generate [SourceInformation] for an instantiation of a class using [node]
+17 -14
View File
@@ -237,7 +237,7 @@ String? _getNativeClassName(ir.Constant constant) {
// TODO(johnniwinther): Add an IrCommonElements for these queries; i.e.
// `commonElements.isNativeAnnotationClass(constant.classNode)`.
if (constant.classNode.name == 'Native' &&
constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
constant.classNode.enclosingLibrary.importUri == Uris.dartJSHelper) {
if (constant.fieldValues.length == 1) {
ir.Constant fieldValue = constant.fieldValues.values.single;
String? name;
@@ -256,13 +256,13 @@ String? _getNativeClassName(ir.Constant constant) {
bool _isNativeMember(ir.Constant constant) {
return constant is ir.InstanceConstant &&
constant.classNode.name == 'ExternalName' &&
constant.classNode.enclosingLibrary.importUri == Uris.dart__internal;
constant.classNode.enclosingLibrary.importUri == Uris.dartInternal;
}
String? _getNativeMemberName(ir.Constant constant) {
if (constant is ir.InstanceConstant &&
constant.classNode.name == 'JSName' &&
constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
constant.classNode.enclosingLibrary.importUri == Uris.dartJSHelper) {
assert(constant.fieldValues.length == 1);
ir.Constant fieldValue = constant.fieldValues.values.single;
if (fieldValue is ir.StringConstant) {
@@ -275,7 +275,7 @@ String? _getNativeMemberName(ir.Constant constant) {
String? _getCreatesAnnotation(ir.Constant constant) {
if (constant is ir.InstanceConstant &&
constant.classNode.name == 'Creates' &&
constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
constant.classNode.enclosingLibrary.importUri == Uris.dartJSHelper) {
assert(constant.fieldValues.length == 1);
ir.Constant fieldValue = constant.fieldValues.values.single;
if (fieldValue is ir.StringConstant) {
@@ -288,7 +288,7 @@ String? _getCreatesAnnotation(ir.Constant constant) {
String? _getReturnsAnnotation(ir.Constant constant) {
if (constant is ir.InstanceConstant &&
constant.classNode.name == 'Returns' &&
constant.classNode.enclosingLibrary.importUri == Uris.dart__js_helper) {
constant.classNode.enclosingLibrary.importUri == Uris.dartJSHelper) {
assert(constant.fieldValues.length == 1);
ir.Constant fieldValue = constant.fieldValues.values.single;
if (fieldValue is ir.StringConstant) {
@@ -301,11 +301,11 @@ String? _getReturnsAnnotation(ir.Constant constant) {
String? _getJsInteropName(ir.Constant constant) {
if (constant is ir.InstanceConstant &&
constant.classNode.name == 'JS' &&
(constant.classNode.enclosingLibrary.importUri == Uris.package_js ||
(constant.classNode.enclosingLibrary.importUri == Uris.packageJS ||
constant.classNode.enclosingLibrary.importUri ==
Uris.dart__js_annotations ||
Uris.dartJSAnnotations ||
constant.classNode.enclosingLibrary.importUri ==
Uris.dart__js_interop)) {
Uris.dartJSInterop)) {
assert(constant.fieldValues.length == 1);
ir.Constant fieldValue = constant.fieldValues.values.single;
if (fieldValue is ir.NullConstant) {
@@ -320,17 +320,17 @@ String? _getJsInteropName(ir.Constant constant) {
bool _isAnonymousJsInterop(ir.Constant constant) {
return constant is ir.InstanceConstant &&
constant.classNode.name == '_Anonymous' &&
(constant.classNode.enclosingLibrary.importUri == Uris.package_js ||
(constant.classNode.enclosingLibrary.importUri == Uris.packageJS ||
constant.classNode.enclosingLibrary.importUri ==
Uris.dart__js_annotations);
Uris.dartJSAnnotations);
}
bool _isStaticInterop(ir.Constant constant) {
return constant is ir.InstanceConstant &&
constant.classNode.name == '_StaticInterop' &&
(constant.classNode.enclosingLibrary.importUri == Uris.package_js ||
(constant.classNode.enclosingLibrary.importUri == Uris.packageJS ||
constant.classNode.enclosingLibrary.importUri ==
Uris.dart__js_annotations);
Uris.dartJSAnnotations);
}
class PragmaAnnotationData {
@@ -347,6 +347,9 @@ class PragmaAnnotationData {
@override
String toString() => 'PragmaAnnotationData($name)';
@override
int get hashCode => Object.hash(suffix, options);
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
@@ -360,13 +363,13 @@ PragmaAnnotationData? _getPragmaAnnotation(ir.Constant constant) {
ir.InstanceConstant value = constant;
ir.Class cls = value.classNode;
Uri uri = cls.enclosingLibrary.importUri;
if (uri == Uris.package_meta_dart2js) {
if (uri == Uris.packageMetaDart2js) {
if (cls.name == '_NoInline') {
return const PragmaAnnotationData('noInline');
} else if (cls.name == '_TryInline') {
return const PragmaAnnotationData('tryInline');
}
} else if (uri == Uris.dart_core && cls.name == 'pragma') {
} else if (uri == Uris.dartCore && cls.name == 'pragma') {
ir.Constant? nameValue;
ir.Constant? optionsValue;
value.fieldValues.forEach((ir.Reference reference, ir.Constant fieldValue) {
+2 -2
View File
@@ -115,8 +115,8 @@ class KernelCapturedScope extends KernelScopeInfo {
_empty,
null,
_empty,
Set.of(scope.freeVariables.where(
(ir.Node variable) => variable is TypeVariableTypeWithContext)),
Set.of(
scope.freeVariables.whereType<TypeVariableTypeWithContext>()),
scope.freeVariablesForRti,
scope.thisUsedAsFreeVariable,
scope.thisUsedAsFreeVariableIfNeedsRti,
+1 -1
View File
@@ -515,7 +515,7 @@ class ImpactBuilder extends ir.RecursiveVisitor implements ImpactRegistry {
// additional unnecessary work.
final name = node.target.name.text;
if (node.target.enclosingClass == null &&
node.target.enclosingLibrary.importUri == Uris.dart__foreign_helper &&
node.target.enclosingLibrary.importUri == Uris.dartForeignHelper &&
getForeignKindFromName(name) != ForeignKind.NONE) {
registerForeignStaticInvocationNode(node);
}
+1 -1
View File
@@ -196,7 +196,7 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
}
}
}
if (!capturedVariablesForScope.isEmpty) {
if (capturedVariablesForScope.isNotEmpty) {
assert(_model.scopeInfo != null);
KernelScopeInfo from = _model.scopeInfo!;
@@ -437,12 +437,16 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
/// temporary.
///
/// We cannot rewrite `<receiver>.m()` to:
///
/// temp = <receiver>.m;
/// temp();
///
/// Because this leaves `this` unbound in the call. But because of dart
/// evaluation order we can write:
///
/// temp = <receiver>;
/// temp.m();
///
js.Expression withCallTargetExpression(
js.Expression node, js.Expression fn(js.Expression result),
{required bool store}) {
+4 -4
View File
@@ -86,7 +86,7 @@ class SizeEstimator implements NodeVisitor<void> {
}
void out(String s) {
if (s.length > 0) {
if (s.isNotEmpty) {
// We can elide a semicolon in some cases, but for simplicity we
// assume a semicolon is needed here.
if (pendingSemicolon) {
@@ -357,7 +357,7 @@ class SizeEstimator implements NodeVisitor<void> {
visitNestedExpression(node.expression, Precedence.expression,
newInForInit: false, newAtStatementBegin: false);
out(':'); // ':'
if (!node.body.statements.isEmpty) {
if (node.body.statements.isNotEmpty) {
blockOutWithoutBraces(node.body);
}
}
@@ -365,7 +365,7 @@ class SizeEstimator implements NodeVisitor<void> {
@override
void visitDefault(Default node) {
out('default:'); // 'default:'
if (!node.body.statements.isEmpty) {
if (node.body.statements.isNotEmpty) {
blockOutWithoutBraces(node.body);
}
}
@@ -734,7 +734,7 @@ class SizeEstimator implements NodeVisitor<void> {
}
bool isValidJavaScriptId(String field) {
if (field.length == 0) return false;
if (field.isEmpty) return false;
// Ignore the leading and trailing string-delimiter.
for (int i = 0; i < field.length; i++) {
// TODO(floitsch): allow more characters.
@@ -223,7 +223,7 @@ class ModularConstantEmitter
class ConstantEmitter extends ModularConstantEmitter {
// Matches blank lines, comment lines and trailing comments that can't be part
// of a string.
static final RegExp COMMENT_RE =
static final RegExp commentRE =
RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''', multiLine: true);
final JCommonElements _commonElements;
@@ -488,7 +488,7 @@ class ConstantEmitter extends ModularConstantEmitter {
}
String stripComments(String rawJavaScript) {
return rawJavaScript.replaceAll(COMMENT_RE, '');
return rawJavaScript.replaceAll(commentRE, '');
}
jsAst.Expression maybeAddListTypeArgumentsNewRti(
@@ -2,7 +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.
part of js_backend.namer;
part of 'namer.dart';
mixin _MinifiedFieldNamer implements Namer {
_FieldNamingRegistry get fieldRegistry;
@@ -139,7 +139,9 @@ class _Pool {
List<_Pool> pools = [];
for (var name in names) {
int length = name.length;
while (pools.length < length) pools.add(_Pool());
while (pools.length < length) {
pools.add(_Pool());
}
_Pool pool = pools[length - 1];
pool._availableSlots[pool._names.length] = true;
pool._names.add(name);
@@ -183,7 +185,9 @@ class _Cohort {
_Cohort? skipEmpty() {
_Cohort? cohort = this;
while (cohort != null && cohort.remaining == 0) cohort = cohort.next;
while (cohort != null && cohort.remaining == 0) {
cohort = cohort.next;
}
return cohort;
}
@@ -2,7 +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.
part of js_backend.namer;
part of 'namer.dart';
class FrequencyBasedNamer extends Namer
with _MinifiedFieldNamer, _MinifiedOneShotInterceptorNamer
@@ -2,7 +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.
part of js_backend.namer;
part of 'namer.dart';
/// Assigns JavaScript identifiers to Dart variables, class-names and members.
class MinifyNamer extends Namer
@@ -20,8 +20,8 @@ class MinifyNamer extends Namer
@override
String get genericInstantiationPrefix => r'$I';
final ALPHABET_CHARACTERS = 52; // a-zA-Z.
final ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9.
static const ALPHABET_CHARACTERS = 52; // a-zA-Z.
static const ALPHANUMERIC_CHARACTERS = 62; // a-zA-Z0-9.
/// You can pass an invalid identifier to this and unlike its non-minifying
/// counterpart it will never return the proposedName as the new fresh name.
+12 -12
View File
@@ -17,7 +17,7 @@ import '../common/names.dart' show Identifiers, Names, Selectors;
import '../constants/constant_system.dart' as constant_system;
import '../constants/values.dart';
import '../common/elements.dart' show CommonElements, ElementEnvironment;
import '../diagnostics/invariant.dart' show DEBUG_MODE;
import '../diagnostics/invariant.dart' show debugMode;
import '../elements/entities.dart';
import '../elements/entity_utils.dart' as utils;
import '../elements/jumps.dart';
@@ -97,7 +97,7 @@ part 'namer_names.dart';
/// JavaScript property such as `__proto__`.
///
/// The following annotated names are generated for instance members, where
/// <NAME> denotes the disambiguated name.
/// `<NAME>` denotes the disambiguated name.
///
/// 0. The disambiguated name can itself be seen as an annotated name.
///
@@ -670,7 +670,7 @@ class Namer extends ModularNamer {
jsAst.Name? newName = userInstanceMembers[key];
if (newName == null) {
String proposedName = privateName(originalName);
if (!suffixes.isEmpty) {
if (suffixes.isNotEmpty) {
// In the proposed name, separate the name parts by '$', because the
// proposed name must be a valid identifier, but not necessarily unique.
proposedName += r'$' + suffixes.join(r'$');
@@ -906,15 +906,15 @@ class Namer extends ModularNamer {
}
// The filename based name can contain all kinds of nasty characters. Make
// sure it is an identifier.
if (!IDENTIFIER.hasMatch(name)) {
if (!identifier.hasMatch(name)) {
String replacer(Match match) {
String s = match[0]!;
if (s == '.') return '_';
return s.codeUnitAt(0).toRadixString(16);
}
name = name.replaceAllMapped(NON_IDENTIFIER_CHAR, replacer);
if (!IDENTIFIER.hasMatch(name)) {
name = name.replaceAllMapped(nonIdentifierChar, replacer);
if (!identifier.hasMatch(name)) {
// e.g. starts with digit.
name = 'lib_$name';
}
@@ -1206,7 +1206,7 @@ class ConstantNamingVisitor implements ConstantValueVisitor<void, Null> {
}
void add(String fragment) {
assert(fragment.length > 0);
assert(fragment.isNotEmpty);
fragments.add(fragment);
length += fragment.length;
if (fragments.length > MAX_FRAGMENTS) failed = true;
@@ -1216,7 +1216,7 @@ class ConstantNamingVisitor implements ConstantValueVisitor<void, Null> {
}
void addIdentifier(String fragment) {
if (fragment.length <= MAX_EXTRA_LENGTH && IDENTIFIER.hasMatch(fragment)) {
if (fragment.length <= MAX_EXTRA_LENGTH && identifier.hasMatch(fragment)) {
add(fragment);
} else {
failed = true;
@@ -2157,8 +2157,8 @@ String suffixForGetInterceptor(CommonElements commonElements,
///
/// $<T>$<N>$namedParam1...$namedParam<M>
///
/// Where <T> is the number of type arguments, <N> is the number of positional
/// arguments and <M> is the number of named arguments.
/// Where `<T>` is the number of type arguments, `<N>` is the number of
/// positional arguments and `<M>` is the number of named arguments.
///
/// If there are no type arguments the `$<T>` is omitted.
///
@@ -2602,8 +2602,8 @@ final Set<String> jsReserved = {
...reservedPropertySymbols
};
final RegExp IDENTIFIER = RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$');
final RegExp NON_IDENTIFIER_CHAR = RegExp(r'[^A-Za-z_0-9$]');
final RegExp identifier = RegExp(r'^[A-Za-z_$][A-Za-z0-9_$]*$');
final RegExp nonIdentifierChar = RegExp(r'[^A-Za-z_0-9$]');
const MAX_FRAGMENTS = 5;
const MAX_EXTRA_LENGTH = 30;
const DEFAULT_TAG_LENGTH = 3;
@@ -2,7 +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.
part of js_backend.namer;
part of 'namer.dart';
abstract class _NamerName extends jsAst.Name {
int get _kind;
@@ -20,7 +20,7 @@ abstract class _NamerName extends jsAst.Name {
@override
String toString() {
if (DEBUG_MODE) {
if (debugMode) {
return 'Name($key)';
}
throw UnsupportedError("Cannot convert a name to a string");
@@ -223,15 +223,13 @@ class TokenName extends _NamerName implements jsAst.ReferenceCountedAstNode {
void markSeen(jsAst.TokenCounter counter) => _rc++;
@override
// ignore: hash_and_equals
bool operator ==(Object other) {
if (other is _NameReference) return this == other._target;
if (identical(this, other)) return true;
return false;
}
@override
int get hashCode => super.hashCode;
void finalize() {
assert(
!isFinalized,
@@ -36,6 +36,9 @@ class TypeCheck {
TypeCheck(this.cls, this.substitution, {this.needsIs = true});
@override
bool operator ==(other) => identical(this, other);
@override
String toString() =>
'TypeCheck(cls=$cls,needsIs=$needsIs,substitution=$substitution)';
@@ -707,11 +707,13 @@ abstract class RuntimeTypesNeed {
///
/// This is for instance the case for generic classes used in a type test:
///
/// ```
/// class C<T> {}
/// main() {
/// C<int>() is C<int>;
/// C<String>() is C<String>;
/// }
/// ```
///
bool classNeedsTypeArguments(ClassEntity cls);
@@ -723,11 +725,13 @@ abstract class RuntimeTypesNeed {
///
/// This is for instance the case for generic methods that use type tests:
///
/// ```
/// method<T>(T t) => t is T;
/// main() {
/// method<int>(0);
/// method<String>('');
/// }
/// ```
///
bool methodNeedsTypeArguments(FunctionEntity method);
@@ -34,7 +34,7 @@ void _partition(
List<_Node> nodes, int minLength, List<String> path, int index) {
while (true) {
// Handle trivial partitions.
if (nodes.length == 0) return;
if (nodes.isEmpty) return;
if (nodes.length == 1 && path.length >= minLength) {
String name = path.join();
assert(name.isNotEmpty);
@@ -49,7 +49,7 @@ void _partition(
for (final node in nodes) {
String string = node.string;
assert(string.length > 0);
assert(string.isNotEmpty);
if (index < string.length) {
int codeUnit = string.codeUnitAt(index);
(partition[codeUnit] ??= []).add(node);
@@ -63,7 +63,7 @@ void _partition(
terminating.assignment = path.join();
}
if (partition.length == 0) return;
if (partition.isEmpty) return;
if (partition.length > 1) {
var keys = partition.keys.toList();
@@ -589,8 +589,8 @@ class _TypeReferenceCollectorVisitor extends js.BaseVisitorVoid {
/// interface types with the same name (i.e. from different libraries), or types
/// with names that contain underscores or dollar signs. There is also some
/// ambiguity in the generated names in the interest of keeping most names
/// short, e.g. "FutureOr_int_Function" could be "FutureOr<int> Function()" or
/// "FutureOr<int Function()>".
/// short, e.g. `"FutureOr_int_Function"` could be `"FutureOr<int> Function()"`
/// or `"FutureOr<int Function()>"`.
class _RecipeToIdentifier extends DartTypeVisitor<void, Null> {
final Map<DartType, int> _backrefs = Map.identity();
final List<String> _fragments = [];
@@ -188,7 +188,7 @@ class ClassStubGenerator {
'internalName': js.quoteName(internalName),
'type': js.number(type),
'arguments': jsAst.ArrayInitializer(
parameterNames.map<jsAst.Expression>(js).toList()),
parameterNames.map<jsAst.Expression>(js.call).toList()),
'namedArguments': jsAst.ArrayInitializer(argNames),
'typeArgumentCount': js.number(selector.typeArgumentCount)
});
@@ -146,8 +146,9 @@ class InstantiationStubGenerator {
late FieldEntity functionField;
_elementEnvironment.forEachInstanceField(instantiationClass,
(ClassEntity enclosing, FieldEntity field) {
if (_closedWorld.fieldAnalysis.getFieldData(field as JField).isElided)
if (_closedWorld.fieldAnalysis.getFieldData(field as JField).isElided) {
return;
}
if (field.name == '_genericClosure') functionField = field;
});
@@ -105,29 +105,29 @@ class InterceptorStubGenerator {
if (cls == _commonElements.jsArrayClass ||
cls == _commonElements.jsMutableArrayClass ||
cls == _commonElements.jsFixedArrayClass ||
cls == _commonElements.jsExtendableArrayClass)
cls == _commonElements.jsExtendableArrayClass) {
hasArray = true;
else if (cls == _commonElements.jsBoolClass)
} else if (cls == _commonElements.jsBoolClass) {
hasBool = true;
else if (cls == _commonElements.jsNumNotIntClass)
} else if (cls == _commonElements.jsNumNotIntClass) {
hasNumNotInt = true;
else if (cls == _commonElements.jsIntClass)
} else if (cls == _commonElements.jsIntClass) {
hasInt = true;
else if (cls == _commonElements.jsNullClass)
} else if (cls == _commonElements.jsNullClass) {
hasNull = true;
else if (cls == _commonElements.jsNumberClass)
} else if (cls == _commonElements.jsNumberClass) {
hasNumber = true;
else if (cls == _commonElements.jsStringClass)
} else if (cls == _commonElements.jsStringClass) {
hasString = true;
else if (cls == _commonElements.jsJavaScriptBigIntClass)
} else if (cls == _commonElements.jsJavaScriptBigIntClass) {
hasJavaScriptBigInt = true;
else if (cls == _commonElements.jsJavaScriptFunctionClass)
} else if (cls == _commonElements.jsJavaScriptFunctionClass) {
hasJavaScriptFunction = true;
else if (cls == _commonElements.jsJavaScriptSymbolClass)
} else if (cls == _commonElements.jsJavaScriptSymbolClass) {
hasJavaScriptSymbol = true;
else if (cls == _commonElements.jsJavaScriptObjectClass)
} else if (cls == _commonElements.jsJavaScriptObjectClass) {
hasJavaScriptObject = true;
else {
} else {
// The set of classes includes classes mixed-in to interceptor classes
// and user extensions of native classes.
//
@@ -2,7 +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.
part of dart2js.js_emitter.program_builder;
part of 'program_builder.dart';
/// Generates the code for all used classes in the program. Static fields (even
/// in classes) are ignored, since they can be treated as non-class elements.
@@ -2,7 +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.
part of dart2js.js_emitter.program_builder;
part of 'program_builder.dart';
/// [member] is an instance field.
///
@@ -442,7 +442,7 @@ class ProgramBuilder {
if (member.isGetter || member is FieldEntity || member.isFunction) {
final selectors =
_codegenWorld.getterInvocationsByName(member.name!);
if (selectors != null && !selectors.isEmpty) {
if (selectors != null && selectors.isNotEmpty) {
for (Selector selector in selectors) {
js.Name stubName = _namer.invocationName(selector);
if (stubNames.add(stubName.key)) {
@@ -462,7 +462,7 @@ class ProgramBuilder {
if (member.isSetter || (member is FieldEntity && !member.isConst)) {
final selectors =
_codegenWorld.setterInvocationsByName(member.name!);
if (selectors != null && !selectors.isEmpty) {
if (selectors != null && selectors.isNotEmpty) {
var stubName = _namer.setterForMember(member);
if (stubNames.add(stubName.key)) {
interceptorClass!.callStubs.add(_buildStubMethod(stubName,
@@ -498,7 +498,7 @@ class ProgramBuilder {
// Named arguments are not yet supported. In the future we
// may want to map named arguments to an object literal containing
// all named arguments.
if (selectors != null && !selectors.isEmpty) {
if (selectors != null && selectors.isNotEmpty) {
for (var selector in selectors.keys) {
// Check whether the arity matches this member.
var argumentCount = selector.argumentCount;
@@ -624,7 +624,7 @@ class ProgramBuilder {
if (member.isGetter || member is FieldEntity) {
Map<Selector, SelectorConstraints>? selectors =
_codegenWorld.invocationsByName(member.name!);
if (selectors != null && !selectors.isEmpty) {
if (selectors != null && selectors.isNotEmpty) {
Map<js.Name, js.Expression> callStubsForMember =
classStubGenerator.generateCallStubsForGetter(member, selectors);
callStubsForMember.forEach((js.Name name, js.Expression code) {
@@ -2,7 +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.
part of dart2js.js_emitter.program_builder;
part of 'program_builder.dart';
class LibraryContents {
final List<ClassEntity> classes = [];
@@ -2,7 +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.
part of dart2js.js_emitter.startup_emitter.model_emitter;
part of 'model_emitter.dart';
/// The fast startup emitter's goal is to minimize the amount of work that the
/// JavaScript engine has to do before it can start running user code.
@@ -646,14 +646,14 @@ class FragmentMerger {
///
/// Where
///
/// - <library uri> is the import uri of the library making a deferred
/// - library uri is the import uri of the library making a deferred
/// import.
/// - <library name> is the name of the library, or "<unnamed>" if it is
/// - library name is the name of the library, or `"<unnamed>"` if it is
/// unnamed.
/// - <prefix> is the `as` prefix used for a given deferred import.
/// - <loadId> is the unique ID assigned by the compiler for each
/// <library uri>/<prefix> pair.
/// - <list of files> is a list of the filenames the must be loaded when that
/// - prefix is the `as` prefix used for a given deferred import.
/// - loadId is the unique ID assigned by the compiler for each
/// library uri/prefix pair.
/// - list of files is a list of the filenames the must be loaded when that
/// import is loaded.
/// TODO(joshualitt): the library name is unused and should be removed. This
/// will be a breaking change.
@@ -847,12 +847,6 @@ class JsClosureClassInfo extends JsScopeInfo
}
}
@override
List<Local> getCreatedFieldEntities(KernelToLocalsMap localsMap) {
_ensureFieldToLocalsMap(localsMap);
return _fieldToLocalsMap!.values.toList();
}
@override
Local getLocalForField(KernelToLocalsMap localsMap, FieldEntity field) {
_ensureFieldToLocalsMap(localsMap);
@@ -1189,22 +1189,22 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
if (cachedMayLookupInMain!) {
type ??= findInLibrary(elementEnvironment.mainLibrary);
}
type ??= findIn(Uris.dart_core);
type ??= findIn(Uris.dart__js_helper);
type ??= findIn(Uris.dart__late_helper);
type ??= findIn(Uris.dart__interceptors);
type ??= findIn(Uris.dart__native_typed_data);
type ??= findIn(Uris.dart_collection);
type ??= findIn(Uris.dart_math);
type ??= findIn(Uris.dart_html);
type ??= findIn(Uris.dart_html_common);
type ??= findIn(Uris.dart_svg);
type ??= findIn(Uris.dart_web_audio);
type ??= findIn(Uris.dart_web_gl);
type ??= findIn(Uris.dart_indexed_db);
type ??= findIn(Uris.dart_typed_data);
type ??= findIn(Uris.dart__rti);
type ??= findIn(Uris.dart_mirrors);
type ??= findIn(Uris.dartCore);
type ??= findIn(Uris.dartJSHelper);
type ??= findIn(Uris.dartLateHelper);
type ??= findIn(Uris.dartInterceptors);
type ??= findIn(Uris.dartNativeTypedData);
type ??= findIn(Uris.dartCollection);
type ??= findIn(Uris.dartMath);
type ??= findIn(Uris.dartHtml);
type ??= findIn(Uris.dartHtmlCommon);
type ??= findIn(Uris.dartSvg);
type ??= findIn(Uris.dartWebAudio);
type ??= findIn(Uris.dartWebGL);
type ??= findIn(Uris.dartIndexedDB);
type ??= findIn(Uris.dartTypedData);
type ??= findIn(Uris.dartRti);
type ??= findIn(Uris.dartMirrors);
if (type == null && required) {
reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
MessageKind.GENERIC, {'text': "Type '$typeName' not found."});
@@ -1254,7 +1254,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
// TODO(johnniwinther): Cache this for later use.
@override
NativeBehavior getNativeBehaviorForJsBuiltinCall(ir.StaticInvocation node) {
if (node.arguments.positional.length < 1) {
if (node.arguments.positional.isEmpty) {
reporter.internalError(
CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type.");
}
@@ -1279,7 +1279,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
@override
NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
ir.StaticInvocation node) {
if (node.arguments.positional.length < 1) {
if (node.arguments.positional.isEmpty) {
reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
"JS embedded global expression has no type.");
}
+3 -3
View File
@@ -296,7 +296,7 @@ class JClosedWorld implements World {
/// Returns `true` if [cls] is mixed into a live class.
bool isUsedAsMixin(ClassEntity cls) {
return !mixinUsesOf(cls).isEmpty;
return mixinUsesOf(cls).isNotEmpty;
}
/// Returns `true` if any live class that mixes in [cls] implements [type].
@@ -390,7 +390,7 @@ class JClosedWorld implements World {
// Stop fast - we found a need for noSuchMethod handling.
return IterationStep.STOP;
}
}, ClassHierarchyNode.EXPLICITLY_INSTANTIATED, strict: true);
}, ClassHierarchyNode.explicitlyInstantiated, strict: true);
// We stopped fast so we need noSuchMethod handling.
return result == IterationStep.STOP;
}
@@ -439,7 +439,7 @@ class JClosedWorld implements World {
link = link.tail!) {
ClassEntity cls = link.head.element;
for (Link<OrderedTypeSet> link = otherTypeSets;
!link.isEmpty;
link.isNotEmpty;
link = link.tail!) {
if (link.head.asInstanceOf(
cls, elementMap.getHierarchyDepth(cls as JClass)) ==
@@ -111,7 +111,7 @@ class JClosedWorldBuilder {
.forEachSubclass((ClassEntity cls) {
convertClassSet(closedWorld.classHierarchy.getClassSet(cls));
return IterationStep.CONTINUE;
}, ClassHierarchyNode.ALL);
}, ClassHierarchyNode.all);
Set<MemberEntity> liveInstanceMembers =
map.toBackendMemberSet(closedWorld.liveInstanceMembers);
+4 -10
View File
@@ -151,11 +151,6 @@ abstract class TypeRecipe {
TypeRecipe();
@override
late final hashCode = _computeHashCode();
int _computeHashCode();
factory TypeRecipe.readFromDataSource(DataSourceReader source) {
TypeRecipe recipe;
source.begin(tag);
@@ -225,7 +220,7 @@ class TypeExpressionRecipe extends TypeRecipe {
}
@override
int _computeHashCode() => type.hashCode * 7;
late final int hashCode = type.hashCode * 7;
@override
bool operator ==(other) {
@@ -260,7 +255,7 @@ class SingletonTypeEnvironmentRecipe extends TypeEnvironmentRecipe {
}
@override
int _computeHashCode() => type.hashCode * 11;
late final int hashCode = type.hashCode * 11;
@override
bool operator ==(other) {
@@ -304,9 +299,8 @@ class FullTypeEnvironmentRecipe extends TypeEnvironmentRecipe {
}
@override
int _computeHashCode() {
return Hashing.listHash(types, Hashing.objectHash(classType, 0));
}
late final int hashCode =
Hashing.listHash(types, Hashing.objectHash(classType, 0));
@override
bool operator ==(other) {
@@ -209,7 +209,7 @@ class Dart2jsTarget extends Target {
arg.value)
..fileOffset = arg.fileOffset;
})), keyType: coreTypes.stringNonNullableRawType)
..isConst = (arguments.named.length == 0)
..isConst = (arguments.named.isEmpty)
..fileOffset = arguments.fileOffset,
ir.IntLiteral(kind.value)..fileOffset = offset,
]))
@@ -922,22 +922,22 @@ class KernelToElementMap implements IrToElementMap {
if (cachedMayLookupInMain!) {
type ??= findInLibrary(elementEnvironment.mainLibrary);
}
type ??= findIn(Uris.dart_core);
type ??= findIn(Uris.dart__js_helper);
type ??= findIn(Uris.dart__late_helper);
type ??= findIn(Uris.dart__interceptors);
type ??= findIn(Uris.dart__native_typed_data);
type ??= findIn(Uris.dart_collection);
type ??= findIn(Uris.dart_math);
type ??= findIn(Uris.dart_html);
type ??= findIn(Uris.dart_html_common);
type ??= findIn(Uris.dart_svg);
type ??= findIn(Uris.dart_web_audio);
type ??= findIn(Uris.dart_web_gl);
type ??= findIn(Uris.dart_indexed_db);
type ??= findIn(Uris.dart_typed_data);
type ??= findIn(Uris.dart__rti);
type ??= findIn(Uris.dart_mirrors);
type ??= findIn(Uris.dartCore);
type ??= findIn(Uris.dartJSHelper);
type ??= findIn(Uris.dartLateHelper);
type ??= findIn(Uris.dartInterceptors);
type ??= findIn(Uris.dartNativeTypedData);
type ??= findIn(Uris.dartCollection);
type ??= findIn(Uris.dartMath);
type ??= findIn(Uris.dartHtml);
type ??= findIn(Uris.dartHtmlCommon);
type ??= findIn(Uris.dartSvg);
type ??= findIn(Uris.dartWebAudio);
type ??= findIn(Uris.dartWebGL);
type ??= findIn(Uris.dartIndexedDB);
type ??= findIn(Uris.dartTypedData);
type ??= findIn(Uris.dartRti);
type ??= findIn(Uris.dartMirrors);
if (type == null && required!) {
reporter.reportErrorMessage(CURRENT_ELEMENT_SPANNABLE,
MessageKind.GENERIC, {'text': "Type '$typeName' not found."});
@@ -988,7 +988,7 @@ class KernelToElementMap implements IrToElementMap {
/// Computes the [NativeBehavior] for a call to the [JS_BUILTIN]
/// function.
NativeBehavior getNativeBehaviorForJsBuiltinCall(ir.StaticInvocation node) {
if (node.arguments.positional.length < 1) {
if (node.arguments.positional.isEmpty) {
reporter.internalError(
CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type.");
}
@@ -1014,7 +1014,7 @@ class KernelToElementMap implements IrToElementMap {
/// TODO(johnniwinther): Cache this for later use.
NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall(
ir.StaticInvocation node) {
if (node.arguments.positional.length < 1) {
if (node.arguments.positional.isEmpty) {
reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
"JS embedded global expression has no type.");
}
@@ -179,7 +179,7 @@ class ListFactorySpecializer extends BaseSpecializer {
/// Returns constant value of the first argument in [args], or null if it is
/// not a constant.
int? _getLengthArgument(Arguments args) {
if (args.positional.length < 1) return null;
if (args.positional.isEmpty) return null;
final value = args.positional.first;
if (value is IntLiteral) {
return value.value;
+9 -5
View File
@@ -29,6 +29,10 @@ class SpecialType {
/// The type Object, but no subtypes:
static const JsObject = SpecialType._('=Object');
@override
bool operator ==(other) =>
identical(this, other) || other is SpecialType && name == other.name;
@override
int get hashCode => name.hashCode;
@@ -99,11 +103,11 @@ class NativeBehavior {
// TODO(sra): Make NativeBehavior immutable so PURE and PURE_ALLOCATION can be
// final constant-like objects.
static NativeBehavior get PURE => NativeBehavior._makePure();
static NativeBehavior get PURE_ALLOCATION =>
static NativeBehavior get pure => NativeBehavior._makePure();
static NativeBehavior get pureAllocation =>
NativeBehavior._makePure(isAllocation: true);
static NativeBehavior get CHANGES_OTHER => NativeBehavior._makeChangesOther();
static NativeBehavior get DEPENDS_OTHER => NativeBehavior._makeDependsOther();
static NativeBehavior get changesOther => NativeBehavior._makeChangesOther();
static NativeBehavior get dependsOther => NativeBehavior._makeDependsOther();
NativeBehavior() : sideEffects = SideEffects.empty();
@@ -229,7 +233,7 @@ class NativeBehavior {
/// The types Ti are non-nullable, so add class `Null` to specify a
/// nullable type, e.g `'String|Null'`.
///
/// 2) A sequence of <tag>:<value> pairs of the following kinds
/// 2) A sequence of `<tag>:<value>` pairs of the following kinds
///
/// <type-tag>:<type-string>
/// <effect-tag>:<effect-string>
+1 -1
View File
@@ -20,7 +20,7 @@ abstract class NativeEnqueuer {
final Set<ClassEntity> _unusedClasses = {};
/// Returns whether native classes are being used.
bool get hasInstantiatedNativeClasses => !_registeredClasses.isEmpty;
bool get hasInstantiatedNativeClasses => _registeredClasses.isNotEmpty;
/// Log message reported if all native types are used.
String? _allUsedMessage;
+2 -1
View File
@@ -292,8 +292,9 @@ class ThrowBehaviorVisitor extends js.BaseVisitor<NativeThrowBehavior> {
@override
NativeThrowBehavior visitPrefix(js.Prefix node) {
if (node.op == 'typeof' && node.argument is js.VariableUse)
if (node.op == 'typeof' && node.argument is js.VariableUse) {
return NativeThrowBehavior.never;
}
NativeThrowBehavior result = visit(node.argument);
switch (node.op) {
case '+':
+4 -3
View File
@@ -129,9 +129,10 @@ void _simplifyConstConditionals(ir.Component component, CompilerOptions options,
if (node is! ir.Annotatable) {
return false;
}
return computePragmaAnnotationDataFromIr(node).any((pragma) =>
pragma == const PragmaAnnotationData('noInline') ||
pragma == const PragmaAnnotationData('never-inline'));
return computePragmaAnnotationDataFromIr(node).any(
(PragmaAnnotationData pragma) =>
pragma == const PragmaAnnotationData('noInline') ||
pragma == const PragmaAnnotationData('never-inline'));
}
fe.ConstConditionalSimplifier(
@@ -33,6 +33,7 @@ import 'package:compiler/src/serialization/serialization.dart';
///
/// Example class before:
///
/// ```
/// class Foo {
/// final Bar bar;
/// final String name;
@@ -45,9 +46,11 @@ import 'package:compiler/src/serialization/serialization.dart';
/// return Foo(bar, name);
/// }
/// }
/// ```
///
/// After:
///
/// ```
/// class Foo {
/// Bar get bar => _bar.loaded();
/// final Deferrable<Bar> _bar;
@@ -67,6 +70,7 @@ import 'package:compiler/src/serialization/serialization.dart';
/// return Foo._deserialized(bar, name);
/// }
/// }
/// ```
abstract class Deferrable<E> {
E loaded();
@@ -119,7 +123,7 @@ class _DeferredCacheWithArg<E, A> extends Deferrable<E> {
E _loadData() {
final reader = _reader!;
final dataLoader = _dataLoader!;
final arg = _arg!;
final arg = _arg as A;
_reader = null;
_dataLoader = null;
_arg = null;
@@ -188,8 +188,9 @@ class FormattingDiagnosticHandler implements api.CompilerDiagnostics {
api.Diagnostic? lastKind = null;
int fatalCount = 0;
final int FATAL = api.Diagnostic.crash.ordinal | api.Diagnostic.error.ordinal;
final int INFO =
final int fatalCode =
api.Diagnostic.crash.ordinal | api.Diagnostic.error.ordinal;
final int infoCode =
api.Diagnostic.info.ordinal | api.Diagnostic.verboseInfo.ordinal;
FormattingDiagnosticHandler();
@@ -232,8 +233,8 @@ class FormattingDiagnosticHandler implements api.CompilerDiagnostics {
if (isAborting) return;
isAborting = (kind == api.Diagnostic.crash);
bool fatal = (kind.ordinal & FATAL) != 0;
bool isInfo = (kind.ordinal & INFO) != 0;
bool fatal = (kind.ordinal & fatalCode) != 0;
bool isInfo = (kind.ordinal & infoCode) != 0;
if (isInfo && uri == null && kind != api.Diagnostic.info) {
info(message, kind);
return;
+1 -1
View File
@@ -210,7 +210,7 @@ class SsaBranchBuilder {
HBasicBlock? joinBlock;
// If at least one branch did not abort, open the joinBranch.
if (!joinBranch.block.predecessors.isEmpty) {
if (joinBranch.block.predecessors.isNotEmpty) {
startBranch(joinBranch);
joinBlock = joinBranch.block;
}
+8 -7
View File
@@ -1321,7 +1321,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
final targetTypeArguments =
closedWorld.elementEnvironment.getFunctionTypeVariables(stubTarget);
if (targetTypeArguments.length > 0) {
if (targetTypeArguments.isNotEmpty) {
if (stubParameterStructure.typeParameters == 0) {
// This stub does not include type parameters so use RTI to make the
// appropriate defaults.
@@ -1498,7 +1498,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
_abstractValueDomain
.isEmpty(parameter.instructionType)
.isDefinitelyTrue);
if (emptyParameters.length > 0) {
if (emptyParameters.isNotEmpty) {
_addComment('${emptyParameters} inferred as [empty]');
add(HInvokeStatic(_commonElements.assertUnreachableMethod, [],
_abstractValueDomain.dynamicType, const []));
@@ -2025,8 +2025,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
// check. The null check is added before the argument type checks since in
// strong mode, the parameter type might be non-nullable.
if (member is FunctionEntity && member.name == '==') {
if (functionNode == null)
if (functionNode == null) {
throw StateError("'==' should have functionNode");
}
if (!_commonElements.operatorEqHandlesNullArgument(member)) {
_handleIf(
visitCondition: () {
@@ -2688,7 +2689,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
bodyExitBlock.addSuccessor(conditionBlock);
}
if (!continueHandlers.isEmpty) {
if (continueHandlers.isNotEmpty) {
if (!isAbortingBody) continueHandlers.add(localsHandler);
localsHandler =
savedLocals.mergeMultiple(continueHandlers, conditionBlock);
@@ -2697,7 +2698,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
HSubGraphBlockInformation bodyInfo =
HSubGraphBlockInformation(bodyGraph);
HLabeledBlockInformation info;
if (!labels.isEmpty) {
if (labels.isNotEmpty) {
info = HLabeledBlockInformation(bodyInfo, labels, isContinue: true);
} else {
info = HLabeledBlockInformation.implicit(bodyInfo, target,
@@ -3297,7 +3298,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
js.Template code = js.js.parseForeignJS('#');
push(HForeignCode(code, _abstractValueDomain.boolType,
[localsHandler.readLocal(switchTarget)],
nativeBehavior: NativeBehavior.PURE));
nativeBehavior: NativeBehavior.pure));
}
_handleIf(
@@ -5035,7 +5036,7 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
ConstantValue constant, ClassEntity classElement) {
if (constant is ConstructedConstantValue &&
constant.type.element == classElement) {
assert(constant.fields.length >= 1);
assert(constant.fields.isNotEmpty);
for (var field in constant.fields.keys) {
if (field.memberName.text == "index") {
final indexConstant = constant.fields[field];
+10 -8
View File
@@ -763,7 +763,7 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
void visitStatement(HInstruction node) {
assert(!isGeneratingExpression);
visit(node);
if (!expressionStack.isEmpty) {
if (expressionStack.isNotEmpty) {
assert(expressionStack.length == 1);
js.Expression expression = pop();
pushExpressionAsStatement(expression, node.sourceInformation);
@@ -962,7 +962,7 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
js.Block avoidContainer = js.Block.empty();
currentContainer = avoidContainer;
assignPhisOfSuccessors(condition!.end.successors.last);
bool hasPhiUpdates = !avoidContainer.statements.isEmpty;
bool hasPhiUpdates = avoidContainer.statements.isNotEmpty;
currentContainer = oldContainer;
if (isConditionExpression &&
@@ -1079,7 +1079,7 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
js.Block exitAvoidContainer = js.Block.empty();
currentContainer = exitAvoidContainer;
assignPhisOfSuccessors(condition!.end.successors.last);
bool hasExitPhiUpdates = !exitAvoidContainer.statements.isEmpty;
bool hasExitPhiUpdates = exitAvoidContainer.statements.isNotEmpty;
currentContainer = oldContainer;
oldContainer = currentContainer;
@@ -1099,7 +1099,7 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
js.Block updateBody = js.Block.empty();
currentContainer = updateBody;
assignPhisOfSuccessors(avoidEdge);
bool hasPhiUpdates = !updateBody.statements.isEmpty;
bool hasPhiUpdates = updateBody.statements.isNotEmpty;
currentContainer = body;
visitBodyIgnoreLabels(info);
if (info.updates != null) {
@@ -1206,7 +1206,7 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
generateStatements(labeledBlockInfo.body);
if (labeledBlockInfo.isContinue) {
while (!continueOverrides.isEmpty) {
while (continueOverrides.isNotEmpty) {
continueAction.remove(continueOverrides.head);
implicitContinueAction.remove(continueOverrides.head);
continueOverrides = continueOverrides.tail!;
@@ -1367,8 +1367,8 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
}
}
while (!worklist.isEmpty) {
while (!ready.isEmpty) {
while (worklist.isNotEmpty) {
while (ready.isNotEmpty) {
String destination = ready.removeLast();
String source = initialValue[destination]!;
// Since [source] might have been updated, use the current
@@ -2156,7 +2156,9 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
List<HInstruction> arguments,
SourceInformation? sourceInformation) {
ConstantValue? findConstant(HInstruction node) {
while (node is HLateValue) node = node.target;
while (node is HLateValue) {
node = node.target;
}
return node is HConstant ? node.constant : null;
}
@@ -872,7 +872,7 @@ class SsaInstructionMerger extends HBaseVisitor<void> implements CodegenPhase {
// entry.
int initializingAssignmentCount = (local is HParameterValue) ? 0 : 1;
return local.usedBy
.where((user) => user is HLocalSet)
.whereType<HLocalSet>()
.skip(initializingAssignmentCount)
.isNotEmpty;
}
@@ -1090,7 +1090,7 @@ class SsaInstructionMerger extends HBaseVisitor<void> implements CodegenPhase {
// Return true if it is found, or false if not.
bool findInInputsAndPopNonMatching(HInstruction instruction) {
assert(!isEffectivelyPure(instruction));
while (!expectedInputs!.isEmpty) {
while (expectedInputs!.isNotEmpty) {
HInstruction nextInput = expectedInputs!.removeLast();
assert(!generateAtUseSite.contains(nextInput));
assert(nextInput.usedBy.length == 1);
@@ -1232,7 +1232,9 @@ class SsaConditionMerger extends HGraphVisitor implements CodegenPhase {
// before the control flow instruction, or the last instruction,
// then we will have to emit a statement for that last instruction.
if (instruction != block.last &&
!identical(instruction, block.last!.previous)) return true;
!identical(instruction, block.last!.previous)) {
return true;
}
// If one of the instructions in the block until [instruction] is
// not generated at use site, then we will have to emit a
@@ -1535,8 +1537,9 @@ class SsaPhiConditioning extends HGraphVisitor implements CodegenPhase {
void _markHandled(HPhi phi, HBasicBlock dominator) {
if (_handled.add(phi)) {
for (final input in phi.inputs) {
if (input is HPhi && dominator.dominates(input.block!))
if (input is HPhi && dominator.dominates(input.block!)) {
_markHandled(input, dominator);
}
}
}
}
@@ -208,7 +208,9 @@ class SsaSimplifyInterceptors extends HBaseVisitor<bool>
instructions.where((i) => i.block == bestBlock).toSet();
HInstruction? current =
(dominator?.block == bestBlock) ? dominator : bestBlock.first;
while (current != null && !set.contains(current)) current = current.next;
while (current != null && !set.contains(current)) {
current = current.next;
}
assert(current != null);
return current;
}
@@ -83,7 +83,7 @@ class InvokeDynamicSpecializer {
return const InvokeDynamicSpecializer();
}
if (selector.isCall) {
if (selector.namedArguments.length == 0) {
if (selector.namedArguments.isEmpty) {
int argumentCount = selector.argumentCount;
if (argumentCount == 0) {
if (name == 'abs') return const AbsSpecializer();
+14 -10
View File
@@ -492,15 +492,16 @@ class LocalsHandler {
/// for (var i = 0; i < 2; i++) fs[i]();
///
/// We solve this by emitting the following code (only for [ast.For] loops):
/// <Create box> <== move the first box creation outside the loop.
/// <initializer>;
/// loop-entry:
/// if (!<condition>) goto loop-exit;
/// <body>
/// <update box> // create a new box and copy the captured loop-variables.
/// <updates>
/// goto loop-entry;
/// loop-exit:
///
/// <Create box> <== move the first box creation outside the loop.
/// <initializer>;
/// loop-entry:
/// if (!<condition>) goto loop-exit;
/// <body>
/// <update box> // create a new box and copy the captured loop-variables.
/// <updates>
/// goto loop-entry;
/// loop-exit:
void startLoop(
CapturedLoopScope loopInfo, SourceInformation? sourceInformation) {
if (loopInfo.hasBoxedLoopVariables) {
@@ -609,7 +610,7 @@ class LocalsHandler {
/// exclude local values from the result when they are no longer in scope.
LocalsHandler mergeMultiple(
List<LocalsHandler> localsHandlers, HBasicBlock joinBlock) {
assert(localsHandlers.length > 0);
assert(localsHandlers.isNotEmpty);
if (localsHandlers.length == 1) return localsHandlers.single;
Map<Local, HInstruction> joinedLocals = {};
HInstruction? thisValue = null;
@@ -708,6 +709,9 @@ class SyntheticLocal extends Local {
SyntheticLocal(this.name, this.executableContext, this.memberContext);
@override
bool operator ==(other) => identical(this, other);
@override
String toString() => 'SyntheticLocal($name)';
}
+1 -1
View File
@@ -267,7 +267,7 @@ abstract class LoopHandler {
builder.open(loopExitBlock);
// Create a new localsHandler for the loopExitBlock with the correct phis.
if (!breakHandlers.isEmpty) {
if (breakHandlers.isNotEmpty) {
if (branchExitBlock != null) {
// Add the values of the locals at the end of the condition block to
// the phis. These are the values that flow to the exit if the
+63 -50
View File
@@ -807,6 +807,10 @@ class HBasicBlock extends HInstructionList {
@override
int get hashCode => id;
@override
bool operator ==(other) =>
identical(this, other) || other is HBasicBlock && id == other.id;
bool get isNew => _status == _BasicBlockStatus.new_;
bool get isOpen => _status == _BasicBlockStatus.open;
bool get isClosed => _status == _BasicBlockStatus.closed;
@@ -870,7 +874,7 @@ class HBasicBlock extends HInstructionList {
}
void addPhi(HPhi phi) {
assert(phi.inputs.length == 0 || phi.inputs.length == predecessors.length);
assert(phi.inputs.isEmpty || phi.inputs.length == predecessors.length);
assert(phi.block == null);
phis.internalAddAfter(phis.last, phi);
phi.notifyAddedToBlock(this);
@@ -1163,9 +1167,10 @@ abstract class HInstruction implements SpannableWithEntity {
: inputs = [...initialInputs];
// Convenience constructors that avoid an intermediate list.
HInstruction._0(this.instructionType) : inputs = [];
HInstruction._1(HInstruction input, this.instructionType) : inputs = [input];
HInstruction._2(
HInstruction._noInput(this.instructionType) : inputs = [];
HInstruction._oneInput(HInstruction input, this.instructionType)
: inputs = [input];
HInstruction._twoInputs(
HInstruction input1, HInstruction input2, this.instructionType)
: inputs = [input1, input2];
@@ -1180,6 +1185,9 @@ abstract class HInstruction implements SpannableWithEntity {
@override
int get hashCode => id;
@override
bool operator ==(other) => identical(this, other);
bool useGvn() => _useGvn;
void setUseGvn() {
_useGvn = true;
@@ -1657,7 +1665,7 @@ class DominatedUses {
/// This used for attaching source information to reads of locals.
class HRef extends HInstruction {
HRef(HInstruction value, SourceInformation sourceInformation)
: super._1(value, value.instructionType) {
: super._oneInput(value, value.instructionType) {
this.sourceInformation = sourceInformation;
}
@@ -1693,10 +1701,11 @@ abstract class HCheck extends HInstruction
HCheck(super.inputs, super.type) {
setUseGvn();
}
HCheck._1(super.input, super.type) : super._1() {
HCheck._oneInput(super.input, super.type) : super._oneInput() {
setUseGvn();
}
HCheck._2(super.input1, super.input2, super.type) : super._2() {
HCheck._twoInputs(super.input1, super.input2, super.type)
: super._twoInputs() {
setUseGvn();
}
@@ -1813,7 +1822,7 @@ class HCreate extends HInstruction {
// Allocates a box to hold mutated captured variables.
class HCreateBox extends HInstruction {
HCreateBox(super.type) : super._0();
HCreateBox(super.type) : super._noInput();
@override
bool isAllocation(AbstractValueDomain domain) => true;
@@ -2276,7 +2285,7 @@ class HFieldSet extends HFieldAccess {
// Raw reference to a function.
class HFunctionReference extends HInstruction {
FunctionEntity element;
HFunctionReference(this.element, super.type) : super._0() {
HFunctionReference(this.element, super.type) : super._noInput() {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
setUseGvn();
@@ -2298,7 +2307,7 @@ class HFunctionReference extends HInstruction {
class HGetLength extends HInstruction {
final bool isAssignable;
HGetLength(super.receiver, super.type, {required this.isAssignable})
: super._1() {
: super._oneInput() {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
setUseGvn();
@@ -2485,7 +2494,7 @@ class HInvokeExternal extends HInvoke {
@override
bool canThrow(AbstractValueDomain domain) {
if (element.isInstanceMember) {
if (inputs.length > 0) {
if (inputs.isNotEmpty) {
return inputs.first.isNull(domain).isPotentiallyTrue
? throwBehavior.canThrow
: throwBehavior.onNonNull.canThrow;
@@ -2507,7 +2516,7 @@ class HInvokeExternal extends HInvoke {
/// is `null` before having any other side-effects.
bool isNullGuardFor(HInstruction receiver) {
if (!element.isInstanceMember) return false;
if (inputs.length < 1) return false;
if (inputs.isEmpty) return false;
if (inputs.first.nonCheck() != receiver.nonCheck()) return false;
return true;
}
@@ -2581,7 +2590,7 @@ class HForeignCode extends HForeign {
bool isJsStatement() => isStatement;
@override
bool canThrow(AbstractValueDomain domain) {
if (inputs.length > 0) {
if (inputs.isNotEmpty) {
return inputs.first.isNull(domain).isPotentiallyTrue
? throwBehavior.canThrow
: throwBehavior.onNonNull.canThrow;
@@ -2602,7 +2611,7 @@ class HForeignCode extends HForeign {
/// [receiver] is `null` before having any other side-effects.
bool isNullGuardFor(HInstruction? receiver) {
if (!throwBehavior.isNullNSMGuard) return false;
if (inputs.length < 1) return false;
if (inputs.isEmpty) return false;
if (inputs.first.nonCheck() != receiver!.nonCheck()) return false;
return true;
}
@@ -2622,7 +2631,7 @@ class HForeignCode extends HForeign {
}
abstract class HInvokeBinary extends HInstruction {
HInvokeBinary(super.left, super.right, super.type) : super._2() {
HInvokeBinary(super.left, super.right, super.type) : super._twoInputs() {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
setUseGvn();
@@ -2854,7 +2863,7 @@ class HBitXor extends HBinaryBitOp {
}
abstract class HInvokeUnary extends HInstruction {
HInvokeUnary(super.input, super.type) : super._1() {
HInvokeUnary(super.input, super.type) : super._oneInput() {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
setUseGvn();
@@ -3034,7 +3043,7 @@ class HLoopBranch extends HConditionalBranch {
class HConstant extends HInstruction {
final ConstantValue constant;
HConstant._internal(this.constant, super.constantType) : super._0();
HConstant._internal(this.constant, super.constantType) : super._noInput();
@override
String toString() => 'literal: ${constant.toStructuredText(null)}';
@@ -3075,7 +3084,7 @@ class HConstant extends HInstruction {
}
class HNot extends HInstruction {
HNot(super.value, super.type) : super._1() {
HNot(super.value, super.type) : super._oneInput() {
setUseGvn();
}
@@ -3093,7 +3102,7 @@ class HNot extends HInstruction {
/// first use must be in an HLocalSet. That is, [HParameterValue]s have a
/// value from the start, whereas [HLocalValue]s need to be initialized first.
class HLocalValue extends HInstruction {
HLocalValue(Entity? variable, super.type) : super._0() {
HLocalValue(Entity? variable, super.type) : super._noInput() {
sourceElement = variable;
}
@@ -3299,7 +3308,7 @@ class HReturn extends HControlFlow {
class HThrowExpression extends HInstruction {
HThrowExpression(
super.value, super.type, SourceInformation? sourceInformation)
: super._1() {
: super._oneInput() {
this.sourceInformation = sourceInformation;
}
@override
@@ -3311,7 +3320,7 @@ class HThrowExpression extends HInstruction {
}
class HAwait extends HInstruction {
HAwait(super.value, super.type) : super._1();
HAwait(super.value, super.type) : super._oneInput();
@override
String toString() => 'await';
@override
@@ -3326,7 +3335,7 @@ class HAwait extends HInstruction {
class HYield extends HInstruction {
HYield(super.value, this.hasStar, super.type,
SourceInformation? sourceInformation)
: super._1() {
: super._oneInput() {
this.sourceInformation = sourceInformation;
}
bool hasStar;
@@ -3360,7 +3369,7 @@ class HStatic extends HInstruction {
final MemberEntity element;
HStatic(this.element, super.type, SourceInformation? sourceInformation)
: super._0() {
: super._noInput() {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
if (element.isAssignable) {
@@ -3400,7 +3409,7 @@ class HInterceptor extends HInstruction {
// (a && C.JSArray_methods).get$first(a)
//
HInterceptor(super.receiver, super.type) : super._1() {
HInterceptor(super.receiver, super.type) : super._oneInput() {
this.sourceInformation = receiver.sourceInformation;
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
@@ -3473,7 +3482,7 @@ class HLazyStatic extends HInstruction {
final FieldEntity element;
HLazyStatic(this.element, super.type, SourceInformation? sourceInformation)
: super._0() {
: super._noInput() {
// TODO(4931): The first access has side-effects, but we afterwards we
// should be able to GVN.
sideEffects.setAllSideEffects();
@@ -3497,7 +3506,7 @@ class HLazyStatic extends HInstruction {
class HStaticStore extends HInstruction {
FieldEntity element;
HStaticStore(this.element, HInstruction value)
: super._1(value, value.instructionType) {
: super._oneInput(value, value.instructionType) {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
sideEffects.setChangesStaticProperty();
@@ -3534,7 +3543,7 @@ class HLiteralList extends HInstruction {
/// The primitive array indexing operation. Note that this instruction
/// does not throw because we generate the checks explicitly.
class HIndex extends HInstruction {
HIndex(super.receiver, super.index, super.type) : super._2() {
HIndex(super.receiver, super.index, super.type) : super._twoInputs() {
sideEffects.clearAllSideEffects();
sideEffects.clearAllDependencies();
sideEffects.setDependsOnIndexStore();
@@ -3604,7 +3613,7 @@ class HIndexAssign extends HInstruction {
}
class HCharCodeAt extends HInstruction {
HCharCodeAt(super.receiver, super.index, super.type) : super._2();
HCharCodeAt(super.receiver, super.index, super.type) : super._twoInputs();
@override
String toString() => 'HCharCodeAt';
@@ -3644,7 +3653,8 @@ class HCharCodeAt extends HInstruction {
/// 'this' with HLateValue(HThis) will have the effect of copying 'this' to a
/// temporary which will reduce the size of minified code.
class HLateValue extends HInstruction implements HLateInstruction {
HLateValue(HInstruction target) : super._1(target, target.instructionType);
HLateValue(HInstruction target)
: super._oneInput(target, target.instructionType);
HInstruction get target => inputs.single;
@@ -3684,7 +3694,7 @@ class HPrimitiveCheck extends HCheck {
HInstruction input, SourceInformation? sourceInformation,
{this.receiverTypeCheckSelector})
: checkedType = type,
super._1(input, type) {
super._oneInput(input, type) {
assert(isReceiverTypeCheck == (receiverTypeCheckSelector != null));
this.sourceElement = input.sourceElement;
this.sourceInformation = sourceInformation;
@@ -3738,7 +3748,7 @@ class HPrimitiveCheck extends HCheck {
// bool!` checks and the backend checks them correctly, this instruction will
// become unnecessary and should be removed.
class HBoolConversion extends HCheck {
HBoolConversion(super.input, super.type) : super._1();
HBoolConversion(super.input, super.type) : super._oneInput();
@override
bool isJsStatement() => false;
@@ -3780,7 +3790,8 @@ class HNullCheck extends HCheck {
Selector? selector;
FieldEntity? field;
HNullCheck(super.input, super.type, {this.sticky = false}) : super._1();
HNullCheck(super.input, super.type, {this.sticky = false})
: super._oneInput();
@override
bool isControlFlow() => true;
@@ -3949,11 +3960,11 @@ class HTypeKnown extends HCheck {
HTypeKnown.pinned(this.knownType, HInstruction input)
: this._isMovable = false,
super._1(input, knownType);
super._oneInput(input, knownType);
HTypeKnown.witnessed(this.knownType, HInstruction input, HInstruction witness)
: this._isMovable = true,
super._2(input, witness, knownType);
super._twoInputs(input, witness, knownType);
@override
String toString() => 'TypeKnown $knownType';
@@ -3997,7 +4008,7 @@ class HTypeKnown extends HCheck {
}
class HRangeConversion extends HCheck {
HRangeConversion(super.input, super.type) : super._1() {
HRangeConversion(super.input, super.type) : super._oneInput() {
sourceElement = checkedInput.sourceElement;
}
@@ -4009,7 +4020,7 @@ class HRangeConversion extends HCheck {
}
class HStringConcat extends HInstruction {
HStringConcat(super.left, super.right, super.type) : super._2() {
HStringConcat(super.left, super.right, super.type) : super._twoInputs() {
setUseGvn();
}
@@ -4033,7 +4044,7 @@ class HStringConcat extends HInstruction {
/// into a String value.
class HStringify extends HInstruction {
bool _isPure = false; // Some special cases are pure, e.g. int argument.
HStringify(super.input, super.resultType) : super._1() {
HStringify(super.input, super.resultType) : super._oneInput() {
sideEffects.setAllSideEffects();
sideEffects.setDependsOnSomething();
}
@@ -4080,7 +4091,7 @@ class HLoopInformation {
do {
HBasicBlock current = workQueue.removeLast();
addBlock(current, workQueue);
} while (!workQueue.isEmpty);
} while (workQueue.isNotEmpty);
}
// Adds a block and transitively all its predecessors in the loop as
@@ -4330,7 +4341,7 @@ class HSwitchBlockInformation implements HStatementInformation {
@override
HBasicBlock get end {
// We don't create a switch block if there are no cases.
assert(!statements.isEmpty);
assert(statements.isNotEmpty);
return statements.last.end;
}
@@ -4352,7 +4363,7 @@ class HIsTest extends HInstruction {
HIsTest(this.dartType, this.checkedAbstractValue, super.rti, super.checked,
super.instructionType)
: super._2() {
: super._twoInputs() {
setUseGvn();
}
@@ -4390,7 +4401,7 @@ class HIsTestSimple extends HInstruction {
HIsTestSimple(this.dartType, this.checkedAbstractValue, this.specialization,
super.checked, super.type)
: super._1() {
: super._oneInput() {
setUseGvn();
}
@@ -4541,7 +4552,7 @@ class HAsCheck extends HCheck {
HAsCheck(this.checkedType, this.checkedTypeExpression, this.isTypeError,
super.rti, super.checked, super.instructionType)
: super._2();
: super._twoInputs();
// The type input is first to facilitate the `type.as(value)` codegen pattern.
HInstruction get typeInput => inputs[0];
@@ -4588,7 +4599,7 @@ class HAsCheckSimple extends HCheck {
HAsCheckSimple(super.checked, this.dartType, this.checkedType,
this.isTypeError, this.method, super.type)
: super._1();
: super._oneInput();
@override
HInstruction get checkedInput => inputs[0];
@@ -4624,7 +4635,8 @@ class HAsCheckSimple extends HCheck {
/// Subtype check comparing two Rti types.
class HSubtypeCheck extends HCheck {
HSubtypeCheck(super.subtype, super.supertype, super.type) : super._2() {
HSubtypeCheck(super.subtype, super.supertype, super.type)
: super._twoInputs() {
setUseGvn();
}
@@ -4653,7 +4665,7 @@ abstract interface class HRtiInstruction {}
class HLoadType extends HInstruction implements HRtiInstruction {
TypeRecipe typeExpression;
HLoadType(this.typeExpression, super.instructionType) : super._0() {
HLoadType(this.typeExpression, super.instructionType) : super._noInput() {
setUseGvn();
}
@@ -4682,11 +4694,11 @@ class HLoadType extends HInstruction implements HRtiInstruction {
///
/// Classes with reified type arguments have the type environment stored on the
/// instance. The reified environment is typically stored as the instance type,
/// e.g. "UnmodifiableListView<int>".
/// e.g. `UnmodifiableListView<int>`.
class HInstanceEnvironment extends HInstruction implements HRtiInstruction {
late AbstractValue codegenInputType; // Assigned in SsaTypeKnownRemover
HInstanceEnvironment(super.instance, super.type) : super._1() {
HInstanceEnvironment(super.instance, super.type) : super._oneInput() {
setUseGvn();
}
@@ -4713,7 +4725,7 @@ class HTypeEval extends HInstruction implements HRtiInstruction {
HTypeEval(
super.environment, this.envStructure, this.typeExpression, super.type)
: super._1() {
: super._oneInput() {
setUseGvn();
}
@@ -4738,7 +4750,8 @@ class HTypeEval extends HInstruction implements HRtiInstruction {
/// Extends an Rti type environment with generic function types.
class HTypeBind extends HInstruction implements HRtiInstruction {
HTypeBind(super.environment, super.typeArguments, super.type) : super._2() {
HTypeBind(super.environment, super.typeArguments, super.type)
: super._twoInputs() {
setUseGvn();
}
@@ -4891,7 +4904,7 @@ class HArrayFlagsSet extends HInstruction
}
class HIsLateSentinel extends HInstruction {
HIsLateSentinel(super.value, super.type) : super._1() {
HIsLateSentinel(super.value, super.type) : super._oneInput() {
setUseGvn();
}
+14 -17
View File
@@ -1234,11 +1234,6 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
return node;
}
@override
HInstruction visitRelational(HRelational node) {
return super.visitRelational(node);
}
HInstruction? handleIdentityCheck(HRelational node) {
HInstruction left = node.left;
HInstruction right = node.right;
@@ -2055,13 +2050,13 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
final left = node.left;
final right = node.right;
StringConstantValue? leftString = getString(left);
if (leftString != null && leftString.stringValue.length == 0) {
if (leftString != null && leftString.stringValue.isEmpty) {
return right;
}
final rightString = getString(right);
if (rightString == null) return node;
if (rightString.stringValue.length == 0) return left;
if (rightString.stringValue.isEmpty) return left;
HInstruction? prefix;
if (leftString == null) {
@@ -2398,7 +2393,7 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
}
InterfaceType instanceType =
_closedWorld.elementEnvironment.getThisType(instance.element);
if (instanceType.typeArguments.length == 0) {
if (instanceType.typeArguments.isEmpty) {
instance.instantiatedTypes?.forEach(_registry.registerInstantiation);
return HLoadType.type(instanceType, instance.instructionType);
}
@@ -2902,7 +2897,7 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
}
bool isDeadCode(HInstruction instruction) {
if (!instruction.usedBy.isEmpty) return false;
if (instruction.usedBy.isNotEmpty) return false;
if (isTrivialDeadStore(instruction)) return true;
if (instruction.sideEffects.hasSideEffects()) return false;
if (instruction.canThrow(_abstractValueDomain)) {
@@ -3164,7 +3159,7 @@ class SsaLiveBlockAnalyzer extends HBaseVisitor<void> {
void analyze() {
markBlockLive(graph.entry);
while (!worklist.isEmpty) {
while (worklist.isNotEmpty) {
HBasicBlock live = worklist.removeLast();
live.last!.accept(this);
}
@@ -3259,7 +3254,7 @@ class SsaDeadPhiEliminator implements OptimizationPhase {
}
// Process the worklist by propagating liveness to phi inputs.
while (!worklist.isEmpty) {
while (worklist.isNotEmpty) {
HPhi phi = worklist.removeLast();
for (final input in phi.inputs) {
if (input is HPhi && !livePhis.contains(input)) {
@@ -3312,7 +3307,7 @@ class SsaRedundantPhiEliminator implements OptimizationPhase {
block.forEachPhi((HPhi phi) => worklist.add(phi));
}
while (!worklist.isEmpty) {
while (worklist.isNotEmpty) {
HPhi phi = worklist.removeLast();
// If the phi has already been processed, continue.
@@ -3382,7 +3377,7 @@ class SsaGlobalValueNumberer implements OptimizationPhase {
do {
GvnWorkItem item = workQueue.removeLast();
visitBasicBlock(item.block, item.valueSet, workQueue);
} while (!workQueue.isEmpty);
} while (workQueue.isNotEmpty);
}
@override
@@ -3422,7 +3417,7 @@ class SsaGlobalValueNumberer implements OptimizationPhase {
bool firstInstructionInLoop = block == loopHeader
// Compensate for lack of code motion.
||
(blockChangesFlags[loopHeader.id] == 0 &&
(blockChangesFlags[loopHeader.id].isEmpty &&
isLoopAlwaysTaken() &&
loopHeader.successors[0] == block);
while (instruction != null) {
@@ -3474,7 +3469,7 @@ class SsaGlobalValueNumberer implements OptimizationPhase {
while (instruction != null) {
final next = instruction.next;
final flags = instruction.sideEffects.getChangesFlags();
assert(flags == 0 || !instruction.useGvn());
assert(flags.isEmpty || !instruction.useGvn());
// TODO(sra): Is the above assertion too strong? We should be able to
// reuse the values generated by idempotent operations that have
// effects. Would it be correct to make the kill below be conditional on
@@ -3512,7 +3507,7 @@ class SsaGlobalValueNumberer implements OptimizationPhase {
HBasicBlock current = workQueue.removeLast();
changesFlags = changesFlags.union(
getChangesFlagsForDominatedBlock(block, current, workQueue));
} while (!workQueue.isEmpty);
} while (workQueue.isNotEmpty);
successorValues.kill(changesFlags);
}
workQueue.add(GvnWorkItem(dominated, successorValues));
@@ -4551,7 +4546,9 @@ class MemorySet {
}
if (use is HInvokeStatic) {
if (closedWorld.commonElements
.isCheckConcurrentModificationError(use.element)) return true;
.isCheckConcurrentModificationError(use.element)) {
return true;
}
}
return false;
+3 -3
View File
@@ -5,7 +5,7 @@
library ssa.tracer;
import '../../compiler_api.dart' as api show OutputSink;
import '../diagnostics/invariant.dart' show DEBUG_MODE;
import '../diagnostics/invariant.dart' show debugMode;
import '../inferrer/abstract_value_domain.dart';
import '../js_backend/namer.dart' show suffixForGetInterceptor;
import '../js_model/js_world.dart' show JClosedWorld;
@@ -23,7 +23,7 @@ class HTracer extends HGraphVisitor with TracerUtil {
HTracer(this.output, this.closedWorld);
void traceGraph(String name, HGraph graph) {
DEBUG_MODE = true;
debugMode = true;
tag("cfg", () {
printProperty("name", name);
visitDominatorTree(graph);
@@ -31,7 +31,7 @@ class HTracer extends HGraphVisitor with TracerUtil {
}
void traceJavaScriptText(String name, String data) {
DEBUG_MODE = true;
debugMode = true;
tag("cfg", () {
printProperty("name", name);
// Emit a fake basic block, with one 'instruction' per line of text.
@@ -107,7 +107,7 @@ class SsaTypePropagator extends HBaseVisitor<AbstractValue>
void processWorklist() {
do {
while (!worklist.isEmpty) {
while (worklist.isNotEmpty) {
int id = worklist.removeLast();
HInstruction instruction = workmap[id]!;
workmap.remove(id);
@@ -120,7 +120,7 @@ class SsaTypePropagator extends HBaseVisitor<AbstractValue>
// replaced operands, so we may need to take another stab at
// emptying the worklist afterwards.
processPendingOptimizations();
} while (!worklist.isEmpty);
} while (worklist.isNotEmpty);
}
void addToWorkList(HInstruction instruction) {
+1 -1
View File
@@ -59,7 +59,7 @@ class HValidator extends HInstructionVisitor {
markInvalid("Return or throw node with > 1 successor "
"or not going to exit-block");
}
if (block.last is HExit && !block.successors.isEmpty) {
if (block.last is HExit && block.successors.isNotEmpty) {
markInvalid("Exit block with successor");
}
@@ -11,7 +11,7 @@ import '../tracer.dart';
import 'nodes.dart';
import 'optimize.dart' show OptimizationPhase, SsaOptimizerTask;
bool _DEBUG = false;
bool _debug = false;
class ValueRangeInfo {
late final IntValue intZero;
@@ -332,6 +332,9 @@ class MarkerValue extends VariableValue {
MarkerValue(this.isLower, this.isPositive, super.info);
@override
int get hashCode => isLower.hashCode;
@override
bool operator ==(other) {
return other is MarkerValue && isLower == other.isLower;
@@ -606,20 +609,22 @@ class Range {
// If we could not compute max or min, pick a value in the two
// ranges, with priority to [IntValue]s because they are simpler.
if (low == info.unknownValue) {
if (lower is IntValue)
if (lower is IntValue) {
low = lower;
else if (other.lower is IntValue)
} else if (other.lower is IntValue) {
low = other.lower;
else
} else {
low = lower;
}
}
if (up == info.unknownValue) {
if (upper is IntValue)
if (upper is IntValue) {
up = upper;
else if (other.upper is IntValue)
} else if (other.upper is IntValue) {
up = other.upper;
else
} else {
up = upper;
}
}
return info.newNormalizedRange(low, up);
}
@@ -1081,8 +1086,9 @@ class SsaValueRangeAnalyzer extends HBaseVisitor<Range>
@override
Range visitInvokeDynamicMethod(HInvokeDynamicMethod invoke) {
if ((invoke.inputs.length == 3) && (invoke.selector.name == "%"))
if ((invoke.inputs.length == 3) && (invoke.selector.name == "%")) {
return handleInvokeModulo(invoke);
}
return super.visitInvokeDynamicMethod(invoke);
}
@@ -1329,7 +1335,7 @@ class LoopUpdateRecognizer extends HBaseVisitor<Range?> {
final widened = updateRange.replaceMarkers(lowerBound, upperBound);
final result = startRange.union(widened);
if (_DEBUG) {
if (_debug) {
print('------- ${loopPhi.sourceElement}'
'\n marker $markerRange'
'\n update $updateRange'
+4
View File
@@ -164,4 +164,8 @@ class ValueSetNode {
int get hashCode => hash;
ValueSetNode? next;
ValueSetNode(this.value, this.hash, this.next);
@override
bool operator ==(other) =>
identical(this, other) || other is ValueSetNode && hash == other.hash;
}
@@ -62,7 +62,9 @@ class LiveInterval {
@override
String toString() {
List<String> res = [];
for (final interval in ranges) res.add(interval.toString());
for (final interval in ranges) {
res.add(interval.toString());
}
return '(${res.join(", ")})';
}
}
@@ -474,12 +476,14 @@ class VariableNamer {
}
String allocateTemporary() {
while (!freeTemporaryNames.isEmpty) {
while (freeTemporaryNames.isNotEmpty) {
String name = freeTemporaryNames.removeLast();
if (!usedNames.contains(name)) return name;
}
String name = 't${temporaryIndex++}';
while (usedNames.contains(name)) name = 't${temporaryIndex++}';
while (usedNames.contains(name)) {
name = 't${temporaryIndex++}';
}
return name;
}
@@ -653,7 +657,9 @@ class SsaVariableAllocator extends HBaseVisitor<void> implements CodegenPhase {
// A [HTypeKnown] instruction never has a name, but its checked
// input might, therefore we need to do a copy instead of an
// assignment.
while (input is HTypeKnown) input = input.inputs[0];
while (input is HTypeKnown) {
input = input.inputs[0];
}
if (!needsName(input)) {
names.addAssignment(predecessor, input, phi);
} else {
+2 -2
View File
@@ -12,7 +12,7 @@ import 'options.dart' show CompilerOptions;
import 'ssa/nodes.dart' as ssa show HGraph;
import 'ssa/tracer.dart' show HTracer;
String? TRACE_FILTER_PATTERN_FOR_TEST;
String? traceFilterPatternForTest;
/// Dumps the intermediate representation after each phase in a format
/// readable by IR Hydra.
@@ -27,7 +27,7 @@ class Tracer with TracerUtil {
factory Tracer(JClosedWorld closedWorld, CompilerOptions options,
api.CompilerOutput compilerOutput) {
String? pattern = options.dumpSsaPattern ?? TRACE_FILTER_PATTERN_FOR_TEST;
String? pattern = options.dumpSsaPattern ?? traceFilterPatternForTest;
if (pattern == null) return Tracer._(closedWorld, null, null);
var traceFilter = RegExp(pattern);
var output =
@@ -200,8 +200,9 @@ class CallStructure {
if (positionalArgumentCount > requiredParameterCount) return false;
assert(positionalArgumentCount == requiredParameterCount);
if (namedArgumentCount >
optionalParameterCount + parameters.requiredNamedParameters.length)
optionalParameterCount + parameters.requiredNamedParameters.length) {
return false;
}
int nameIndex = 0;
List<String> namedParameters = parameters.namedParameters;
@@ -213,8 +214,9 @@ class CallStructure {
while (nameIndex < namedParameters.length) {
String parameterName = namedParameters[nameIndex];
if (name == parameterName) {
if (parameters.requiredNamedParameters.contains(name))
if (parameters.requiredNamedParameters.contains(name)) {
seenRequiredNamedParameters++;
}
found = true;
break;
}
@@ -201,12 +201,12 @@ class ClassHierarchyImpl implements ClassHierarchy {
node.forEachSubclass((ClassEntity cls) {
getClassHierarchyNode(cls).writeToDataSink(sink);
return IterationStep.CONTINUE;
}, ClassHierarchyNode.ALL);
}, ClassHierarchyNode.all);
ClassSet set = getClassSet(_commonElements.objectClass);
set.forEachSubclass((ClassEntity cls) {
getClassSet(cls).writeToDataSink(sink);
return IterationStep.CONTINUE;
}, ClassHierarchyNode.ALL);
}, ClassHierarchyNode.all);
sink.end(tag);
}
@@ -262,7 +262,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
ClassHierarchyNode? hierarchy = _classHierarchyNodes[cls];
if (hierarchy == null) return const [];
return hierarchy
.subclassesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
.subclassesByMask(ClassHierarchyNode.explicitlyInstantiated);
}
@override
@@ -270,7 +270,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
ClassHierarchyNode? subclasses = _classHierarchyNodes[cls];
if (subclasses == null) return const [];
return subclasses.subclassesByMask(
ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
ClassHierarchyNode.explicitlyInstantiated,
strict: true);
}
@@ -286,7 +286,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
ClassEntity cls, IterationStep f(ClassEntity cls)) {
ClassHierarchyNode? subclasses = _classHierarchyNodes[cls];
if (subclasses == null) return;
subclasses.forEachSubclass(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
subclasses.forEachSubclass(f, ClassHierarchyNode.explicitlyInstantiated,
strict: true);
}
@@ -295,7 +295,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
ClassHierarchyNode? subclasses = _classHierarchyNodes[cls];
if (subclasses == null) return false;
return subclasses.anySubclass(
predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
predicate, ClassHierarchyNode.explicitlyInstantiated,
strict: true);
}
@@ -305,8 +305,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
if (classSet == null) {
return const [];
} else {
return classSet
.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED);
return classSet.subtypesByMask(ClassHierarchyNode.explicitlyInstantiated);
}
}
@@ -316,7 +315,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
if (classSet == null) {
return const [];
} else {
return classSet.subtypesByMask(ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
return classSet.subtypesByMask(ClassHierarchyNode.explicitlyInstantiated,
strict: true);
}
}
@@ -327,7 +326,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
if (classSet == null) {
return const [];
} else {
return classSet.subtypesByMask(ClassHierarchyNode.ALL);
return classSet.subtypesByMask(ClassHierarchyNode.all);
}
}
@@ -343,7 +342,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
ClassEntity cls, IterationStep f(ClassEntity cls)) {
ClassSet? classSet = _classSets[cls];
if (classSet == null) return;
classSet.forEachSubtype(f, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
classSet.forEachSubtype(f, ClassHierarchyNode.explicitlyInstantiated,
strict: true);
}
@@ -352,7 +351,7 @@ class ClassHierarchyImpl implements ClassHierarchy {
ClassSet? classSet = _classSets[cls];
if (classSet == null) return false;
return classSet.anySubtype(
predicate, ClassHierarchyNode.EXPLICITLY_INSTANTIATED,
predicate, ClassHierarchyNode.explicitlyInstantiated,
strict: true);
}
@@ -779,11 +778,11 @@ class _InheritedInThisClassCache {
if (_inheritingClasses == null) {
_inheritingClasses = {};
_inheritingClasses!.addAll(memberHoldingClassNode
.subclassesByMask(ClassHierarchyNode.ALL, strict: false));
.subclassesByMask(ClassHierarchyNode.all, strict: false));
for (ClassHierarchyNode mixinApplication
in builder._classSets[memberHoldingClass]!.mixinApplicationNodes) {
_inheritingClasses!.addAll(mixinApplication
.subclassesByMask(ClassHierarchyNode.ALL, strict: false));
.subclassesByMask(ClassHierarchyNode.all, strict: false));
}
}
@@ -861,7 +860,7 @@ class _InheritedInSubtypeCache {
classes.add(z);
}
return IterationStep.CONTINUE;
}, ClassHierarchyNode.ALL, strict: strict);
}, ClassHierarchyNode.all, strict: strict);
}
// A subclasses of [x] that implement [y].
+6 -6
View File
@@ -51,7 +51,7 @@ class ClassHierarchyNode {
/// Enum set for selecting instantiated classes in
/// [ClassHierarchyNode.subclassesByMask],
/// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
static final EnumSet<Instantiation> INSTANTIATED = EnumSet.fromValues(const [
static final EnumSet<Instantiation> instantiated = EnumSet.fromValues(const [
Instantiation.DIRECTLY_INSTANTIATED,
Instantiation.INDIRECTLY_INSTANTIATED,
Instantiation.ABSTRACTLY_INSTANTIATED,
@@ -60,7 +60,7 @@ class ClassHierarchyNode {
/// Enum set for selecting directly and abstractly instantiated classes in
/// [ClassHierarchyNode.subclassesByMask],
/// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
static final EnumSet<Instantiation> EXPLICITLY_INSTANTIATED =
static final EnumSet<Instantiation> explicitlyInstantiated =
EnumSet.fromValues(const [
Instantiation.DIRECTLY_INSTANTIATED,
Instantiation.ABSTRACTLY_INSTANTIATED,
@@ -69,7 +69,7 @@ class ClassHierarchyNode {
/// Enum set for selecting all classes in
/// [ClassHierarchyNode.subclassesByMask],
/// [ClassHierarchyNode.subclassesByMask] and [ClassSet.subtypesByMask].
static final EnumSet<Instantiation> ALL =
static final EnumSet<Instantiation> all =
EnumSet.allValues(Instantiation.values);
/// Creates an enum set for selecting the returned classes in
@@ -404,7 +404,7 @@ class ClassHierarchyNode {
continue;
}
if (withRespectTo != null &&
!child.anySubclass(isRelatedTo, ClassHierarchyNode.ALL)) {
!child.anySubclass(isRelatedTo, ClassHierarchyNode.all)) {
continue;
}
if (needsComma) {
@@ -655,7 +655,7 @@ class ClassSet {
return node.subclassesByMask(mask, strict: strict);
}
return SubtypesIterable.SubtypesIterator(this, mask, includeRoot: !strict);
return SubtypesIterable.subtypesIterator(this, mask, includeRoot: !strict);
}
/// Applies [predicate] to each subclass of [cls] matching the criteria
@@ -951,7 +951,7 @@ class SubtypesIterable extends IterableBase<ClassEntity> {
final EnumSet<Instantiation> mask;
final bool includeRoot;
SubtypesIterable.SubtypesIterator(this.subtypeSet, this.mask,
SubtypesIterable.subtypesIterator(this.subtypeSet, this.mask,
{this.includeRoot = true});
@override
@@ -154,7 +154,7 @@ class FunctionSetNode {
final set = elements as Set<MemberEntity>;
set.add(element);
}
if (!cache.isEmpty) cache.clear();
if (cache.isNotEmpty) cache.clear();
}
}
@@ -167,14 +167,14 @@ class FunctionSetNode {
if (index != list.length) {
list[index] = last;
}
if (!cache.isEmpty) cache.clear();
if (cache.isNotEmpty) cache.clear();
} else {
final set = elements as List<MemberEntity>;
if (set.remove(element)) {
// To avoid wobbling between the two representations, we do
// not transition back to the list representation even if we
// end up with few enough elements at this point.
if (!cache.isEmpty) cache.clear();
if (cache.isNotEmpty) cache.clear();
}
}
}
@@ -214,7 +214,7 @@ class FunctionSetNode {
// have been provided.
FunctionSetQuery noSuchMethodQuery =
noSuchMethods.query(noSuchMethodMask!, domain);
if (!noSuchMethodQuery.functions.isEmpty) {
if (noSuchMethodQuery.functions.isNotEmpty) {
functions ??= Setlet();
functions.addAll(noSuchMethodQuery.functions);
}
@@ -398,7 +398,7 @@ class MemberHierarchyBuilder {
final override = elementEnv.lookupClassMember(subtype, name);
if (override != null) addParent(override, member);
return IterationStep.CONTINUE;
}, ClassHierarchyNode.INSTANTIATED, strict: true);
}, ClassHierarchyNode.instantiated, strict: true);
if (!foundSuperclass) {
(_dynamicRoots[selector] ??= Setlet()).add(member);
@@ -747,7 +747,7 @@ class ParameterUsage {
_parameterStructure.requiredPositionalParameters
? null
: 0;
if (!_parameterStructure.namedParameters.isEmpty) {
if (_parameterStructure.namedParameters.isNotEmpty) {
_unprovidedNamedParameters =
Set<String>.from(_parameterStructure.namedParameters);
}
+7 -1
View File
@@ -43,6 +43,10 @@ class Selector {
@override
final int hashCode;
@override
bool operator ==(other) =>
identical(this, other) || other is Selector && hashCode == other.hashCode;
int get argumentCount => callStructure.argumentCount;
int get namedArgumentCount => callStructure.namedArgumentCount;
int get positionalArgumentCount => callStructure.positionalArgumentCount;
@@ -253,7 +257,9 @@ class Selector {
(name == "hashCode" ||
name == "runtimeType" ||
name == "toString" ||
name == "noSuchMethod")) return true;
name == "noSuchMethod")) {
return true;
}
// Calling toString always succeeds, calls to `noSuchMethod` (even well
// formed calls) always throw.
if (isCall &&

Some files were not shown because too many files have changed in this diff Show More