[dart2js] Update pubspec to 3.8 and reformat.
Change-Id: Ib1afd38a7d3694c2e5ed591132f41b147f76d75a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427560 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
This commit is contained in:
committed by
Commit Queue
parent
ec6a35c9ff
commit
2bb32ec55a
@@ -102,26 +102,21 @@ class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact {
|
||||
factory _CodegenImpact.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
MemberEntity member = source.readMember();
|
||||
final dynamicUses =
|
||||
source
|
||||
.readListOrNull(() => DynamicUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final staticUses =
|
||||
source
|
||||
.readListOrNull(() => StaticUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final typeUses =
|
||||
source
|
||||
.readListOrNull(() => TypeUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final constantUses =
|
||||
source
|
||||
.readListOrNull(() => ConstantUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final typeVariableBoundsSubtypeChecks =
|
||||
source.readListOrNull(() {
|
||||
return (source.readDartType(), source.readDartType());
|
||||
})?.toSet();
|
||||
final dynamicUses = source
|
||||
.readListOrNull(() => DynamicUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final staticUses = source
|
||||
.readListOrNull(() => StaticUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final typeUses = source
|
||||
.readListOrNull(() => TypeUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final constantUses = source
|
||||
.readListOrNull(() => ConstantUse.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final typeVariableBoundsSubtypeChecks = source.readListOrNull(() {
|
||||
return (source.readDartType(), source.readDartType());
|
||||
})?.toSet();
|
||||
final constSymbols = source.readStringsOrNull()?.toSet();
|
||||
final specializedGetInterceptors = source.readListOrNull(() {
|
||||
return source.readClasses().toSet();
|
||||
@@ -129,20 +124,16 @@ class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact {
|
||||
bool usesInterceptor = source.readBool();
|
||||
final asyncMarkersValue = source.readInt();
|
||||
final asyncMarkers = EnumSet<AsyncMarker>.fromRawBits(asyncMarkersValue);
|
||||
final genericInstantiations =
|
||||
source
|
||||
.readListOrNull(
|
||||
() => GenericInstantiation.readFromDataSource(source),
|
||||
)
|
||||
?.toSet();
|
||||
final genericInstantiations = source
|
||||
.readListOrNull(() => GenericInstantiation.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final nativeBehaviors = source.readListOrNull(
|
||||
() => NativeBehavior.readFromDataSource(source),
|
||||
);
|
||||
final nativeMethods = source.readMembersOrNull<FunctionEntity>()?.toSet();
|
||||
final oneShotInterceptors =
|
||||
source
|
||||
.readListOrNull(() => Selector.readFromDataSource(source))
|
||||
?.toSet();
|
||||
final oneShotInterceptors = source
|
||||
.readListOrNull(() => Selector.readFromDataSource(source))
|
||||
?.toSet();
|
||||
source.end(tag);
|
||||
return _CodegenImpact.internal(
|
||||
member,
|
||||
@@ -455,8 +446,8 @@ class CodegenResult {
|
||||
source.begin(tag);
|
||||
js.Fun? code = source.readJsNodeOrNull() as js.Fun?;
|
||||
CodegenImpact impact = CodegenImpact.readFromDataSource(source);
|
||||
final deferredExpressionData = js
|
||||
.DeferredExpressionRegistry.readDataFromDataSource(source);
|
||||
final deferredExpressionData =
|
||||
js.DeferredExpressionRegistry.readDataFromDataSource(source);
|
||||
source.end(tag);
|
||||
if (code != null) {
|
||||
code = code.withAnnotation(deferredExpressionData) as js.Fun;
|
||||
|
||||
@@ -100,8 +100,10 @@ abstract class CommonElements {
|
||||
late final ClassEntity streamClass = _findClass(asyncLibrary, 'Stream');
|
||||
|
||||
/// The dart:core library.
|
||||
late final LibraryEntity coreLibrary =
|
||||
_env.lookupLibrary(Uris.dartCore, required: true)!;
|
||||
late final LibraryEntity coreLibrary = _env.lookupLibrary(
|
||||
Uris.dartCore,
|
||||
required: true,
|
||||
)!;
|
||||
|
||||
/// The dart:async library.
|
||||
late final LibraryEntity? asyncLibrary = _env.lookupLibrary(Uris.dartAsync);
|
||||
@@ -118,12 +120,16 @@ abstract class CommonElements {
|
||||
);
|
||||
|
||||
/// The dart:typed_data library.
|
||||
late final LibraryEntity typedDataLibrary =
|
||||
_env.lookupLibrary(Uris.dartNativeTypedData, required: true)!;
|
||||
late final LibraryEntity typedDataLibrary = _env.lookupLibrary(
|
||||
Uris.dartNativeTypedData,
|
||||
required: true,
|
||||
)!;
|
||||
|
||||
/// The dart:_js_shared_embedded_names library.
|
||||
late final LibraryEntity sharedEmbeddedNamesLibrary =
|
||||
_env.lookupLibrary(Uris.dartJSSharedEmbeddedNames, required: true)!;
|
||||
late final LibraryEntity sharedEmbeddedNamesLibrary = _env.lookupLibrary(
|
||||
Uris.dartJSSharedEmbeddedNames,
|
||||
required: true,
|
||||
)!;
|
||||
|
||||
/// The dart:_js_helper library.
|
||||
late final LibraryEntity? jsHelperLibrary = _env.lookupLibrary(
|
||||
@@ -146,12 +152,16 @@ abstract class CommonElements {
|
||||
);
|
||||
|
||||
/// The dart:_rti library.
|
||||
late final LibraryEntity rtiLibrary =
|
||||
_env.lookupLibrary(Uris.dartRti, required: true)!;
|
||||
late final LibraryEntity rtiLibrary = _env.lookupLibrary(
|
||||
Uris.dartRti,
|
||||
required: true,
|
||||
)!;
|
||||
|
||||
/// The dart:_internal library.
|
||||
late final LibraryEntity internalLibrary =
|
||||
_env.lookupLibrary(Uris.dartInternal, required: true)!;
|
||||
late final LibraryEntity internalLibrary = _env.lookupLibrary(
|
||||
Uris.dartInternal,
|
||||
required: true,
|
||||
)!;
|
||||
|
||||
/// The dart:js_util library.
|
||||
late final LibraryEntity? dartJsUtilLibrary = _env.lookupLibrary(
|
||||
@@ -185,8 +195,10 @@ abstract class CommonElements {
|
||||
// TODO(johnniwinther): Kernel does not include redirecting factories
|
||||
// so this cannot be found in kernel. Find a consistent way to handle
|
||||
// this and similar cases.
|
||||
return _symbolConstructorTarget ??=
|
||||
_env.lookupConstructor(symbolImplementationClass, '')!;
|
||||
return _symbolConstructorTarget ??= _env.lookupConstructor(
|
||||
symbolImplementationClass,
|
||||
'',
|
||||
)!;
|
||||
}
|
||||
|
||||
void _ensureSymbolConstructorDependencies() {
|
||||
@@ -227,8 +239,10 @@ abstract class CommonElements {
|
||||
}
|
||||
|
||||
/// The function `identical` in dart:core.
|
||||
late final FunctionEntity identicalFunction =
|
||||
_findLibraryMember(coreLibrary, 'identical')!;
|
||||
late final FunctionEntity identicalFunction = _findLibraryMember(
|
||||
coreLibrary,
|
||||
'identical',
|
||||
)!;
|
||||
|
||||
/// Whether [element] is the `Function.apply` method.
|
||||
///
|
||||
@@ -420,8 +434,9 @@ abstract class CommonElements {
|
||||
bool onlyStringKeys = false,
|
||||
}) {
|
||||
// TODO(51534): Use CONST_CANONICAL_TYPE(T_i) for arguments.
|
||||
ClassEntity classElement =
|
||||
onlyStringKeys ? constantStringMapClass : generalConstantMapClass;
|
||||
ClassEntity classElement = onlyStringKeys
|
||||
? constantStringMapClass
|
||||
: generalConstantMapClass;
|
||||
return _env.createInterfaceType(classElement, sourceType.typeArguments);
|
||||
}
|
||||
|
||||
@@ -430,25 +445,25 @@ abstract class CommonElements {
|
||||
bool onlyStringKeys = false,
|
||||
}) {
|
||||
// TODO(51534): Use CONST_CANONICAL_TYPE(T_i) for arguments.
|
||||
ClassEntity classElement =
|
||||
onlyStringKeys ? constantStringSetClass : generalConstantSetClass;
|
||||
ClassEntity classElement = onlyStringKeys
|
||||
? constantStringSetClass
|
||||
: generalConstantSetClass;
|
||||
return _env.createInterfaceType(classElement, sourceType.typeArguments);
|
||||
}
|
||||
|
||||
/// Returns the field that holds the internal name in the implementation class
|
||||
/// for `Symbol`.
|
||||
|
||||
FieldEntity get symbolField =>
|
||||
_symbolImplementationField ??=
|
||||
_env.lookupLocalClassMember(
|
||||
symbolImplementationClass,
|
||||
PrivateName(
|
||||
'_name',
|
||||
symbolImplementationClass.library.canonicalUri,
|
||||
),
|
||||
required: true,
|
||||
)
|
||||
as FieldEntity;
|
||||
FieldEntity get symbolField => _symbolImplementationField ??=
|
||||
_env.lookupLocalClassMember(
|
||||
symbolImplementationClass,
|
||||
PrivateName(
|
||||
'_name',
|
||||
symbolImplementationClass.library.canonicalUri,
|
||||
),
|
||||
required: true,
|
||||
)
|
||||
as FieldEntity;
|
||||
|
||||
InterfaceType get symbolImplementationType =>
|
||||
_env.getRawType(symbolImplementationClass);
|
||||
@@ -462,10 +477,12 @@ abstract class CommonElements {
|
||||
return _mapLiteralClass!;
|
||||
}
|
||||
|
||||
late final ConstructorEntity mapLiteralConstructor =
|
||||
_env.lookupConstructor(mapLiteralClass, '_literal')!;
|
||||
late final ConstructorEntity mapLiteralConstructorEmpty =
|
||||
_env.lookupConstructor(mapLiteralClass, '_empty')!;
|
||||
late final ConstructorEntity mapLiteralConstructor = _env.lookupConstructor(
|
||||
mapLiteralClass,
|
||||
'_literal',
|
||||
)!;
|
||||
late final ConstructorEntity mapLiteralConstructorEmpty = _env
|
||||
.lookupConstructor(mapLiteralClass, '_empty')!;
|
||||
late final FunctionEntity mapLiteralUntypedMaker =
|
||||
_env.lookupLocalClassMember(
|
||||
mapLiteralClass,
|
||||
@@ -484,10 +501,12 @@ abstract class CommonElements {
|
||||
'LinkedHashSet',
|
||||
);
|
||||
|
||||
late final ConstructorEntity setLiteralConstructor =
|
||||
_env.lookupConstructor(setLiteralClass, '_literal')!;
|
||||
late final ConstructorEntity setLiteralConstructorEmpty =
|
||||
_env.lookupConstructor(setLiteralClass, '_empty')!;
|
||||
late final ConstructorEntity setLiteralConstructor = _env.lookupConstructor(
|
||||
setLiteralClass,
|
||||
'_literal',
|
||||
)!;
|
||||
late final ConstructorEntity setLiteralConstructorEmpty = _env
|
||||
.lookupConstructor(setLiteralClass, '_empty')!;
|
||||
late final FunctionEntity setLiteralUntypedMaker =
|
||||
_env.lookupLocalClassMember(
|
||||
setLiteralClass,
|
||||
@@ -716,8 +735,10 @@ abstract class CommonElements {
|
||||
late final FunctionEntity getNativeInterceptorMethod =
|
||||
_findInterceptorsFunction('getNativeInterceptor');
|
||||
|
||||
late final ConstructorEntity jsArrayTypedConstructor =
|
||||
_env.lookupConstructor(jsArrayClass, 'typed')!;
|
||||
late final ConstructorEntity jsArrayTypedConstructor = _env.lookupConstructor(
|
||||
jsArrayClass,
|
||||
'typed',
|
||||
)!;
|
||||
|
||||
// From dart:_js_helper
|
||||
// TODO(johnniwinther): Avoid the need for this (from [CheckedModeHelper]).
|
||||
|
||||
@@ -109,12 +109,11 @@ abstract class CompilerTask {
|
||||
return runZoned(
|
||||
action,
|
||||
zoneValues: _zoneValues ??= {_measurer: this},
|
||||
zoneSpecification:
|
||||
_zoneSpecification ??= ZoneSpecification(
|
||||
run: _run,
|
||||
runUnary: _runUnary,
|
||||
runBinary: _runBinary,
|
||||
),
|
||||
zoneSpecification: _zoneSpecification ??= ZoneSpecification(
|
||||
run: _run,
|
||||
runUnary: _runUnary,
|
||||
runBinary: _runBinary,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -159,10 +159,9 @@ class Compiler {
|
||||
options.validate();
|
||||
environment = Environment(options.environment);
|
||||
|
||||
abstractValueStrategy =
|
||||
options.useTrivialAbstractValueDomain
|
||||
? const TrivialAbstractValueStrategy()
|
||||
: const TypeMaskStrategy();
|
||||
abstractValueStrategy = options.useTrivialAbstractValueDomain
|
||||
? const TrivialAbstractValueStrategy()
|
||||
: const TypeMaskStrategy();
|
||||
if (options.debugGlobalInference) {
|
||||
abstractValueStrategy = ComputableAbstractValueStrategy(
|
||||
abstractValueStrategy,
|
||||
@@ -267,8 +266,10 @@ class Compiler {
|
||||
return '${library.importUri}(${library.fileUri})';
|
||||
}
|
||||
|
||||
var unusedLibraries =
|
||||
component.libraries.where(isUnused).map(libraryString).toList();
|
||||
var unusedLibraries = component.libraries
|
||||
.where(isUnused)
|
||||
.map(libraryString)
|
||||
.toList();
|
||||
unusedLibraries.sort();
|
||||
var jsonLibraries = jsonEncode(unusedLibraries);
|
||||
outputProvider.createOutputSink(
|
||||
@@ -318,10 +319,9 @@ class Compiler {
|
||||
if (options.readProgramSplit != null) {
|
||||
var constraintUri = options.readProgramSplit;
|
||||
var constraintParser = psc.Parser();
|
||||
var programSplitJson =
|
||||
await CompilerFileSystem(
|
||||
provider,
|
||||
).entityForUri(constraintUri!).readAsString();
|
||||
var programSplitJson = await CompilerFileSystem(
|
||||
provider,
|
||||
).entityForUri(constraintUri!).readAsString();
|
||||
programSplitConstraintsData = constraintParser.read(programSplitJson);
|
||||
}
|
||||
|
||||
@@ -353,9 +353,9 @@ class Compiler {
|
||||
List<Uri> libraries,
|
||||
) {
|
||||
frontendStrategy.registerLoadedLibraries(component, libraries);
|
||||
ResolutionEnqueuer resolutionEnqueuer = frontendStrategy
|
||||
.createResolutionEnqueuer(enqueueTask, this)
|
||||
..onEmptyForTesting = onResolutionQueueEmptyForTesting;
|
||||
ResolutionEnqueuer resolutionEnqueuer =
|
||||
frontendStrategy.createResolutionEnqueuer(enqueueTask, this)
|
||||
..onEmptyForTesting = onResolutionQueueEmptyForTesting;
|
||||
if (retainDataForTesting) {
|
||||
resolutionEnqueuerForTesting = resolutionEnqueuer;
|
||||
resolutionWorldBuilderForTesting = resolutionEnqueuer.worldBuilder;
|
||||
@@ -455,8 +455,8 @@ class Compiler {
|
||||
}
|
||||
return output.withNewComponent(component);
|
||||
} else {
|
||||
ir.Component component =
|
||||
await serializationTask.deserializeComponentAndUpdateOptions();
|
||||
ir.Component component = await serializationTask
|
||||
.deserializeComponentAndUpdateOptions();
|
||||
if (retainDataForTesting) {
|
||||
componentForTesting = component;
|
||||
}
|
||||
@@ -952,8 +952,8 @@ class Compiler {
|
||||
// so that tests can determine the cause of the message.
|
||||
final messageText =
|
||||
diagnosticMessage is DiagnosticCfeMessage && options.testMode
|
||||
? diagnosticMessage.messageCode
|
||||
: '$message';
|
||||
? diagnosticMessage.messageCode
|
||||
: '$message';
|
||||
if (span.isUnknown) {
|
||||
callUserHandler(message, null, null, null, messageText, kind);
|
||||
} else {
|
||||
|
||||
@@ -425,8 +425,9 @@ class ShiftRightOperation extends BinaryBitOperation {
|
||||
ConstantValue adjustedLeft = left;
|
||||
if (left is IntConstantValue) {
|
||||
BigInt value = left.intValue;
|
||||
BigInt truncated =
|
||||
value.isNegative ? value.toSigned(32) : value.toUnsigned(32);
|
||||
BigInt truncated = value.isNegative
|
||||
? value.toSigned(32)
|
||||
: value.toUnsigned(32);
|
||||
if (value != truncated) {
|
||||
adjustedLeft = createInt(truncated);
|
||||
}
|
||||
|
||||
@@ -715,10 +715,9 @@ Future<api.CompilationResult> compile(
|
||||
}
|
||||
|
||||
// TODO(johnniwinther): Measure time for reading files.
|
||||
SourceFileByteReader byteReader =
|
||||
compilerOptions.memoryMappedFiles
|
||||
? const MemoryMapSourceFileByteReader()
|
||||
: const MemoryCopySourceFileByteReader();
|
||||
SourceFileByteReader byteReader = compilerOptions.memoryMappedFiles
|
||||
? const MemoryMapSourceFileByteReader()
|
||||
: const MemoryCopySourceFileByteReader();
|
||||
|
||||
SourceFileProvider inputProvider;
|
||||
if (bazelPaths != null) {
|
||||
@@ -990,8 +989,9 @@ void writeString(Uri uri, String text) {
|
||||
if (!uri.isScheme('file')) {
|
||||
_fail('Unhandled scheme ${uri.scheme}.');
|
||||
}
|
||||
var file = (File(uri.toFilePath())
|
||||
..createSync(recursive: true)).openSync(mode: FileMode.write);
|
||||
var file = (File(
|
||||
uri.toFilePath(),
|
||||
)..createSync(recursive: true)).openSync(mode: FileMode.write);
|
||||
file.writeStringSync(text);
|
||||
file.closeSync();
|
||||
}
|
||||
@@ -1052,7 +1052,8 @@ Usage: dart compile js [arguments] <dart entry point>
|
||||
-O2 Safe production-oriented optimizations (like minification).
|
||||
-O3 Potentially unsafe optimizations (see -h -v for details).
|
||||
-O4 More aggressive unsafe optimizations (see -h -v for details).
|
||||
'''.trim(),
|
||||
'''
|
||||
.trim(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1244,7 +1245,8 @@ be removed in a future version:
|
||||
--no-frequency-based-minification
|
||||
Experimental. Disable the new frequency based minifying namer and use the
|
||||
old namer instead.
|
||||
'''.trim(),
|
||||
'''
|
||||
.trim(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -644,10 +644,9 @@ class DeferredLoadTask extends CompilerTask {
|
||||
unitText.write(' <MAIN UNIT>');
|
||||
} else {
|
||||
unitText.write(' imports:');
|
||||
var imports =
|
||||
outputUnit.imports
|
||||
.map((i) => '${i.enclosingLibraryUri.resolveUri(i.uri)}')
|
||||
.toList();
|
||||
var imports = outputUnit.imports
|
||||
.map((i) => '${i.enclosingLibraryUri.resolveUri(i.uri)}')
|
||||
.toList();
|
||||
for (var i in imports..sort()) {
|
||||
unitText.write('\n $i:');
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ class Builder {
|
||||
for (var import in imports) {
|
||||
var libraryUri = import.enclosingLibraryUri;
|
||||
var prefix = import.name;
|
||||
Map<String, ImportEntity> uriNodes =
|
||||
importsByUriAndPrefix[libraryUri] ??= {};
|
||||
Map<String, ImportEntity> uriNodes = importsByUriAndPrefix[libraryUri] ??=
|
||||
{};
|
||||
uriNodes[prefix!] = import;
|
||||
}
|
||||
|
||||
@@ -181,8 +181,9 @@ class Builder {
|
||||
}
|
||||
} else {
|
||||
assert(constraint.combinerType == CombinerType.or);
|
||||
var setTransition =
|
||||
setTransitions[constraint] ??= SetTransition(constraint.imports);
|
||||
var setTransition = setTransitions[constraint] ??= SetTransition(
|
||||
constraint.imports,
|
||||
);
|
||||
setTransition.transitions.addAll(transitiveChildren);
|
||||
}
|
||||
|
||||
|
||||
@@ -218,8 +218,9 @@ class DiagnosticReporter {
|
||||
}
|
||||
|
||||
void _reportAssertionFailure(SpannableAssertionFailure ex) {
|
||||
String message =
|
||||
(ex.message != null) ? tryToString(ex.message!) : tryToString(ex);
|
||||
String message = (ex.message != null)
|
||||
? tryToString(ex.message!)
|
||||
: tryToString(ex);
|
||||
_reportDiagnosticInternal(
|
||||
createMessage(ex.node, MessageKind.generic, {'text': message}),
|
||||
const <DiagnosticMessage>[],
|
||||
|
||||
@@ -672,18 +672,18 @@ class ElementInfoCollector {
|
||||
}
|
||||
|
||||
if (function is ConstructorEntity) {
|
||||
name =
|
||||
name == ""
|
||||
? function.enclosingClass.name
|
||||
: "${function.enclosingClass.name}.${function.name}";
|
||||
name = name == ""
|
||||
? function.enclosingClass.name
|
||||
: "${function.enclosingClass.name}.${function.name}";
|
||||
kind = FunctionInfo.CONSTRUCTOR_FUNCTION_KIND;
|
||||
}
|
||||
|
||||
FunctionModifiers modifiers = FunctionModifiers(
|
||||
isStatic: function.isStatic,
|
||||
isConst: function.isConst,
|
||||
isFactory:
|
||||
function is ConstructorEntity ? function.isFactoryConstructor : false,
|
||||
isFactory: function is ConstructorEntity
|
||||
? function.isFactoryConstructor
|
||||
: false,
|
||||
isExternal: function.isExternal,
|
||||
);
|
||||
List<CodeSpan> code = dumpInfoTask.codeOf(function);
|
||||
@@ -777,10 +777,9 @@ class ElementInfoCollector {
|
||||
return state.outputToInfo.putIfAbsent(outputUnit, () {
|
||||
// Dump-info currently only works with the full emitter. If another
|
||||
// emitter is used it will fail here.
|
||||
final filename =
|
||||
outputUnit.isMainOutput
|
||||
? (options.outputUri?.pathSegments.last ?? 'out')
|
||||
: deferredPartFileName(options, outputUnit.name);
|
||||
final filename = outputUnit.isMainOutput
|
||||
? (options.outputUri?.pathSegments.last ?? 'out')
|
||||
: deferredPartFileName(options, outputUnit.name);
|
||||
OutputUnitInfo info = OutputUnitInfo(
|
||||
filename,
|
||||
outputUnit.name,
|
||||
@@ -946,8 +945,9 @@ class KernelInfoCollector {
|
||||
if (superclass == coreTypes.objectClass) {
|
||||
continue;
|
||||
}
|
||||
final superclassLibrary =
|
||||
environment.lookupLibrary(superclass.enclosingLibrary.importUri)!;
|
||||
final superclassLibrary = environment.lookupLibrary(
|
||||
superclass.enclosingLibrary.importUri,
|
||||
)!;
|
||||
final superclassEntity = environment.lookupClass(
|
||||
superclassLibrary,
|
||||
superclass.name,
|
||||
@@ -1064,10 +1064,9 @@ class KernelInfoCollector {
|
||||
);
|
||||
|
||||
// TODO(markzipan): Determine if it's safe to default to nonNullable here.
|
||||
final nullability =
|
||||
parent is ir.Member
|
||||
? parent.enclosingLibrary.nonNullable
|
||||
: ir.Nullability.nonNullable;
|
||||
final nullability = parent is ir.Member
|
||||
? parent.enclosingLibrary.nonNullable
|
||||
: ir.Nullability.nonNullable;
|
||||
final functionType = function.computeFunctionType(nullability);
|
||||
|
||||
FunctionInfo info = FunctionInfo.fromKernel(
|
||||
@@ -1279,14 +1278,13 @@ class DumpInfoAnnotator {
|
||||
return null;
|
||||
}
|
||||
|
||||
final kFieldInfos =
|
||||
kernelInfo.state.info.fields
|
||||
.where(
|
||||
(f) =>
|
||||
f.name == field.name &&
|
||||
fullyResolvedNameForInfo(f.parent) == parentName,
|
||||
)
|
||||
.toList();
|
||||
final kFieldInfos = kernelInfo.state.info.fields
|
||||
.where(
|
||||
(f) =>
|
||||
f.name == field.name &&
|
||||
fullyResolvedNameForInfo(f.parent) == parentName,
|
||||
)
|
||||
.toList();
|
||||
assert(
|
||||
kFieldInfos.length == 1,
|
||||
'Ambiguous field resolution. '
|
||||
@@ -1349,14 +1347,13 @@ class DumpInfoAnnotator {
|
||||
// TODO(markzipan): [parentName] is used for disambiguation, but this might
|
||||
// not always be valid. Check and validate later.
|
||||
ClassInfo? visitClass(ClassEntity clazz, String parentName) {
|
||||
final kClassInfos =
|
||||
kernelInfo.state.info.classes
|
||||
.where(
|
||||
(i) =>
|
||||
i.name == clazz.name &&
|
||||
fullyResolvedNameForInfo(i.parent) == parentName,
|
||||
)
|
||||
.toList();
|
||||
final kClassInfos = kernelInfo.state.info.classes
|
||||
.where(
|
||||
(i) =>
|
||||
i.name == clazz.name &&
|
||||
fullyResolvedNameForInfo(i.parent) == parentName,
|
||||
)
|
||||
.toList();
|
||||
assert(
|
||||
kClassInfos.length == 1,
|
||||
'Ambiguous class resolution. '
|
||||
@@ -1432,10 +1429,9 @@ class DumpInfoAnnotator {
|
||||
|
||||
ClosureInfo? visitClosureClass(ClassEntity element) {
|
||||
final disambiguatedElementName = entityDisambiguator.name(element);
|
||||
final kClosureInfos =
|
||||
kernelInfo.state.info.closures
|
||||
.where((info) => info.name == disambiguatedElementName)
|
||||
.toList();
|
||||
final kClosureInfos = kernelInfo.state.info.closures
|
||||
.where((info) => info.name == disambiguatedElementName)
|
||||
.toList();
|
||||
assert(
|
||||
kClosureInfos.length == 1,
|
||||
'Ambiguous closure resolution. '
|
||||
@@ -1475,27 +1471,25 @@ class DumpInfoAnnotator {
|
||||
|
||||
var compareName = function.name;
|
||||
if (function is ConstructorEntity) {
|
||||
compareName =
|
||||
compareName == ""
|
||||
? function.enclosingClass.name
|
||||
: "${function.enclosingClass.name}.${function.name}";
|
||||
compareName = compareName == ""
|
||||
? function.enclosingClass.name
|
||||
: "${function.enclosingClass.name}.${function.name}";
|
||||
}
|
||||
|
||||
// Multiple kernel members can sometimes map to a single JElement.
|
||||
// [isSetter] and [isGetter] are required for disambiguating these cases.
|
||||
final kFunctionInfos =
|
||||
kernelInfo.state.info.functions
|
||||
.where(
|
||||
(i) =>
|
||||
i.name == compareName &&
|
||||
(isClosure
|
||||
? i.parent!.name
|
||||
: fullyResolvedNameForInfo(i.parent)) ==
|
||||
parentName &&
|
||||
!(function.isGetter ^ i.modifiers.isGetter) &&
|
||||
!(function.isSetter ^ i.modifiers.isSetter),
|
||||
)
|
||||
.toList();
|
||||
final kFunctionInfos = kernelInfo.state.info.functions
|
||||
.where(
|
||||
(i) =>
|
||||
i.name == compareName &&
|
||||
(isClosure
|
||||
? i.parent!.name
|
||||
: fullyResolvedNameForInfo(i.parent)) ==
|
||||
parentName &&
|
||||
!(function.isGetter ^ i.modifiers.isGetter) &&
|
||||
!(function.isSetter ^ i.modifiers.isSetter),
|
||||
)
|
||||
.toList();
|
||||
assert(
|
||||
kFunctionInfos.length <= 1,
|
||||
'Ambiguous function resolution. '
|
||||
@@ -1570,10 +1564,9 @@ class DumpInfoAnnotator {
|
||||
return kernelInfo.state.outputToInfo.putIfAbsent(outputUnit, () {
|
||||
// Dump-info currently only works with the full emitter. If another
|
||||
// emitter is used it will fail here.
|
||||
final filename =
|
||||
outputUnit.isMainOutput
|
||||
? (options.outputUri?.pathSegments.last ?? 'out')
|
||||
: deferredPartFileName(options, outputUnit.name);
|
||||
final filename = outputUnit.isMainOutput
|
||||
? (options.outputUri?.pathSegments.last ?? 'out')
|
||||
: deferredPartFileName(options, outputUnit.name);
|
||||
OutputUnitInfo info = OutputUnitInfo(
|
||||
filename,
|
||||
outputUnit.name,
|
||||
@@ -1843,8 +1836,8 @@ class DumpInfoTask extends CompilerTask implements InfoReporter {
|
||||
DumpInfoStateData result = infoCollector.state;
|
||||
|
||||
// Recursively build links to function uses
|
||||
final functionEntities =
|
||||
infoCollector.state.entityToInfo.keys.whereType<FunctionEntity>();
|
||||
final functionEntities = infoCollector.state.entityToInfo.keys
|
||||
.whereType<FunctionEntity>();
|
||||
for (final entity in functionEntities) {
|
||||
final info = infoCollector.state.entityToInfo[entity] as FunctionInfo;
|
||||
Iterable<Selection> uses = getRetaining(entity, closedWorld);
|
||||
@@ -1861,8 +1854,8 @@ class DumpInfoTask extends CompilerTask implements InfoReporter {
|
||||
}
|
||||
|
||||
// Recursively build links to field uses
|
||||
final fieldEntity =
|
||||
infoCollector.state.entityToInfo.keys.whereType<FieldEntity>();
|
||||
final fieldEntity = infoCollector.state.entityToInfo.keys
|
||||
.whereType<FieldEntity>();
|
||||
for (final entity in fieldEntity) {
|
||||
final info = infoCollector.state.entityToInfo[entity] as FieldInfo;
|
||||
Iterable<Selection> uses = getRetaining(entity, closedWorld);
|
||||
@@ -1924,8 +1917,8 @@ class DumpInfoTask extends CompilerTask implements InfoReporter {
|
||||
DumpInfoStateData result = infoCollector.state;
|
||||
|
||||
// Recursively build links to function uses
|
||||
final functionEntities =
|
||||
infoCollector.state.entityToInfo.keys.whereType<FunctionEntity>();
|
||||
final functionEntities = infoCollector.state.entityToInfo.keys
|
||||
.whereType<FunctionEntity>();
|
||||
for (final entity in functionEntities) {
|
||||
final info = infoCollector.state.entityToInfo[entity] as FunctionInfo;
|
||||
Iterable<Selection> uses = getRetaining(entity, closedWorld);
|
||||
@@ -1943,8 +1936,8 @@ class DumpInfoTask extends CompilerTask implements InfoReporter {
|
||||
}
|
||||
|
||||
// Recursively build links to field uses
|
||||
final fieldEntity =
|
||||
infoCollector.state.entityToInfo.keys.whereType<FieldEntity>();
|
||||
final fieldEntity = infoCollector.state.entityToInfo.keys
|
||||
.whereType<FieldEntity>();
|
||||
for (final entity in fieldEntity) {
|
||||
final info = infoCollector.state.entityToInfo[entity] as FieldInfo;
|
||||
Iterable<Selection> uses = getRetaining(entity, closedWorld);
|
||||
|
||||
@@ -1826,18 +1826,20 @@ abstract class DartTypes {
|
||||
namedParameterTypes,
|
||||
typeVariables,
|
||||
);
|
||||
List<FunctionTypeVariable> normalizableVariables =
|
||||
typeVariables
|
||||
.where((FunctionTypeVariable t) => t.bound is NeverType)
|
||||
.toList();
|
||||
List<FunctionTypeVariable> normalizableVariables = typeVariables
|
||||
.where((FunctionTypeVariable t) => t.bound is NeverType)
|
||||
.toList();
|
||||
return normalizableVariables.isEmpty
|
||||
? type
|
||||
: subst(
|
||||
List<DartType>.filled(normalizableVariables.length, neverType()),
|
||||
normalizableVariables,
|
||||
type,
|
||||
)
|
||||
as FunctionType;
|
||||
List<DartType>.filled(
|
||||
normalizableVariables.length,
|
||||
neverType(),
|
||||
),
|
||||
normalizableVariables,
|
||||
type,
|
||||
)
|
||||
as FunctionType;
|
||||
}
|
||||
|
||||
DartType futureOrType(DartType typeArgument) {
|
||||
@@ -1889,10 +1891,12 @@ abstract class DartTypes {
|
||||
subst(arguments, t.typeVariables, type);
|
||||
DartType returnType = substType(t.returnType);
|
||||
List<DartType> parameterTypes = t.parameterTypes.map(substType).toList();
|
||||
List<DartType> optionalParameterTypes =
|
||||
t.optionalParameterTypes.map(substType).toList();
|
||||
List<DartType> namedParameterTypes =
|
||||
t.namedParameterTypes.map(substType).toList();
|
||||
List<DartType> optionalParameterTypes = t.optionalParameterTypes
|
||||
.map(substType)
|
||||
.toList();
|
||||
List<DartType> namedParameterTypes = t.namedParameterTypes
|
||||
.map(substType)
|
||||
.toList();
|
||||
return functionType(
|
||||
returnType,
|
||||
parameterTypes,
|
||||
@@ -2175,8 +2179,9 @@ abstract class DartTypes {
|
||||
// Interface Compositionality + Super-Interface:
|
||||
if (s is InterfaceType) {
|
||||
if (t is InterfaceType) {
|
||||
InterfaceType? instance =
|
||||
s.element == t.element ? s : asInstanceOf(s, t.element);
|
||||
InterfaceType? instance = s.element == t.element
|
||||
? s
|
||||
: asInstanceOf(s, t.element);
|
||||
if (instance == null) return false;
|
||||
List<DartType> sArgs = instance.typeArguments;
|
||||
List<DartType> tArgs = t.typeArguments;
|
||||
|
||||
@@ -143,17 +143,15 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
_memberData = _inferrer.dataOfMember(_analyzedMember),
|
||||
// TODO(johnniwinther): Should side effects also be tracked for field
|
||||
// initializers?
|
||||
_sideEffectsBuilder =
|
||||
_analyzedMember is FunctionEntity
|
||||
? _inferrer.inferredDataBuilder.getSideEffectsBuilder(
|
||||
_analyzedMember,
|
||||
)
|
||||
: SideEffectsBuilder.free(_analyzedMember),
|
||||
_sideEffectsBuilder = _analyzedMember is FunctionEntity
|
||||
? _inferrer.inferredDataBuilder.getSideEffectsBuilder(
|
||||
_analyzedMember,
|
||||
)
|
||||
: SideEffectsBuilder.free(_analyzedMember),
|
||||
_inGenerativeConstructor = _analyzedNode is ir.Constructor,
|
||||
_capturedAndBoxed =
|
||||
capturedAndBoxed != null
|
||||
? Map<Local, FieldEntity>.from(capturedAndBoxed)
|
||||
: <Local, FieldEntity>{},
|
||||
_capturedAndBoxed = capturedAndBoxed != null
|
||||
? Map<Local, FieldEntity>.from(capturedAndBoxed)
|
||||
: <Local, FieldEntity>{},
|
||||
_stateInternal =
|
||||
previousState ??
|
||||
LocalState.initial(
|
||||
@@ -458,11 +456,10 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
case ir.AsyncMarker.Sync:
|
||||
if (_returnType == null) {
|
||||
// No return in the body.
|
||||
_returnType =
|
||||
_state.seenReturnOrThrow
|
||||
? _types
|
||||
.nonNullEmpty() // Body always throws.
|
||||
: _types.nullType;
|
||||
_returnType = _state.seenReturnOrThrow
|
||||
? _types
|
||||
.nonNullEmpty() // Body always throws.
|
||||
: _types.nullType;
|
||||
} else if (!_state.seenReturnOrThrow) {
|
||||
// We haven'TypeInformation seen returns on all branches. So the
|
||||
// method may also return null.
|
||||
@@ -727,18 +724,17 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
PhiElementTypeInformation? elementType;
|
||||
int length = 0;
|
||||
for (TypeInformation type in elementTypes) {
|
||||
elementType =
|
||||
elementType == null
|
||||
? _types.allocatePhi(null, null, type, isTry: false)
|
||||
: _types.addPhiInput(null, elementType, type);
|
||||
elementType = elementType == null
|
||||
? _types.allocatePhi(null, null, type, isTry: false)
|
||||
: _types.addPhiInput(null, elementType, type);
|
||||
length++;
|
||||
}
|
||||
final simplifiedElementType =
|
||||
elementType == null
|
||||
? _types.nonNullEmpty()
|
||||
: _types.simplifyPhi(null, null, elementType);
|
||||
TypeInformation containerType =
|
||||
isConst ? _types.constListType : _types.growableListType;
|
||||
final simplifiedElementType = elementType == null
|
||||
? _types.nonNullEmpty()
|
||||
: _types.simplifyPhi(null, null, elementType);
|
||||
TypeInformation containerType = isConst
|
||||
? _types.constListType
|
||||
: _types.growableListType;
|
||||
return _types.allocateList(
|
||||
containerType,
|
||||
node,
|
||||
@@ -766,17 +762,16 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
return _inferrer.concreteTypes.putIfAbsent(node, () {
|
||||
PhiElementTypeInformation? elementType;
|
||||
for (TypeInformation type in elementTypes) {
|
||||
elementType =
|
||||
elementType == null
|
||||
? _types.allocatePhi(null, null, type, isTry: false)
|
||||
: _types.addPhiInput(null, elementType, type);
|
||||
elementType = elementType == null
|
||||
? _types.allocatePhi(null, null, type, isTry: false)
|
||||
: _types.addPhiInput(null, elementType, type);
|
||||
}
|
||||
final simplifiedElementType =
|
||||
elementType == null
|
||||
? _types.nonNullEmpty()
|
||||
: _types.simplifyPhi(null, null, elementType);
|
||||
TypeInformation containerType =
|
||||
isConst ? _types.constSetType : _types.setType;
|
||||
final simplifiedElementType = elementType == null
|
||||
? _types.nonNullEmpty()
|
||||
: _types.simplifyPhi(null, null, elementType);
|
||||
TypeInformation containerType = isConst
|
||||
? _types.constSetType
|
||||
: _types.setType;
|
||||
return _types.allocateSet(
|
||||
containerType,
|
||||
node,
|
||||
@@ -1268,10 +1263,9 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
ir.VariableDeclaration? variable,
|
||||
) {
|
||||
if (_types.selectorNeedsUpdate(receiverType, mask)) {
|
||||
mask =
|
||||
receiverType == _types.dynamicType
|
||||
? null
|
||||
: _types.newTypedSelector(receiverType, mask);
|
||||
mask = receiverType == _types.dynamicType
|
||||
? null
|
||||
: _types.newTypedSelector(receiverType, mask);
|
||||
_inferrer.updateSelectorInMember(
|
||||
_analyzedMember,
|
||||
callType,
|
||||
@@ -1780,11 +1774,10 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
if (_isConstructorOfTypedArraySubclass(constructor)) {
|
||||
// We have something like `Uint32List(len)`.
|
||||
final length = _findLength(arguments);
|
||||
final member =
|
||||
_elementMap.elementEnvironment.lookupClassMember(
|
||||
constructor.enclosingClass,
|
||||
Names.indexName,
|
||||
)!;
|
||||
final member = _elementMap.elementEnvironment.lookupClassMember(
|
||||
constructor.enclosingClass,
|
||||
Names.indexName,
|
||||
)!;
|
||||
TypeInformation elementType = _inferrer.returnTypeOfMember(member);
|
||||
return _inferrer.concreteTypes.putIfAbsent(
|
||||
node,
|
||||
@@ -1909,8 +1902,11 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
);
|
||||
|
||||
// Narrow tested variable to not late sentinel on false branch.
|
||||
final currentTypeInformation =
|
||||
stateWhenNotSentinel.readLocal(_inferrer, _capturedAndBoxed, local)!;
|
||||
final currentTypeInformation = stateWhenNotSentinel.readLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
local,
|
||||
)!;
|
||||
stateWhenNotSentinel.updateLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
@@ -2164,12 +2160,11 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
LocalState stateAfterCheckWhenFalse = LocalState.childPath(_state);
|
||||
|
||||
// Narrow variable to tested type on true branch.
|
||||
final currentTypeInformation =
|
||||
stateAfterCheckWhenTrue.readLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
local,
|
||||
)!;
|
||||
final currentTypeInformation = stateAfterCheckWhenTrue.readLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
local,
|
||||
)!;
|
||||
stateAfterCheckWhenTrue.updateLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
@@ -2200,12 +2195,8 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
);
|
||||
|
||||
// Narrow tested variable to 'not null' on false branch.
|
||||
TypeInformation currentTypeInformation =
|
||||
stateAfterCheckWhenNotNull.readLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
local,
|
||||
)!;
|
||||
TypeInformation currentTypeInformation = stateAfterCheckWhenNotNull
|
||||
.readLocal(_inferrer, _capturedAndBoxed, local)!;
|
||||
stateAfterCheckWhenNotNull.updateLocal(
|
||||
_inferrer,
|
||||
_capturedAndBoxed,
|
||||
@@ -2277,13 +2268,12 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
final stateAfterRightWhenTrue = _stateAfterWhenTrue;
|
||||
final stateAfterRightWhenFalse = _stateAfterWhenFalse;
|
||||
final stateAfterWhenTrue = stateAfterRightWhenTrue;
|
||||
LocalState stateAfterWhenFalse = LocalState.childPath(
|
||||
stateBefore,
|
||||
).mergeDiamondFlow(
|
||||
_inferrer,
|
||||
stateAfterLeftWhenFalse,
|
||||
stateAfterRightWhenFalse,
|
||||
);
|
||||
LocalState stateAfterWhenFalse = LocalState.childPath(stateBefore)
|
||||
.mergeDiamondFlow(
|
||||
_inferrer,
|
||||
stateAfterLeftWhenFalse,
|
||||
stateAfterRightWhenFalse,
|
||||
);
|
||||
LocalState after = stateBefore.mergeDiamondFlow(
|
||||
_inferrer,
|
||||
stateAfterWhenTrue,
|
||||
@@ -2308,13 +2298,12 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
final rightInfo = handleCondition(node.right)!;
|
||||
final stateAfterRightWhenTrue = _stateAfterWhenTrue;
|
||||
final stateAfterRightWhenFalse = _stateAfterWhenFalse;
|
||||
LocalState stateAfterWhenTrue = LocalState.childPath(
|
||||
stateBefore,
|
||||
).mergeDiamondFlow(
|
||||
_inferrer,
|
||||
stateAfterLeftWhenTrue,
|
||||
stateAfterRightWhenTrue,
|
||||
);
|
||||
LocalState stateAfterWhenTrue = LocalState.childPath(stateBefore)
|
||||
.mergeDiamondFlow(
|
||||
_inferrer,
|
||||
stateAfterLeftWhenTrue,
|
||||
stateAfterRightWhenTrue,
|
||||
);
|
||||
LocalState stateAfterWhenFalse = stateAfterRightWhenFalse;
|
||||
LocalState stateAfter = stateBefore.mergeDiamondFlow(
|
||||
_inferrer,
|
||||
@@ -2552,13 +2541,12 @@ class KernelTypeGraphBuilder extends ir.VisitorDefault<TypeInformation?>
|
||||
// Continue with a copy of the state after the finalizer since control flow
|
||||
// should continue linearly. Update abort state to account for try/catch
|
||||
// aborting.
|
||||
_state =
|
||||
LocalState.childPath(_state)
|
||||
..seenReturnOrThrow =
|
||||
_state.seenReturnOrThrow || stateBeforeFinalizer.seenReturnOrThrow
|
||||
..seenBreakOrContinue =
|
||||
_state.seenBreakOrContinue ||
|
||||
stateBeforeFinalizer.seenBreakOrContinue;
|
||||
_state = LocalState.childPath(_state)
|
||||
..seenReturnOrThrow =
|
||||
_state.seenReturnOrThrow || stateBeforeFinalizer.seenReturnOrThrow
|
||||
..seenBreakOrContinue =
|
||||
_state.seenBreakOrContinue ||
|
||||
stateBeforeFinalizer.seenBreakOrContinue;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,9 @@ class ComputableAbstractValue implements AbstractValue {
|
||||
bool get isComputed => _wrappedValue != null;
|
||||
bool get isUncomputed => _wrappedValue == null;
|
||||
|
||||
AbstractValue _unwrapOrThrow() =>
|
||||
isUncomputed
|
||||
? throw StateError("Uncomputed abstract value")
|
||||
: _wrappedValue!;
|
||||
AbstractValue _unwrapOrThrow() => isUncomputed
|
||||
? throw StateError("Uncomputed abstract value")
|
||||
: _wrappedValue!;
|
||||
|
||||
AbstractValue _unwrapOrEmpty(AbstractValueDomain wrappedDomain) =>
|
||||
isUncomputed ? wrappedDomain.emptyType : _wrappedValue!;
|
||||
|
||||
@@ -754,10 +754,10 @@ class InferrerEngine {
|
||||
globalLocalsMap.getLocalsMap(member),
|
||||
node != null
|
||||
? ir.StaticTypeContext(
|
||||
node,
|
||||
closedWorld.elementMap.typeEnvironment,
|
||||
cache: ir.StaticTypeCacheImpl(),
|
||||
)
|
||||
node,
|
||||
closedWorld.elementMap.typeEnvironment,
|
||||
cache: ir.StaticTypeCacheImpl(),
|
||||
)
|
||||
: null,
|
||||
memberHierarchyBuilder,
|
||||
);
|
||||
|
||||
@@ -50,15 +50,15 @@ class VariableScope {
|
||||
}
|
||||
|
||||
VariableScope.deepCopyOf(VariableScope other)
|
||||
: variables =
|
||||
other.variables == null
|
||||
? null
|
||||
: Map<Local, TypeInformation>.from(other.variables!),
|
||||
: variables = other.variables == null
|
||||
? null
|
||||
: Map<Local, TypeInformation>.from(other.variables!),
|
||||
tryBlock = other.tryBlock,
|
||||
copyOf = other.copyOf ?? other,
|
||||
_level = other._level,
|
||||
parent =
|
||||
other.parent == null ? null : VariableScope.deepCopyOf(other.parent!);
|
||||
parent = other.parent == null
|
||||
? null
|
||||
: VariableScope.deepCopyOf(other.parent!);
|
||||
|
||||
/// `true` if this scope is for a try block.
|
||||
bool get isTry => tryBlock != null;
|
||||
@@ -224,8 +224,9 @@ class FieldInitializationScope {
|
||||
if (isThisExposed) return this;
|
||||
if (isIndefinite) return this;
|
||||
|
||||
FieldInitializationScope otherScope =
|
||||
elseScope.fields == null ? this : elseScope;
|
||||
FieldInitializationScope otherScope = elseScope.fields == null
|
||||
? this
|
||||
: elseScope;
|
||||
|
||||
thenScope.forEach((FieldEntity field, TypeInformation type) {
|
||||
final otherType = otherScope.readField(field);
|
||||
@@ -400,8 +401,9 @@ class LocalsHandler {
|
||||
final myType = _locals[local];
|
||||
if (myType == null) return; // Variable is only defined in [other].
|
||||
if (type == myType) return;
|
||||
_locals[local] =
|
||||
inPlace ? type : inferrer.types.allocateDiamondPhi(myType, type);
|
||||
_locals[local] = inPlace
|
||||
? type
|
||||
: inferrer.types.allocateDiamondPhi(myType, type);
|
||||
});
|
||||
return this;
|
||||
}
|
||||
@@ -493,10 +495,9 @@ class LocalsHandler {
|
||||
// Use a separate locals handler to perform the merge in, so that Phi
|
||||
// creation does not invalidate previous type knowledge while we might
|
||||
// still look it up.
|
||||
VariableScope merged =
|
||||
tryBlock != null
|
||||
? VariableScope.tryBlock(tryBlock, parent: _locals)
|
||||
: VariableScope(parent: _locals);
|
||||
VariableScope merged = tryBlock != null
|
||||
? VariableScope.tryBlock(tryBlock, parent: _locals)
|
||||
: VariableScope(parent: _locals);
|
||||
Map<Local, int> seenLocals = {};
|
||||
// Merge all other handlers.
|
||||
for (LocalsHandler handler in handlers) {
|
||||
|
||||
@@ -310,8 +310,9 @@ class _GraphGenerator extends TypeInformationVisitor<void> {
|
||||
var tracerSet = global.assignmentsBeforeTracing[node] ?? const {};
|
||||
var currentSet = node.inputs.toSet();
|
||||
for (TypeInformation assignment in currentSet) {
|
||||
String color =
|
||||
originalSet.contains(assignment) ? unchangedEdge : addedEdge;
|
||||
String color = originalSet.contains(assignment)
|
||||
? unchangedEdge
|
||||
: addedEdge;
|
||||
addEdge(assignment, node, color: color);
|
||||
}
|
||||
for (TypeInformation assignment in originalSet) {
|
||||
|
||||
@@ -156,10 +156,9 @@ abstract class TypeInformation {
|
||||
void incrementRefineCount() =>
|
||||
_flags = EnumSet.fromRawBits(_flags.mask.bits + (1 << numTypeInfoFlags));
|
||||
|
||||
void clearRefineCount() =>
|
||||
_flags = EnumSet.fromRawBits(
|
||||
_flags.mask.bits & ((1 << numTypeInfoFlags) - 1),
|
||||
);
|
||||
void clearRefineCount() => _flags = EnumSet.fromRawBits(
|
||||
_flags.mask.bits & ((1 << numTypeInfoFlags) - 1),
|
||||
);
|
||||
|
||||
void addUser(TypeInformation user) {
|
||||
assert(!user.isConcrete);
|
||||
@@ -654,10 +653,9 @@ class GetterTypeInformation extends MemberTypeInformation {
|
||||
AbstractValueDomain abstractValueDomain,
|
||||
this._member,
|
||||
FunctionType type,
|
||||
) : _type =
|
||||
abstractValueDomain
|
||||
.createFromStaticType(type.returnType)
|
||||
.abstractValue,
|
||||
) : _type = abstractValueDomain
|
||||
.createFromStaticType(type.returnType)
|
||||
.abstractValue,
|
||||
super._internal(abstractValueDomain, _member);
|
||||
|
||||
@override
|
||||
@@ -704,10 +702,9 @@ class MethodTypeInformation extends MemberTypeInformation {
|
||||
AbstractValueDomain abstractValueDomain,
|
||||
this._member,
|
||||
FunctionType type,
|
||||
) : _type =
|
||||
abstractValueDomain
|
||||
.createFromStaticType(type.returnType)
|
||||
.abstractValue,
|
||||
) : _type = abstractValueDomain
|
||||
.createFromStaticType(type.returnType)
|
||||
.abstractValue,
|
||||
super._internal(abstractValueDomain, _member);
|
||||
|
||||
@override
|
||||
@@ -739,10 +736,9 @@ class FactoryConstructorTypeInformation extends MemberTypeInformation {
|
||||
AbstractValueDomain abstractValueDomain,
|
||||
this._member,
|
||||
FunctionType type,
|
||||
) : _type =
|
||||
abstractValueDomain
|
||||
.createFromStaticType(type.returnType)
|
||||
.abstractValue,
|
||||
) : _type = abstractValueDomain
|
||||
.createFromStaticType(type.returnType)
|
||||
.abstractValue,
|
||||
super._internal(abstractValueDomain, _member);
|
||||
|
||||
@override
|
||||
@@ -797,10 +793,9 @@ class GenerativeConstructorTypeInformation extends MemberTypeInformation {
|
||||
return _narrowType(
|
||||
inferrer.abstractValueDomain,
|
||||
mask,
|
||||
_baseType ??=
|
||||
cls.isAbstract
|
||||
? inferrer.abstractValueDomain.createNonNullSubclass(cls)
|
||||
: inferrer.abstractValueDomain.createNonNullExact(cls),
|
||||
_baseType ??= cls.isAbstract
|
||||
? inferrer.abstractValueDomain.createNonNullSubclass(cls)
|
||||
: inferrer.abstractValueDomain.createNonNullExact(cls),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -962,10 +957,9 @@ class ParameterTypeInformation extends ElementTypeInformation {
|
||||
AbstractValue mask,
|
||||
InferrerEngine inferrer,
|
||||
) {
|
||||
final staticType =
|
||||
isOptionalNoDefault
|
||||
? inferrer.abstractValueDomain.includeNull(_type)
|
||||
: _type;
|
||||
final staticType = isOptionalNoDefault
|
||||
? inferrer.abstractValueDomain.includeNull(_type)
|
||||
: _type;
|
||||
return _narrowType(inferrer.abstractValueDomain, mask, staticType);
|
||||
}
|
||||
|
||||
@@ -1253,11 +1247,10 @@ class DynamicCallSiteTypeInformation<T extends ir.Node>
|
||||
selector!,
|
||||
typeMask,
|
||||
);
|
||||
final targets =
|
||||
_targets = inferrer.memberHierarchyBuilder.rootsForCall(
|
||||
typeMask,
|
||||
selector!,
|
||||
);
|
||||
final targets = _targets = inferrer.memberHierarchyBuilder.rootsForCall(
|
||||
typeMask,
|
||||
selector!,
|
||||
);
|
||||
invalidateTargetsIncludeComplexNoSuchMethod();
|
||||
receiver.addUser(this);
|
||||
if (arguments != null) {
|
||||
@@ -1351,10 +1344,9 @@ class DynamicCallSiteTypeInformation<T extends ir.Node>
|
||||
abstractValueDomain.isIntegerOrNull(info.type).isDefinitelyTrue;
|
||||
bool isEmpty(TypeInformation info) =>
|
||||
abstractValueDomain.isEmpty(info.type).isDefinitelyTrue;
|
||||
bool isUInt31(TypeInformation info) =>
|
||||
abstractValueDomain
|
||||
.isUInt31(abstractValueDomain.excludeNull(info.type))
|
||||
.isDefinitelyTrue;
|
||||
bool isUInt31(TypeInformation info) => abstractValueDomain
|
||||
.isUInt31(abstractValueDomain.excludeNull(info.type))
|
||||
.isDefinitelyTrue;
|
||||
bool isPositiveInt(TypeInformation info) =>
|
||||
abstractValueDomain.isPositiveIntegerOrNull(info.type).isDefinitelyTrue;
|
||||
|
||||
@@ -1451,16 +1443,12 @@ class DynamicCallSiteTypeInformation<T extends ir.Node>
|
||||
typeMask,
|
||||
);
|
||||
|
||||
final includesClosureCall =
|
||||
_hasClosureCallTargets = closedWorld.includesClosureCall(
|
||||
localSelector,
|
||||
typeMask,
|
||||
);
|
||||
final targets =
|
||||
_targets = inferrer.memberHierarchyBuilder.rootsForCall(
|
||||
typeMask,
|
||||
localSelector,
|
||||
);
|
||||
final includesClosureCall = _hasClosureCallTargets = closedWorld
|
||||
.includesClosureCall(localSelector, typeMask);
|
||||
final targets = _targets = inferrer.memberHierarchyBuilder.rootsForCall(
|
||||
typeMask,
|
||||
localSelector,
|
||||
);
|
||||
|
||||
// Update the call graph if the targets could have changed.
|
||||
if (!identical(targets, oldTargets)) {
|
||||
@@ -1581,11 +1569,8 @@ class DynamicCallSiteTypeInformation<T extends ir.Node>
|
||||
localSelector,
|
||||
mask,
|
||||
);
|
||||
final newTargets =
|
||||
_targets = inferrer.memberHierarchyBuilder.rootsForCall(
|
||||
mask,
|
||||
localSelector,
|
||||
);
|
||||
final newTargets = _targets = inferrer.memberHierarchyBuilder
|
||||
.rootsForCall(mask, localSelector);
|
||||
invalidateTargetsIncludeComplexNoSuchMethod();
|
||||
for (final target in newTargets) {
|
||||
if (!oldTargets.contains(target)) {
|
||||
@@ -2346,10 +2331,9 @@ class RecordTypeInformation extends TypeInformation with TracedTypeInformation {
|
||||
|
||||
@override
|
||||
AbstractValue safeType(InferrerEngine inferrer) {
|
||||
final shapeClass =
|
||||
inferrer.closedWorld.recordData
|
||||
.representationForShape(recordShape)
|
||||
?.cls;
|
||||
final shapeClass = inferrer.closedWorld.recordData
|
||||
.representationForShape(recordShape)
|
||||
?.cls;
|
||||
return shapeClass != null
|
||||
? inferrer.abstractValueDomain.createNonNullSubtype(shapeClass)
|
||||
: inferrer.abstractValueDomain.recordType;
|
||||
|
||||
@@ -339,8 +339,9 @@ class TypeSystem {
|
||||
return excludeLateSentinel0();
|
||||
}
|
||||
|
||||
AbstractValue narrowing =
|
||||
_abstractValueDomain.createFromStaticType(annotation).abstractValue;
|
||||
AbstractValue narrowing = _abstractValueDomain
|
||||
.createFromStaticType(annotation)
|
||||
.abstractValue;
|
||||
|
||||
if (excludeNull) {
|
||||
narrowing = _abstractValueDomain.excludeNull(narrowing);
|
||||
@@ -376,10 +377,9 @@ class TypeSystem {
|
||||
Local parameter, {
|
||||
bool isVirtual = false,
|
||||
}) {
|
||||
final typeInformations =
|
||||
isVirtual
|
||||
? virtualParameterTypeInformations
|
||||
: parameterTypeInformations;
|
||||
final typeInformations = isVirtual
|
||||
? virtualParameterTypeInformations
|
||||
: parameterTypeInformations;
|
||||
return typeInformations.putIfAbsent(parameter, () {
|
||||
ParameterTypeInformation typeInformation = strategy
|
||||
.createParameterTypeInformation(
|
||||
@@ -489,8 +489,9 @@ class TypeSystem {
|
||||
bool isElementInferred = isConst || isTypedArray;
|
||||
|
||||
final inferredLength = isFixed ? length : null;
|
||||
final elementTypeMask =
|
||||
isElementInferred ? elementType.type : dynamicType.type;
|
||||
final elementTypeMask = isElementInferred
|
||||
? elementType.type
|
||||
: dynamicType.type;
|
||||
AbstractValue mask = _abstractValueDomain.createContainerValue(
|
||||
type.type,
|
||||
node,
|
||||
@@ -538,8 +539,9 @@ class TypeSystem {
|
||||
assert(strategy.checkSetNode(node));
|
||||
bool isConst = type.type == _abstractValueDomain.constSetType;
|
||||
|
||||
AbstractValue elementTypeMask =
|
||||
isConst ? elementType.type : dynamicType.type;
|
||||
AbstractValue elementTypeMask = isConst
|
||||
? elementType.type
|
||||
: dynamicType.type;
|
||||
AbstractValue mask = _abstractValueDomain.createSetValue(
|
||||
type.type,
|
||||
node,
|
||||
@@ -577,22 +579,22 @@ class TypeSystem {
|
||||
PhiElementTypeInformation? keyType, valueType;
|
||||
for (int i = 0; i < keyTypes.length; ++i) {
|
||||
final typeForKey = keyTypes[i];
|
||||
keyType =
|
||||
keyType == null
|
||||
? allocatePhi(null, null, typeForKey, isTry: false)
|
||||
: addPhiInput(null, keyType, typeForKey);
|
||||
keyType = keyType == null
|
||||
? allocatePhi(null, null, typeForKey, isTry: false)
|
||||
: addPhiInput(null, keyType, typeForKey);
|
||||
|
||||
final typeForValue = valueTypes[i];
|
||||
valueType =
|
||||
valueType == null
|
||||
? allocatePhi(null, null, typeForValue, isTry: false)
|
||||
: addPhiInput(null, valueType, typeForValue);
|
||||
valueType = valueType == null
|
||||
? allocatePhi(null, null, typeForValue, isTry: false)
|
||||
: addPhiInput(null, valueType, typeForValue);
|
||||
}
|
||||
|
||||
final simplifiedKeyType =
|
||||
keyType == null ? nonNullEmpty() : simplifyPhi(null, null, keyType);
|
||||
final simplifiedValueType =
|
||||
valueType == null ? nonNullEmpty() : simplifyPhi(null, null, valueType);
|
||||
final simplifiedKeyType = keyType == null
|
||||
? nonNullEmpty()
|
||||
: simplifyPhi(null, null, keyType);
|
||||
final simplifiedValueType = valueType == null
|
||||
? nonNullEmpty()
|
||||
: simplifyPhi(null, null, valueType);
|
||||
|
||||
AbstractValue keyTypeMask, valueTypeMask;
|
||||
if (isFixed) {
|
||||
@@ -847,8 +849,9 @@ class TypeSystem {
|
||||
|
||||
AbstractValue? newType;
|
||||
for (AbstractValue mask in list) {
|
||||
newType =
|
||||
newType == null ? mask : _abstractValueDomain.union(newType, mask);
|
||||
newType = newType == null
|
||||
? mask
|
||||
: _abstractValueDomain.union(newType, mask);
|
||||
// Likewise - stop early if we already reach dynamic.
|
||||
if (_abstractValueDomain.containsAll(newType).isPotentiallyTrue) {
|
||||
isTopIgnoringFlags = true;
|
||||
|
||||
@@ -105,10 +105,9 @@ class FlatTypeMask extends TypeMask {
|
||||
CommonMasks domain, {
|
||||
bool hasLateSentinel = false,
|
||||
}) {
|
||||
final powerset =
|
||||
hasLateSentinel
|
||||
? _specialValueDomain.fromValue(TypeMaskSpecialValue.lateSentinel)
|
||||
: Bitset.empty();
|
||||
final powerset = hasLateSentinel
|
||||
? _specialValueDomain.fromValue(TypeMaskSpecialValue.lateSentinel)
|
||||
: Bitset.empty();
|
||||
|
||||
return FlatTypeMask._emptyOrSpecial(domain, powerset);
|
||||
}
|
||||
@@ -117,10 +116,9 @@ class FlatTypeMask extends TypeMask {
|
||||
CommonMasks domain, {
|
||||
bool hasLateSentinel = false,
|
||||
}) {
|
||||
final powerset =
|
||||
hasLateSentinel
|
||||
? _specialValueDomain.allValues
|
||||
: _specialValueDomain.fromValue(TypeMaskSpecialValue.null_);
|
||||
final powerset = hasLateSentinel
|
||||
? _specialValueDomain.allValues
|
||||
: _specialValueDomain.fromValue(TypeMaskSpecialValue.null_);
|
||||
|
||||
return FlatTypeMask._emptyOrSpecial(domain, powerset);
|
||||
}
|
||||
@@ -180,8 +178,9 @@ class FlatTypeMask extends TypeMask {
|
||||
|
||||
final probe = domain._powersetCache[base];
|
||||
final powerset = switch (kind) {
|
||||
FlatTypeMaskKind.empty =>
|
||||
throw StateError('Unexpected empty kind with base $base'),
|
||||
FlatTypeMaskKind.empty => throw StateError(
|
||||
'Unexpected empty kind with base $base',
|
||||
),
|
||||
FlatTypeMaskKind.exact => probe.exact,
|
||||
FlatTypeMaskKind.subclass => probe.subclass,
|
||||
FlatTypeMaskKind.subtype => probe.subtype,
|
||||
@@ -266,10 +265,9 @@ class FlatTypeMask extends TypeMask {
|
||||
@override
|
||||
Bitset get powerset => _getPowerset(_flags);
|
||||
|
||||
ClassQuery get _classQuery =>
|
||||
isExact
|
||||
? ClassQuery.exact
|
||||
: (isSubclass ? ClassQuery.subclass : ClassQuery.subtype);
|
||||
ClassQuery get _classQuery => isExact
|
||||
? ClassQuery.exact
|
||||
: (isSubclass ? ClassQuery.subclass : ClassQuery.subtype);
|
||||
|
||||
@override
|
||||
bool get isEmpty =>
|
||||
@@ -551,11 +549,11 @@ class FlatTypeMask extends TypeMask {
|
||||
// If we weaken the constraint on this type, we have to make sure that
|
||||
// the result is normalized.
|
||||
: FlatTypeMask.normalized(
|
||||
base!,
|
||||
combinedKind,
|
||||
combinedPowerset,
|
||||
domain,
|
||||
);
|
||||
base!,
|
||||
combinedKind,
|
||||
combinedPowerset,
|
||||
domain,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -594,9 +592,9 @@ class FlatTypeMask extends TypeMask {
|
||||
return includeNull
|
||||
? TypeMask.empty(domain, hasLateSentinel: includeLateSentinel)
|
||||
: TypeMask.nonNullEmpty(
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
);
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
);
|
||||
case SimpleSubclassResult.exact1:
|
||||
assert(isExact);
|
||||
return withPowerset(powerset, domain);
|
||||
@@ -620,22 +618,22 @@ class FlatTypeMask extends TypeMask {
|
||||
return includeNull
|
||||
? TypeMask.empty(domain, hasLateSentinel: includeLateSentinel)
|
||||
: TypeMask.nonNullEmpty(
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
);
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
);
|
||||
} else if (classes.length == 1) {
|
||||
ClassEntity cls = classes.first;
|
||||
return includeNull
|
||||
? TypeMask.subclass(
|
||||
cls,
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
)
|
||||
cls,
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
)
|
||||
: TypeMask.nonNullSubclass(
|
||||
cls,
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
);
|
||||
cls,
|
||||
domain,
|
||||
hasLateSentinel: includeLateSentinel,
|
||||
);
|
||||
}
|
||||
|
||||
List<FlatTypeMask> masks = List.from(
|
||||
@@ -692,10 +690,9 @@ class FlatTypeMask extends TypeMask {
|
||||
assert(a.isSubclass || a.isSubtype);
|
||||
assert(b.isSubtype);
|
||||
final aBase = a.base!;
|
||||
var elements =
|
||||
a.isSubclass
|
||||
? closedWorld.classHierarchy.strictSubclassesOf(aBase)
|
||||
: closedWorld.classHierarchy.strictSubtypesOf(aBase);
|
||||
var elements = a.isSubclass
|
||||
? closedWorld.classHierarchy.strictSubclassesOf(aBase)
|
||||
: closedWorld.classHierarchy.strictSubtypesOf(aBase);
|
||||
for (var element in elements) {
|
||||
if (closedWorld.classHierarchy.isSubtypeOf(element, b.base!)) {
|
||||
return false;
|
||||
@@ -882,18 +879,15 @@ class _PowersetCache {
|
||||
final Map<ClassEntity, _CachedPowersets> _cache = {};
|
||||
|
||||
_PowersetCache(this._closedWorld)
|
||||
: _interceptorCone =
|
||||
_closedWorld.classHierarchy
|
||||
.subclassesOf(_closedWorld.commonElements.jsInterceptorClass)
|
||||
.toSet(),
|
||||
_indexableCone =
|
||||
_closedWorld.classHierarchy
|
||||
.subtypesOf(_closedWorld.commonElements.jsIndexableClass)
|
||||
.toSet(),
|
||||
_mutableIndexableCone =
|
||||
_closedWorld.classHierarchy
|
||||
.subtypesOf(_closedWorld.commonElements.jsMutableIndexableClass)
|
||||
.toSet();
|
||||
: _interceptorCone = _closedWorld.classHierarchy
|
||||
.subclassesOf(_closedWorld.commonElements.jsInterceptorClass)
|
||||
.toSet(),
|
||||
_indexableCone = _closedWorld.classHierarchy
|
||||
.subtypesOf(_closedWorld.commonElements.jsIndexableClass)
|
||||
.toSet(),
|
||||
_mutableIndexableCone = _closedWorld.classHierarchy
|
||||
.subtypesOf(_closedWorld.commonElements.jsMutableIndexableClass)
|
||||
.toSet();
|
||||
|
||||
Bitset _computeExactPowerset(ClassEntity cls) {
|
||||
var powerset = Bitset.empty();
|
||||
|
||||
@@ -460,10 +460,9 @@ class CommonMasks with AbstractValueDomain {
|
||||
covariant TypeMask expressionMask,
|
||||
ClassEntity cls,
|
||||
) {
|
||||
final typeMask =
|
||||
(cls == commonElements.nullClass)
|
||||
? nullType
|
||||
: createNonNullSubtype(cls);
|
||||
final typeMask = (cls == commonElements.nullClass)
|
||||
? nullType
|
||||
: createNonNullSubtype(cls);
|
||||
if (expressionMask.union(typeMask, this) == typeMask) {
|
||||
return AbstractBool.true_;
|
||||
} else if (expressionMask.isDisjoint(typeMask, closedWorld)) {
|
||||
@@ -756,11 +755,10 @@ class CommonMasks with AbstractValueDomain {
|
||||
AbstractBool isPrimitiveOrNull(TypeMask value) =>
|
||||
AbstractBool.trueOrMaybe(_isPrimitiveOrNull(value));
|
||||
|
||||
bool _isIndexable(TypeMask value) =>
|
||||
!_indexableDomain.contains(
|
||||
value.powerset,
|
||||
TypeMaskIndexableProperty.notIndexable,
|
||||
);
|
||||
bool _isIndexable(TypeMask value) => !_indexableDomain.contains(
|
||||
value.powerset,
|
||||
TypeMaskIndexableProperty.notIndexable,
|
||||
);
|
||||
|
||||
bool _isIndexablePrimitive(TypeMask value) =>
|
||||
value.containsOnlyString(closedWorld) || _isIndexable(value);
|
||||
@@ -984,8 +982,9 @@ class CommonMasks with AbstractValueDomain {
|
||||
|
||||
@override
|
||||
AbstractValue getDictionaryValueForKey(AbstractValue value, String key) {
|
||||
final result =
|
||||
value is DictionaryTypeMask ? value.getValueForKey(key) : null;
|
||||
final result = value is DictionaryTypeMask
|
||||
? value.getValueForKey(key)
|
||||
: null;
|
||||
return result ?? dynamicType;
|
||||
}
|
||||
|
||||
@@ -1221,12 +1220,11 @@ String formatType(DartTypes dartTypes, TypeMask type) {
|
||||
].join('');
|
||||
}
|
||||
String nullFlag = type.isNullable ? '?' : '';
|
||||
String subFlag =
|
||||
type.isExact
|
||||
? ''
|
||||
: type.isSubclass
|
||||
? '+'
|
||||
: '*';
|
||||
String subFlag = type.isExact
|
||||
? ''
|
||||
: type.isSubclass
|
||||
? '+'
|
||||
: '*';
|
||||
String sentinelFlag = type.hasLateSentinel ? '\$' : '';
|
||||
return '${type.base!.name}$nullFlag$subFlag$sentinelFlag';
|
||||
}
|
||||
|
||||
@@ -374,27 +374,27 @@ class RecordTypeMask extends TypeMask {
|
||||
if (domain.closedWorld.classHierarchy.hasAnyStrictSubclass(recordClass)) {
|
||||
return isNullable
|
||||
? FlatTypeMask.subclass(
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
)
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
)
|
||||
: FlatTypeMask.nonNullSubclass(
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
);
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
);
|
||||
} else {
|
||||
return isNullable
|
||||
? FlatTypeMask.exact(
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
)
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
)
|
||||
: FlatTypeMask.nonNullExact(
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
);
|
||||
recordClass,
|
||||
domain,
|
||||
hasLateSentinel: hasLateSentinel,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -747,13 +747,12 @@ abstract class TypeMask implements AbstractValue {
|
||||
}
|
||||
|
||||
String domainToString(EnumSetDomain domain) {
|
||||
final mnemonics =
|
||||
domain
|
||||
.toEnumSet(powerset)
|
||||
.iterable(domain.values)
|
||||
.toList()
|
||||
.reversed
|
||||
.join();
|
||||
final mnemonics = domain
|
||||
.toEnumSet(powerset)
|
||||
.iterable(domain.values)
|
||||
.toList()
|
||||
.reversed
|
||||
.join();
|
||||
return '{$mnemonics}';
|
||||
}
|
||||
|
||||
|
||||
@@ -105,10 +105,9 @@ class UnionTypeMask extends TypeMask {
|
||||
} else if (mask.isEmpty) {
|
||||
continue;
|
||||
} else {
|
||||
var flatMask =
|
||||
mask is RecordTypeMask
|
||||
? mask.toFlatTypeMask(domain)
|
||||
: mask as FlatTypeMask;
|
||||
var flatMask = mask is RecordTypeMask
|
||||
? mask.toFlatTypeMask(domain)
|
||||
: mask as FlatTypeMask;
|
||||
int inListIndex = -1;
|
||||
bool covered = false;
|
||||
|
||||
|
||||
@@ -205,13 +205,12 @@ class GlobalTypeInferenceTask extends CompilerTask {
|
||||
globalLocalsMap,
|
||||
);
|
||||
} else {
|
||||
final inferrer =
|
||||
typesInferrerInternal ??= compiler.backendStrategy
|
||||
.createTypesInferrer(
|
||||
closedWorld,
|
||||
globalLocalsMap,
|
||||
inferredDataBuilder,
|
||||
);
|
||||
final inferrer = typesInferrerInternal ??= compiler.backendStrategy
|
||||
.createTypesInferrer(
|
||||
closedWorld,
|
||||
globalLocalsMap,
|
||||
inferredDataBuilder,
|
||||
);
|
||||
results = inferrer.analyzeMain(mainElement);
|
||||
_metrics = inferrer.metrics;
|
||||
}
|
||||
@@ -310,8 +309,9 @@ class GlobalTypeInferenceResultsImpl implements GlobalTypeInferenceResults {
|
||||
.readAbstractValueFromDataSource(source),
|
||||
),
|
||||
);
|
||||
Set<Selector> returnsListElementTypeSet =
|
||||
source.readList(() => Selector.readFromDataSource(source)).toSet();
|
||||
Set<Selector> returnsListElementTypeSet = source
|
||||
.readList(() => Selector.readFromDataSource(source))
|
||||
.toSet();
|
||||
Deferrable<Map<ir.TreeNode, AbstractValue>> allocatedLists = source
|
||||
.readDeferrable(
|
||||
(source) => source.readTreeNodeMap(
|
||||
|
||||
@@ -68,8 +68,10 @@ String? computeKernelElementNameForSourceMaps(
|
||||
node = node.parent!;
|
||||
}
|
||||
MemberEntity enclosingMember = elementMap.getMember(node);
|
||||
String enclosingMemberName =
|
||||
computeElementNameForSourceMaps(enclosingMember, callStructure)!;
|
||||
String enclosingMemberName = computeElementNameForSourceMaps(
|
||||
enclosingMember,
|
||||
callStructure,
|
||||
)!;
|
||||
return '$enclosingMemberName.$name';
|
||||
case MemberKind.constructor:
|
||||
case MemberKind.constructorBody:
|
||||
|
||||
@@ -46,15 +46,17 @@ class PositionSourceInformation extends SourceInformation {
|
||||
.readIndexedOrNullNoCache<SourceLocation>(
|
||||
() => SourceLocation.readFromDataSource(source),
|
||||
);
|
||||
List<FrameContext>?
|
||||
inliningContext = source.readIndexedOrNullNoCache<List<FrameContext>>(
|
||||
() =>
|
||||
// FrameContext must be cached since PositionSourceInformation.==
|
||||
// requires identity comparison on the objects in inliningContext.
|
||||
source.readList(
|
||||
() => source.readIndexed(() => FrameContext.readFromDataSource(source)),
|
||||
),
|
||||
);
|
||||
List<FrameContext>? inliningContext = source
|
||||
.readIndexedOrNullNoCache<List<FrameContext>>(
|
||||
() =>
|
||||
// FrameContext must be cached since PositionSourceInformation.==
|
||||
// requires identity comparison on the objects in inliningContext.
|
||||
source.readList(
|
||||
() => source.readIndexed(
|
||||
() => FrameContext.readFromDataSource(source),
|
||||
),
|
||||
),
|
||||
);
|
||||
source.end(tag);
|
||||
return PositionSourceInformation(
|
||||
startPosition,
|
||||
@@ -1161,10 +1163,9 @@ class OnlineJavaScriptTracer extends js.BaseVisitor1Void<int>
|
||||
node,
|
||||
_currentNode,
|
||||
active: _currentNode.active,
|
||||
branchData:
|
||||
branchKind == null
|
||||
? null
|
||||
: _BranchData(branchKind, branchNotificationMode, branchToken),
|
||||
branchData: branchKind == null
|
||||
? null
|
||||
: _BranchData(branchKind, branchNotificationMode, branchToken),
|
||||
statementOffset: statementOffset ?? _currentNode.statementOffset,
|
||||
offsetPositionMode: offsetPositionMode,
|
||||
steps: resetSteps ? [] : _currentNode.steps,
|
||||
@@ -1284,12 +1285,8 @@ class OnlineJavaScriptTracer extends js.BaseVisitor1Void<int>
|
||||
counter: value.counter + 1,
|
||||
position: value.position,
|
||||
),
|
||||
ifAbsent:
|
||||
() => (
|
||||
kind: callPosition.codePositionKind,
|
||||
counter: 1,
|
||||
position: null,
|
||||
),
|
||||
ifAbsent: () =>
|
||||
(kind: callPosition.codePositionKind, counter: 1, position: null),
|
||||
);
|
||||
}
|
||||
_currentNode.addNotifyStep(StepKind.call);
|
||||
@@ -1495,8 +1492,12 @@ class OnlineJavaScriptTracer extends js.BaseVisitor1Void<int>
|
||||
notifyStart(node);
|
||||
|
||||
// Create empty node as root of tree.
|
||||
_rootNode =
|
||||
_currentNode = _PositionInfoNode(node, null, active: false, steps: []);
|
||||
_rootNode = _currentNode = _PositionInfoNode(
|
||||
node,
|
||||
null,
|
||||
active: false,
|
||||
steps: [],
|
||||
);
|
||||
|
||||
Offset startOffset = getOffsetForNode(null, startPosition);
|
||||
notifyStep(node, startOffset, StepKind.noInfo, force: true);
|
||||
|
||||
@@ -147,11 +147,11 @@ class ProtobufImpactHandler implements ConditionalImpactHandler {
|
||||
);
|
||||
late final ir.Procedure _builderInfoAddMethod = _elementMap.env.libraryIndex
|
||||
.getProcedure(protobufLibraryUri, 'BuilderInfo', 'add');
|
||||
late final ir.FunctionType _typeOfBuilderInfoAddOfNull = ir
|
||||
.FunctionTypeInstantiator.instantiate(
|
||||
_builderInfoAddMethod.getterType as ir.FunctionType,
|
||||
const <ir.DartType>[ir.NullType()],
|
||||
);
|
||||
late final ir.FunctionType _typeOfBuilderInfoAddOfNull =
|
||||
ir.FunctionTypeInstantiator.instantiate(
|
||||
_builderInfoAddMethod.getterType as ir.FunctionType,
|
||||
const <ir.DartType>[ir.NullType()],
|
||||
);
|
||||
|
||||
late final ir.Procedure? _builderInfoAddUnusedMethod = _elementMap
|
||||
.env
|
||||
@@ -232,9 +232,9 @@ class ProtobufImpactHandler implements ConditionalImpactHandler {
|
||||
// conditional on the associated field being reachable.
|
||||
return _impactData =
|
||||
interfaceTarget.enclosingClass == _builderInfoClass &&
|
||||
metadataInitializers.contains(node.name.text)
|
||||
? ImpactData()
|
||||
: null;
|
||||
metadataInitializers.contains(node.name.text)
|
||||
? ImpactData()
|
||||
: null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -98,8 +98,9 @@ mixin VariableCollectorMixin {
|
||||
|
||||
void visitInVariableScope(ir.TreeNode root, void Function() f) {
|
||||
VariableScopeImpl? oldScope = currentVariableScope;
|
||||
final newScope =
|
||||
currentVariableScope = variableScopeModel.createScopeFor(root);
|
||||
final newScope = currentVariableScope = variableScopeModel.createScopeFor(
|
||||
root,
|
||||
);
|
||||
oldScope?.addSubScope(newScope);
|
||||
f();
|
||||
currentVariableScope = oldScope;
|
||||
|
||||
@@ -141,8 +141,9 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
|
||||
/// This method should be called in the visit methods of all expressions that
|
||||
/// could potentially be constant to bubble up the constness of expressions.
|
||||
EvaluationComplexity _evaluateImplicitConstant(ir.Expression node) {
|
||||
ir.Constant? constant =
|
||||
(node is ir.ConstantExpression) ? node.constant : null;
|
||||
ir.Constant? constant = (node is ir.ConstantExpression)
|
||||
? node.constant
|
||||
: null;
|
||||
if (constant != null) {
|
||||
return EvaluationComplexity.constant(constant);
|
||||
}
|
||||
@@ -865,10 +866,9 @@ class ScopeModelBuilder extends ir.VisitorDefault<EvaluationComplexity>
|
||||
@override
|
||||
EvaluationComplexity visitFunctionNode(ir.FunctionNode node) {
|
||||
final parent = node.parent;
|
||||
VariableUse parameterUsage =
|
||||
parent is ir.Member
|
||||
? MemberParameterVariableUse(parent)
|
||||
: LocalParameterVariableUse(parent as ir.LocalFunction);
|
||||
VariableUse parameterUsage = parent is ir.Member
|
||||
? MemberParameterVariableUse(parent)
|
||||
: LocalParameterVariableUse(parent as ir.LocalFunction);
|
||||
visitNodesInContext(node.typeParameters, parameterUsage);
|
||||
for (ir.VariableDeclaration declaration in node.positionalParameters) {
|
||||
_handleVariableDeclaration(declaration, parameterUsage);
|
||||
|
||||
@@ -754,10 +754,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
beginLabel(newLabel("Function start"));
|
||||
// AsyncStar needs a return label for its handling of cancellation. See
|
||||
// [visitDartYield].
|
||||
exitLabel =
|
||||
(analysis.hasExplicitReturns || isAsyncStar)
|
||||
? newLabel("return")
|
||||
: null;
|
||||
exitLabel = (analysis.hasExplicitReturns || isAsyncStar)
|
||||
? newLabel("return")
|
||||
: null;
|
||||
handlerLabels[node] = rethrowLabel = newLabel("rethrow");
|
||||
js.Statement body = node.body;
|
||||
jumpTargets.add(node);
|
||||
@@ -836,8 +835,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
js.VariableDeclarationList(variables);
|
||||
|
||||
// Names are already safe when added.
|
||||
List<js.Parameter> typeParameters =
|
||||
typeArgumentNames.map((name) => js.Parameter(name)).toList();
|
||||
List<js.Parameter> typeParameters = typeArgumentNames
|
||||
.map((name) => js.Parameter(name))
|
||||
.toList();
|
||||
return finishFunction(
|
||||
node.params,
|
||||
typeParameters,
|
||||
@@ -968,10 +968,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
int thenLabel = newLabel("then");
|
||||
int joinLabel = newLabel("join");
|
||||
withExpression(node.left, (js.Expression left) {
|
||||
js.Statement assignLeft =
|
||||
isResult(left)
|
||||
? js.Block.empty()
|
||||
: js.js.statement('# = #;', [result, left]);
|
||||
js.Statement assignLeft = isResult(left)
|
||||
? js.Block.empty()
|
||||
: js.js.statement('# = #;', [result, left]);
|
||||
if (node.op == "&&") {
|
||||
addStatement(
|
||||
js.js.statement('if (#) #; else #', [
|
||||
@@ -1240,8 +1239,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
int startLabel = newLabel("for condition");
|
||||
// If there is no update, continuing the loop is the same as going to the
|
||||
// start.
|
||||
int continueLabel =
|
||||
(node.update == null) ? startLabel : newLabel("for update");
|
||||
int continueLabel = (node.update == null)
|
||||
? startLabel
|
||||
: newLabel("for update");
|
||||
continueLabels[node] = continueLabel;
|
||||
int afterLabel = newLabel("after for");
|
||||
breakLabels[node] = afterLabel;
|
||||
@@ -1314,8 +1314,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
}
|
||||
int thenLabel = newLabel("then");
|
||||
int joinLabel = newLabel("join");
|
||||
int elseLabel =
|
||||
(node.otherwise is js.EmptyStatement) ? joinLabel : newLabel("else");
|
||||
int elseLabel = (node.otherwise is js.EmptyStatement)
|
||||
? joinLabel
|
||||
: newLabel("else");
|
||||
|
||||
withExpression(node.condition, (js.Expression condition) {
|
||||
addExpressionStatement(
|
||||
@@ -1571,19 +1572,13 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
bool oldInsideUntranslated = insideUntranslatedBreakable;
|
||||
insideUntranslatedBreakable = true;
|
||||
withExpression(node.key, (js.Expression key) {
|
||||
List<js.SwitchClause> cases =
|
||||
node.cases.map((js.SwitchClause clause) {
|
||||
if (clause is js.Case) {
|
||||
return js.Case(
|
||||
clause.expression,
|
||||
translateToBlock(clause.body),
|
||||
);
|
||||
} else {
|
||||
return js.Default(
|
||||
translateToBlock((clause as js.Default).body),
|
||||
);
|
||||
}
|
||||
}).toList();
|
||||
List<js.SwitchClause> cases = node.cases.map((js.SwitchClause clause) {
|
||||
if (clause is js.Case) {
|
||||
return js.Case(clause.expression, translateToBlock(clause.body));
|
||||
} else {
|
||||
return js.Default(translateToBlock((clause as js.Default).body));
|
||||
}
|
||||
}).toList();
|
||||
addStatement(js.Switch(key, cases));
|
||||
}, store: false);
|
||||
insideUntranslatedBreakable = oldInsideUntranslated;
|
||||
@@ -1691,8 +1686,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
|
||||
void setErrorHandler([int? errorHandler]) {
|
||||
hasHandlerLabels = true; // TODO(sra): Add short form error handler.
|
||||
js.Expression label =
|
||||
(errorHandler == null) ? currentErrorHandler : js.number(errorHandler);
|
||||
js.Expression label = (errorHandler == null)
|
||||
? currentErrorHandler
|
||||
: js.number(errorHandler);
|
||||
addStatement(js.js.statement('# = #;', [handler, label]));
|
||||
}
|
||||
|
||||
@@ -1736,8 +1732,9 @@ abstract class AsyncRewriterBase extends js.NodeVisitor<Object?> {
|
||||
);
|
||||
variableRenamings.removeLast();
|
||||
}
|
||||
js.Block? translatedFinallyPart =
|
||||
(finallyPart == null) ? null : translateToBlock(finallyPart);
|
||||
js.Block? translatedFinallyPart = (finallyPart == null)
|
||||
? null
|
||||
: translateToBlock(finallyPart);
|
||||
addStatement(js.Try(body, translatedCatchPart, translatedFinallyPart));
|
||||
return;
|
||||
}
|
||||
@@ -2057,8 +2054,9 @@ class AsyncRewriter extends AsyncRewriterBase {
|
||||
js.Expression runtimeHelperCall = js
|
||||
.js("#runtimeHelper(#returnValue, #completer)", {
|
||||
"runtimeHelper": asyncReturn,
|
||||
"returnValue":
|
||||
analysis.hasExplicitReturns ? returnValue : js.LiteralNull(),
|
||||
"returnValue": analysis.hasExplicitReturns
|
||||
? returnValue
|
||||
: js.LiteralNull(),
|
||||
"completer": completer,
|
||||
})
|
||||
.withSourceInformation(sourceInformation);
|
||||
@@ -2574,8 +2572,9 @@ class AsyncStarRewriter extends AsyncRewriterBase {
|
||||
);
|
||||
js.Expression yieldExpressionCall = js
|
||||
.js("#yieldExpression(#expression)", {
|
||||
"yieldExpression":
|
||||
node.hasStar ? yieldStarExpression : yieldExpression,
|
||||
"yieldExpression": node.hasStar
|
||||
? yieldStarExpression
|
||||
: yieldExpression,
|
||||
"expression": expression,
|
||||
})
|
||||
.withSourceInformation(sourceInformation);
|
||||
@@ -3260,8 +3259,9 @@ class PreTranslationAnalysis extends js.BaseVisitor<bool> {
|
||||
if (node.finallyPart != null) hasFinally = true;
|
||||
bool body = visit(node.body);
|
||||
bool catchPart = (node.catchPart == null) ? false : visit(node.catchPart!);
|
||||
bool finallyPart =
|
||||
(node.finallyPart == null) ? false : visit(node.finallyPart!);
|
||||
bool finallyPart = (node.finallyPart == null)
|
||||
? false
|
||||
: visit(node.finallyPart!);
|
||||
return body || catchPart || finallyPart;
|
||||
}
|
||||
|
||||
|
||||
@@ -297,19 +297,20 @@ class BackendUsageImpl implements BackendUsage {
|
||||
|
||||
factory BackendUsageImpl.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
Set<FunctionEntity> globalFunctionDependencies =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> globalFunctionDependencies = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<ClassEntity> globalClassDependencies = source.readClasses().toSet();
|
||||
Set<FunctionEntity> helperFunctionsUsed =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> helperFunctionsUsed = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<ClassEntity> helperClassesUsed = source.readClasses().toSet();
|
||||
Set<RuntimeTypeUse> runtimeTypeUses =
|
||||
source.readList(() {
|
||||
RuntimeTypeUseKind kind = source.readEnum(RuntimeTypeUseKind.values);
|
||||
DartType receiverType = source.readDartType();
|
||||
DartType? argumentType = source.readDartTypeOrNull();
|
||||
return RuntimeTypeUse(kind, receiverType, argumentType);
|
||||
}).toSet();
|
||||
Set<RuntimeTypeUse> runtimeTypeUses = source.readList(() {
|
||||
RuntimeTypeUseKind kind = source.readEnum(RuntimeTypeUseKind.values);
|
||||
DartType receiverType = source.readDartType();
|
||||
DartType? argumentType = source.readDartTypeOrNull();
|
||||
return RuntimeTypeUse(kind, receiverType, argumentType);
|
||||
}).toSet();
|
||||
bool needToInitializeIsolateAffinityTag = source.readBool();
|
||||
bool needToInitializeDispatchProperty = source.readBool();
|
||||
bool requiresPreamble = source.readBool();
|
||||
|
||||
@@ -770,8 +770,9 @@ class DeferredHolderExpressionFinalizerImpl
|
||||
|
||||
for (var resource in holderResources) {
|
||||
// Our default names are either 'MAIN,' 'PART<N>', or '<NAME>_C'.
|
||||
var holderName =
|
||||
resource.isMainFragment ? mainResourceName : 'part${resource.name}';
|
||||
var holderName = resource.isMainFragment
|
||||
? mainResourceName
|
||||
: 'part${resource.name}';
|
||||
holderName = holderName.toUpperCase();
|
||||
var holder = Holder(holderName);
|
||||
|
||||
|
||||
@@ -348,8 +348,8 @@ class JFieldAnalysis {
|
||||
}
|
||||
ParameterStructure? invokedParameters =
|
||||
closedWorld.annotationsData.hasNoElision(constructor)
|
||||
? constructor.parameterStructure
|
||||
: constructorUsage.invokedParameters;
|
||||
? constructor.parameterStructure
|
||||
: constructorUsage.invokedParameters;
|
||||
|
||||
Initializer? initializer = data.initializers[constructor];
|
||||
if (initializer == null) {
|
||||
@@ -561,15 +561,14 @@ class JFieldAnalysis {
|
||||
}
|
||||
}
|
||||
|
||||
data =
|
||||
fieldData[jField] = FieldAnalysisData(
|
||||
initialValue: value,
|
||||
isEffectivelyFinal: isEffectivelyFinal,
|
||||
isElided: isElided,
|
||||
isEager: isEager,
|
||||
eagerCreationIndex: creationIndex,
|
||||
eagerFieldDependenciesForTesting: eagerFieldDependencies,
|
||||
);
|
||||
data = fieldData[jField] = FieldAnalysisData(
|
||||
initialValue: value,
|
||||
isEffectivelyFinal: isEffectivelyFinal,
|
||||
isElided: isElided,
|
||||
isEager: isEager,
|
||||
eagerCreationIndex: creationIndex,
|
||||
eagerFieldDependenciesForTesting: eagerFieldDependencies,
|
||||
);
|
||||
}
|
||||
|
||||
currentFields.remove(kField);
|
||||
@@ -665,8 +664,8 @@ class FieldAnalysisData {
|
||||
bool isLateBackingField = source.readBool();
|
||||
bool isEager = source.readBool();
|
||||
int? eagerCreationIndex = source.readIntOrNull();
|
||||
List<FieldEntity>? eagerFieldDependencies =
|
||||
source.readMembersOrNull<FieldEntity>();
|
||||
List<FieldEntity>? eagerFieldDependencies = source
|
||||
.readMembersOrNull<FieldEntity>();
|
||||
source.end(tag);
|
||||
return FieldAnalysisData(
|
||||
initialValue: initialValue,
|
||||
|
||||
@@ -76,8 +76,9 @@ class FrequencyBasedNamer extends Namer
|
||||
return result;
|
||||
}
|
||||
|
||||
List<TokenName> usedNames =
|
||||
tokens.where((TokenName a) => a._rc > 0).toList();
|
||||
List<TokenName> usedNames = tokens
|
||||
.where((TokenName a) => a._rc > 0)
|
||||
.toList();
|
||||
usedNames.sort(compareReferenceCount);
|
||||
for (var token in usedNames) {
|
||||
token.finalize();
|
||||
|
||||
@@ -105,10 +105,12 @@ class InferredDataImpl implements InferredData {
|
||||
Map<FunctionEntity, SideEffects> sideEffects = source.readMemberMap(
|
||||
(MemberEntity member) => SideEffects.readFromDataSource(source),
|
||||
);
|
||||
Set<FunctionEntity> elementsThatCannotThrow =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> functionsThatMightBePassedToApply =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> elementsThatCannotThrow = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<FunctionEntity> functionsThatMightBePassedToApply = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
source.end(tag);
|
||||
return InferredDataImpl(
|
||||
closedWorld,
|
||||
|
||||
@@ -131,8 +131,9 @@ class InterceptorDataImpl implements InterceptorData {
|
||||
interceptedMembers[name] = members;
|
||||
}
|
||||
Set<ClassEntity> interceptedClasses = source.readClasses().toSet();
|
||||
Set<ClassEntity> classesMixedIntoInterceptedClasses =
|
||||
source.readClasses().toSet();
|
||||
Set<ClassEntity> classesMixedIntoInterceptedClasses = source
|
||||
.readClasses()
|
||||
.toSet();
|
||||
source.end(tag);
|
||||
return InterceptorDataImpl(
|
||||
nativeData,
|
||||
@@ -192,16 +193,15 @@ class InterceptorDataImpl implements InterceptorData {
|
||||
AbstractValue? mask,
|
||||
JClosedWorld closedWorld,
|
||||
) {
|
||||
Set<MemberEntity> elements =
|
||||
_interceptedMixinElements[selector.name] ??=
|
||||
(interceptedMembers[selector.name]
|
||||
?.where(
|
||||
(element) => classesMixedIntoInterceptedClasses.contains(
|
||||
element.enclosingClass,
|
||||
),
|
||||
)
|
||||
.toSet() ??
|
||||
const {});
|
||||
Set<MemberEntity> elements = _interceptedMixinElements[selector.name] ??=
|
||||
(interceptedMembers[selector.name]
|
||||
?.where(
|
||||
(element) => classesMixedIntoInterceptedClasses.contains(
|
||||
element.enclosingClass,
|
||||
),
|
||||
)
|
||||
.toSet() ??
|
||||
const {});
|
||||
if (elements.isEmpty) return false;
|
||||
return elements.any((element) {
|
||||
return selector.applies(element) &&
|
||||
@@ -420,8 +420,10 @@ class OneShotInterceptorData {
|
||||
String key = suffixForGetInterceptor(_commonElements, _nativeData, classes);
|
||||
Map<String, OneShotInterceptor> interceptors =
|
||||
_oneShotInterceptors[selector] ??= {};
|
||||
OneShotInterceptor interceptor =
|
||||
interceptors[key] ??= OneShotInterceptor(key, selector);
|
||||
OneShotInterceptor interceptor = interceptors[key] ??= OneShotInterceptor(
|
||||
key,
|
||||
selector,
|
||||
);
|
||||
interceptor.classes.addAll(classes);
|
||||
registerSpecializedGetInterceptor(classes);
|
||||
return namer.nameForOneShotInterceptor(selector, classes);
|
||||
@@ -434,8 +436,8 @@ class OneShotInterceptorData {
|
||||
classes = _interceptorData.interceptedClasses;
|
||||
}
|
||||
String key = suffixForGetInterceptor(_commonElements, _nativeData, classes);
|
||||
SpecializedGetInterceptor interceptor =
|
||||
_specializedGetInterceptors[key] ??= SpecializedGetInterceptor(key);
|
||||
SpecializedGetInterceptor interceptor = _specializedGetInterceptors[key] ??=
|
||||
SpecializedGetInterceptor(key);
|
||||
interceptor.classes.addAll(classes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,20 +419,17 @@ mixin _MinifiedOneShotInterceptorNamer implements Namer {
|
||||
Selector selector,
|
||||
Iterable<ClassEntity> classes,
|
||||
) {
|
||||
final root =
|
||||
selector.isOperator
|
||||
? operatorNameToIdentifier(selector.name)
|
||||
: privateName(selector.memberName);
|
||||
String prefix =
|
||||
selector.isGetter
|
||||
? r"$get"
|
||||
: selector.isSetter
|
||||
? r"$set"
|
||||
: "";
|
||||
String callSuffix =
|
||||
selector.isCall
|
||||
? callSuffixForStructure(selector.callStructure).join()
|
||||
: "";
|
||||
final root = selector.isOperator
|
||||
? operatorNameToIdentifier(selector.name)
|
||||
: privateName(selector.memberName);
|
||||
String prefix = selector.isGetter
|
||||
? r"$get"
|
||||
: selector.isSetter
|
||||
? r"$set"
|
||||
: "";
|
||||
String callSuffix = selector.isCall
|
||||
? callSuffixForStructure(selector.callStructure).join()
|
||||
: "";
|
||||
String suffix = suffixForGetInterceptor(
|
||||
_commonElements,
|
||||
_nativeData,
|
||||
|
||||
@@ -317,8 +317,10 @@ class Namer extends ModularNamer {
|
||||
// Public names are easy.
|
||||
if (!originalName.isPrivate) return text;
|
||||
|
||||
final library =
|
||||
_elementEnvironment.lookupLibrary(originalName.uri!, required: true)!;
|
||||
final library = _elementEnvironment.lookupLibrary(
|
||||
originalName.uri!,
|
||||
required: true,
|
||||
)!;
|
||||
|
||||
// The first library asking for a short private name wins.
|
||||
LibraryEntity owner = shortPrivateNameOwners.putIfAbsent(
|
||||
@@ -704,15 +706,14 @@ class Namer extends ModularNamer {
|
||||
List<String> suffixes = const [],
|
||||
]) {
|
||||
// Build a string encoding the library name, if the name is private.
|
||||
String libraryKey =
|
||||
originalName.isPrivate
|
||||
? _generateLibraryKey(
|
||||
_elementEnvironment.lookupLibrary(
|
||||
originalName.uri!,
|
||||
required: true,
|
||||
)!,
|
||||
).toString()
|
||||
: '';
|
||||
String libraryKey = originalName.isPrivate
|
||||
? _generateLibraryKey(
|
||||
_elementEnvironment.lookupLibrary(
|
||||
originalName.uri!,
|
||||
required: true,
|
||||
)!,
|
||||
).toString()
|
||||
: '';
|
||||
|
||||
// In the unique key, separate the name parts by '@'.
|
||||
// This avoids clashes since the original names cannot contain that symbol.
|
||||
@@ -1091,8 +1092,9 @@ class Namer extends ModularNamer {
|
||||
@override
|
||||
js_ast.Name staticClosureName(FunctionEntity element) {
|
||||
assert(element.isTopLevel || element.isStatic);
|
||||
String enclosing =
|
||||
element.enclosingClass == null ? "" : element.enclosingClass!.name;
|
||||
String enclosing = element.enclosingClass == null
|
||||
? ""
|
||||
: element.enclosingClass!.name;
|
||||
String library = _proposeNameForLibrary(element.library);
|
||||
String name = replaceNonIdentifierCharacters(element.name!);
|
||||
return _disambiguateInternalGlobal(
|
||||
@@ -2268,11 +2270,10 @@ String suffixForGetInterceptor(
|
||||
return cls.name;
|
||||
}
|
||||
|
||||
List<String> names =
|
||||
classes
|
||||
.where((cls) => !nativeData.isNativeOrExtendsNative(cls))
|
||||
.map(abbreviate)
|
||||
.toList();
|
||||
List<String> names = classes
|
||||
.where((cls) => !nativeData.isNativeOrExtendsNative(cls))
|
||||
.map(abbreviate)
|
||||
.toList();
|
||||
// There is one dispatch mechanism for all native classes.
|
||||
if (classes.any((cls) => nativeData.isNativeOrExtendsNative(cls))) {
|
||||
names.add("x");
|
||||
@@ -2696,13 +2697,12 @@ const List<String> reservedGlobalObjectNames = [
|
||||
|
||||
const List<String> reservedGlobalHelperFunctions = ["init"];
|
||||
|
||||
final List<String> userGlobalObjects =
|
||||
List.from(reservedGlobalObjectNames)
|
||||
..remove('C')
|
||||
..remove('H')
|
||||
..remove('J')
|
||||
..remove('P')
|
||||
..remove('W');
|
||||
final List<String> userGlobalObjects = List.from(reservedGlobalObjectNames)
|
||||
..remove('C')
|
||||
..remove('H')
|
||||
..remove('J')
|
||||
..remove('P')
|
||||
..remove('W');
|
||||
|
||||
final RegExp _identifierStartRE = RegExp(r'[A-Za-z_$]');
|
||||
final RegExp _nonIdentifierRE = RegExp(r'[^A-Za-z0-9_$]');
|
||||
|
||||
@@ -509,8 +509,9 @@ class NativeDataBuilder {
|
||||
required bool callthrough,
|
||||
}) {
|
||||
final memberType = environment.getFunctionType(member);
|
||||
final functionType =
|
||||
callthrough ? memberType.returnType as FunctionType : memberType;
|
||||
final functionType = callthrough
|
||||
? memberType.returnType as FunctionType
|
||||
: memberType;
|
||||
return dartTypes.isNonNullable(functionType.returnType);
|
||||
}
|
||||
|
||||
@@ -567,10 +568,9 @@ class NativeDataBuilder {
|
||||
callthrough: member.isGetter && selector.kind == SelectorKind.call,
|
||||
),
|
||||
);
|
||||
data.interopNullChecks[selector] =
|
||||
canCheckInCallee
|
||||
? InteropNullCheckKind.calleeCheck
|
||||
: InteropNullCheckKind.callerCheck;
|
||||
data.interopNullChecks[selector] = canCheckInCallee
|
||||
? InteropNullCheckKind.calleeCheck
|
||||
: InteropNullCheckKind.callerCheck;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -176,16 +176,19 @@ class NoSuchMethodData {
|
||||
/// Deserializes a [NoSuchMethodData] object from [source].
|
||||
factory NoSuchMethodData.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
Set<FunctionEntity> throwingImpls =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> otherImpls =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> forwardingSyntaxImpls =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
List<FunctionEntity> complexNoReturnImpls =
|
||||
source.readMembers<FunctionEntity>();
|
||||
List<FunctionEntity> complexReturningImpls =
|
||||
source.readMembers<FunctionEntity>();
|
||||
Set<FunctionEntity> throwingImpls = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<FunctionEntity> otherImpls = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<FunctionEntity> forwardingSyntaxImpls = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
List<FunctionEntity> complexNoReturnImpls = source
|
||||
.readMembers<FunctionEntity>();
|
||||
List<FunctionEntity> complexReturningImpls = source
|
||||
.readMembers<FunctionEntity>();
|
||||
source.end(tag);
|
||||
return NoSuchMethodData(throwingImpls, otherImpls, forwardingSyntaxImpls)
|
||||
.._complexNoReturnImpls.addAll(complexNoReturnImpls)
|
||||
|
||||
@@ -94,14 +94,13 @@ class TrivialRuntimeTypesChecksBuilder implements RuntimeTypesChecksBuilder {
|
||||
in _closedWorld.classHierarchy
|
||||
.getClassSet(_closedWorld.commonElements.objectClass)
|
||||
.subtypes()) {
|
||||
ClassUse classUse =
|
||||
ClassUse()
|
||||
..directInstance = true
|
||||
..checkedInstance = true
|
||||
..typeArgument = true
|
||||
..checkedTypeArgument = true
|
||||
..typeLiteral = true
|
||||
..functionType = _computeFunctionType(_elementEnvironment, cls);
|
||||
ClassUse classUse = ClassUse()
|
||||
..directInstance = true
|
||||
..checkedInstance = true
|
||||
..typeArgument = true
|
||||
..checkedTypeArgument = true
|
||||
..typeLiteral = true
|
||||
..functionType = _computeFunctionType(_elementEnvironment, cls);
|
||||
classUseMap[cls] = classUse;
|
||||
}
|
||||
TypeChecks typeChecks = _substitutions._computeChecks(classUseMap);
|
||||
@@ -263,8 +262,9 @@ mixin RuntimeTypesSubstitutionsMixin implements RuntimeTypesSubstitutions {
|
||||
);
|
||||
|
||||
// The checks for [checkedClass] inherited for [superClass].
|
||||
TypeCheck? checkFromSuperClass =
|
||||
superChecks != null ? superChecks[checkedClass] : null;
|
||||
TypeCheck? checkFromSuperClass = superChecks != null
|
||||
? superChecks[checkedClass]
|
||||
: null;
|
||||
|
||||
// Whether [cls] need an explicit $isX property for [checkedClass].
|
||||
//
|
||||
@@ -297,8 +297,10 @@ mixin RuntimeTypesSubstitutionsMixin implements RuntimeTypesSubstitutions {
|
||||
} else {
|
||||
// We need a non-trivial substitution function for
|
||||
// [checkedClass].
|
||||
Substitution substitution =
|
||||
computeSubstitution(cls, checkedClass)!;
|
||||
Substitution substitution = computeSubstitution(
|
||||
cls,
|
||||
checkedClass,
|
||||
)!;
|
||||
checks.add(
|
||||
TypeCheck(checkedClass, substitution, needsIs: false),
|
||||
);
|
||||
@@ -321,8 +323,10 @@ mixin RuntimeTypesSubstitutionsMixin implements RuntimeTypesSubstitutions {
|
||||
} else {
|
||||
// We need a non-trivial substitution function for
|
||||
// [checkedClass].
|
||||
Substitution substitution =
|
||||
computeSubstitution(cls, checkedClass)!;
|
||||
Substitution substitution = computeSubstitution(
|
||||
cls,
|
||||
checkedClass,
|
||||
)!;
|
||||
checks.add(
|
||||
TypeCheck(checkedClass, substitution, needsIs: needsIs),
|
||||
);
|
||||
@@ -756,8 +760,8 @@ class RuntimeTypesImpl
|
||||
.getParameterCheckPolicy(method)
|
||||
.isEmitted) {
|
||||
if (_rtiNeed.methodNeedsTypeArguments(method)) {
|
||||
for (TypeVariableType typeVariable in _elementEnvironment
|
||||
.getFunctionTypeVariables(method)) {
|
||||
for (TypeVariableType typeVariable
|
||||
in _elementEnvironment.getFunctionTypeVariables(method)) {
|
||||
DartType bound = _elementEnvironment.getTypeVariableBound(
|
||||
typeVariable.element,
|
||||
);
|
||||
|
||||
@@ -693,10 +693,9 @@ int? indexTypeVariable(
|
||||
// index, even though in the general case it is not at a specific index.
|
||||
|
||||
ClassHierarchy classHierarchy = world.classHierarchy;
|
||||
var test =
|
||||
mustCheckAllSubtypes(world, cls)
|
||||
? classHierarchy.anyStrictSubtypeOf
|
||||
: classHierarchy.anyStrictSubclassOf;
|
||||
var test = mustCheckAllSubtypes(world, cls)
|
||||
? classHierarchy.anyStrictSubtypeOf
|
||||
: classHierarchy.anyStrictSubclassOf;
|
||||
if (test(cls, (ClassEntity subclass) {
|
||||
return !rtiSubstitutions.isTrivialSubstitution(subclass, cls);
|
||||
})) {
|
||||
|
||||
@@ -885,16 +885,21 @@ class RuntimeTypesNeedImpl implements RuntimeTypesNeed {
|
||||
ElementEnvironment elementEnvironment,
|
||||
) {
|
||||
source.begin(tag);
|
||||
Set<ClassEntity> classesNeedingTypeArguments =
|
||||
source.readClasses<ClassEntity>().toSet();
|
||||
Set<FunctionEntity> methodsNeedingSignature =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<FunctionEntity> methodsNeedingTypeArguments =
|
||||
source.readMembers<FunctionEntity>().toSet();
|
||||
Set<Selector> selectorsNeedingTypeArguments =
|
||||
source.readList(() => Selector.readFromDataSource(source)).toSet();
|
||||
Set<int> instantiationsNeedingTypeArguments =
|
||||
source.readList(source.readInt).toSet();
|
||||
Set<ClassEntity> classesNeedingTypeArguments = source
|
||||
.readClasses<ClassEntity>()
|
||||
.toSet();
|
||||
Set<FunctionEntity> methodsNeedingSignature = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<FunctionEntity> methodsNeedingTypeArguments = source
|
||||
.readMembers<FunctionEntity>()
|
||||
.toSet();
|
||||
Set<Selector> selectorsNeedingTypeArguments = source
|
||||
.readList(() => Selector.readFromDataSource(source))
|
||||
.toSet();
|
||||
Set<int> instantiationsNeedingTypeArguments = source
|
||||
.readList(source.readInt)
|
||||
.toSet();
|
||||
source.end(tag);
|
||||
return RuntimeTypesNeedImpl(
|
||||
elementEnvironment,
|
||||
@@ -1130,8 +1135,9 @@ class RuntimeTypesNeedBuilderImpl implements RuntimeTypesNeedBuilder {
|
||||
}
|
||||
|
||||
Set<Local> localFunctions = closedWorld.localFunctions.toSet();
|
||||
Set<FunctionEntity> closurizedMembers =
|
||||
closedWorld.closurizedMembersWithFreeTypeVariables.toSet();
|
||||
Set<FunctionEntity> closurizedMembers = closedWorld
|
||||
.closurizedMembersWithFreeTypeVariables
|
||||
.toSet();
|
||||
|
||||
// Check local functions and closurized members.
|
||||
void checkClosures({required DartType potentialSubtypeOf}) {
|
||||
@@ -1389,10 +1395,9 @@ class RuntimeTypesNeedBuilderImpl implements RuntimeTypesNeedBuilder {
|
||||
Set<ClassEntity> allClassesNeedingRuntimeType;
|
||||
if (neededOnAll) {
|
||||
neededOnFunctions = true;
|
||||
allClassesNeedingRuntimeType =
|
||||
closedWorld.classHierarchy
|
||||
.subclassesOf(commonElements.objectClass)
|
||||
.toSet();
|
||||
allClassesNeedingRuntimeType = closedWorld.classHierarchy
|
||||
.subclassesOf(commonElements.objectClass)
|
||||
.toSet();
|
||||
} else {
|
||||
allClassesNeedingRuntimeType = {};
|
||||
// TODO(johnniwinther): Support this operation directly in
|
||||
|
||||
@@ -266,8 +266,9 @@ class StringReferenceFinalizerImpl implements StringReferenceFinalizer {
|
||||
// Called from collector visitor.
|
||||
void registerStringReference(StringReference node) {
|
||||
StringConstantValue constant = node.constant;
|
||||
_ReferenceSet refs =
|
||||
_referencesByString[constant] ??= _ReferenceSet(constant);
|
||||
_ReferenceSet refs = _referencesByString[constant] ??= _ReferenceSet(
|
||||
constant,
|
||||
);
|
||||
refs.count++;
|
||||
refs._references.add(node);
|
||||
}
|
||||
@@ -290,8 +291,10 @@ class StringReferenceFinalizerImpl implements StringReferenceFinalizer {
|
||||
}
|
||||
}
|
||||
|
||||
List<_ReferenceSet> referenceSetsUsingProperties =
|
||||
_referencesByString.values.where((ref) => !ref.generateAtUse).toList();
|
||||
List<_ReferenceSet> referenceSetsUsingProperties = _referencesByString
|
||||
.values
|
||||
.where((ref) => !ref.generateAtUse)
|
||||
.toList();
|
||||
|
||||
// Sort by string (which is unique and stable) so that similar strings are
|
||||
// grouped together.
|
||||
@@ -363,14 +366,14 @@ class StringReferenceFinalizerImpl implements StringReferenceFinalizer {
|
||||
|
||||
// Step 2. Sort by frequency to arrange common entries have shorter property
|
||||
// names.
|
||||
List<_ReferenceSet> referencesByFrequency =
|
||||
referencesInTable.toList()..sort((a, b) {
|
||||
assert(a.name != b.name);
|
||||
int r = b.count.compareTo(a.count); // Decreasing frequency.
|
||||
if (r != 0) return r;
|
||||
// Tie-break with raw string.
|
||||
return _ReferenceSet.compareByString(a, b);
|
||||
});
|
||||
List<_ReferenceSet> referencesByFrequency = referencesInTable.toList()
|
||||
..sort((a, b) {
|
||||
assert(a.name != b.name);
|
||||
int r = b.count.compareTo(a.count); // Decreasing frequency.
|
||||
if (r != 0) return r;
|
||||
// Tie-break with raw string.
|
||||
return _ReferenceSet.compareByString(a, b);
|
||||
});
|
||||
|
||||
for (final referenceSet in referencesByFrequency) {
|
||||
// TODO(sra): Assess the dispersal of this hash function in the
|
||||
|
||||
@@ -308,8 +308,10 @@ class TypeReferenceFinalizerImpl implements TypeReferenceFinalizer {
|
||||
}
|
||||
}
|
||||
|
||||
List<_ReferenceSet> referenceSetsUsingProperties =
|
||||
_referencesByRecipe.values.where((ref) => !ref.generateAtUse).toList();
|
||||
List<_ReferenceSet> referenceSetsUsingProperties = _referencesByRecipe
|
||||
.values
|
||||
.where((ref) => !ref.generateAtUse)
|
||||
.toList();
|
||||
|
||||
// Sort by name (which is unique and mostly stable) so that similar recipes
|
||||
// are grouped together.
|
||||
@@ -320,8 +322,9 @@ class TypeReferenceFinalizerImpl implements TypeReferenceFinalizer {
|
||||
// Doing so saves 2-3 bytes per entry, but with an overhead of 30+ bytes for
|
||||
// the IIFE. So it is smaller to use the IIFE only for over 10 or so types.
|
||||
const minUseIIFE = 10;
|
||||
final helperLocal =
|
||||
referenceSetsUsingProperties.length < minUseIIFE ? null : 'findType';
|
||||
final helperLocal = referenceSetsUsingProperties.length < minUseIIFE
|
||||
? null
|
||||
: 'findType';
|
||||
|
||||
List<js.Property> properties = [];
|
||||
for (_ReferenceSet referenceSet in referenceSetsUsingProperties) {
|
||||
@@ -431,15 +434,15 @@ class TypeReferenceFinalizerImpl implements TypeReferenceFinalizer {
|
||||
|
||||
// Step 2. Sort by frequency to arrange common entries have shorter property
|
||||
// names.
|
||||
List<_ReferenceSet> referencesByFrequency =
|
||||
referencesInTable.toList()..sort((a, b) {
|
||||
assert(a.name != b.name);
|
||||
int r = b.count.compareTo(a.count); // Decreasing frequency.
|
||||
if (r != 0) return r;
|
||||
return a.name!.compareTo(
|
||||
b.name!,
|
||||
); // Tie-break with characteristic name.
|
||||
});
|
||||
List<_ReferenceSet> referencesByFrequency = referencesInTable.toList()
|
||||
..sort((a, b) {
|
||||
assert(a.name != b.name);
|
||||
int r = b.count.compareTo(a.count); // Decreasing frequency.
|
||||
if (r != 0) return r;
|
||||
return a.name!.compareTo(
|
||||
b.name!,
|
||||
); // Tie-break with characteristic name.
|
||||
});
|
||||
|
||||
for (var referenceSet in referencesByFrequency) {
|
||||
referenceSet.hash = _hashCharacteristicString(referenceSet.name!);
|
||||
|
||||
@@ -180,11 +180,10 @@ class ClassStubGenerator {
|
||||
List.generate(selector.argumentCount, (i) => '\$$i') +
|
||||
List.generate(selector.typeArgumentCount, (i) => '\$T${i + 1}');
|
||||
|
||||
List<js_ast.Expression> argNames =
|
||||
selector.callStructure
|
||||
.getOrderedNamedArguments()
|
||||
.map((String name) => js.string(name))
|
||||
.toList();
|
||||
List<js_ast.Expression> argNames = selector.callStructure
|
||||
.getOrderedNamedArguments()
|
||||
.map((String name) => js.string(name))
|
||||
.toList();
|
||||
|
||||
js_ast.Name methodName = _namer.asName(selector.invocationMirrorMemberName);
|
||||
js_ast.Name internalName = _namer.invocationMirrorInternalName(selector);
|
||||
|
||||
@@ -155,11 +155,10 @@ class InstantiationStubGenerator {
|
||||
FunctionEntity? member,
|
||||
) {
|
||||
// 1. Find the number of type parameters in [instantiationClass].
|
||||
int typeArgumentCount =
|
||||
_closedWorld.dartTypes
|
||||
.getThisType(instantiationClass)
|
||||
.typeArguments
|
||||
.length;
|
||||
int typeArgumentCount = _closedWorld.dartTypes
|
||||
.getThisType(instantiationClass)
|
||||
.typeArguments
|
||||
.length;
|
||||
assert(typeArgumentCount > 0);
|
||||
|
||||
// 2. Find the function field access path.
|
||||
|
||||
@@ -154,10 +154,9 @@ class MetadataCollector implements js_ast.TokenFinalizer {
|
||||
|
||||
js_ast.Expression _addTypeInOutputUnit(DartType type, OutputUnit outputUnit) {
|
||||
final typeMap = _typesMap[outputUnit] ??= {};
|
||||
final metadataEntryList =
|
||||
(typeMap[type] ??= [
|
||||
BoundMetadataEntry(_computeTypeRepresentation(type)),
|
||||
]);
|
||||
final metadataEntryList = (typeMap[type] ??= [
|
||||
BoundMetadataEntry(_computeTypeRepresentation(type)),
|
||||
]);
|
||||
return metadataEntryList.single;
|
||||
}
|
||||
|
||||
|
||||
@@ -138,8 +138,9 @@ class Collector {
|
||||
|
||||
/// Compute all the classes and typedefs that must be emitted.
|
||||
void computeNeededDeclarations() {
|
||||
Set<ClassEntity> backendTypeHelpers =
|
||||
getBackendTypeHelpers(_commonElements).toSet();
|
||||
Set<ClassEntity> backendTypeHelpers = getBackendTypeHelpers(
|
||||
_commonElements,
|
||||
).toSet();
|
||||
|
||||
// Compute needed classes.
|
||||
Set<ClassEntity> instantiatedClasses =
|
||||
@@ -163,11 +164,10 @@ class Collector {
|
||||
addClassesWithSuperclasses(instantiatedClasses);
|
||||
|
||||
// 2. Add all classes used as mixins.
|
||||
Set<ClassEntity> mixinClasses =
|
||||
neededClasses
|
||||
.map(_elementEnvironment.getEffectiveMixinClass)
|
||||
.whereType<ClassEntity>()
|
||||
.toSet();
|
||||
Set<ClassEntity> mixinClasses = neededClasses
|
||||
.map(_elementEnvironment.getEffectiveMixinClass)
|
||||
.whereType<ClassEntity>()
|
||||
.toSet();
|
||||
neededClasses.addAll(mixinClasses);
|
||||
|
||||
// 3. Add classes only needed for their constructors.
|
||||
|
||||
@@ -234,13 +234,12 @@ class ProgramBuilder {
|
||||
}
|
||||
});
|
||||
|
||||
List<Class> nativeClasses =
|
||||
collector.nativeClassesAndSubclasses
|
||||
.map((ClassEntity classElement) => _classes[classElement]!)
|
||||
.toList();
|
||||
List<Class> nativeClasses = collector.nativeClassesAndSubclasses
|
||||
.map((ClassEntity classElement) => _classes[classElement]!)
|
||||
.toList();
|
||||
|
||||
Set<ClassEntity> interceptorClassesNeededByConstants =
|
||||
collector.computeInterceptorsReferencedFromConstants();
|
||||
Set<ClassEntity> interceptorClassesNeededByConstants = collector
|
||||
.computeInterceptorsReferencedFromConstants();
|
||||
|
||||
_unneededNativeClasses = _task.nativeEmitter.prepareNativeClasses(
|
||||
nativeClasses,
|
||||
@@ -509,13 +508,13 @@ class ProgramBuilder {
|
||||
if (stubNames.add(stubName.key)) {
|
||||
final code =
|
||||
_options.interopNullAssertions &&
|
||||
_nativeData.interopNullChecks[selector] ==
|
||||
InteropNullCheckKind.calleeCheck
|
||||
? js.js('function(obj) { return #(obj.#) }', [
|
||||
interopNullAssert,
|
||||
jsName,
|
||||
])
|
||||
: js.js('function(obj) { return obj.# }', [jsName]);
|
||||
_nativeData.interopNullChecks[selector] ==
|
||||
InteropNullCheckKind.calleeCheck
|
||||
? js.js('function(obj) { return #(obj.#) }', [
|
||||
interopNullAssert,
|
||||
jsName,
|
||||
])
|
||||
: js.js('function(obj) { return obj.# }', [jsName]);
|
||||
interceptorClass!.callStubs.add(
|
||||
_buildStubMethod(stubName, code, element: member),
|
||||
);
|
||||
@@ -593,16 +592,16 @@ class ProgramBuilder {
|
||||
// would.
|
||||
final code =
|
||||
_options.interopNullAssertions &&
|
||||
_nativeData.interopNullChecks[selector] ==
|
||||
InteropNullCheckKind.calleeCheck
|
||||
? js.js(
|
||||
'function(receiver, #) { return #(receiver.#(#)) }',
|
||||
[parameters, interopNullAssert, jsName, parameters],
|
||||
)
|
||||
: js.js(
|
||||
'function(receiver, #) { return receiver.#(#) }',
|
||||
[parameters, jsName, parameters],
|
||||
);
|
||||
_nativeData.interopNullChecks[selector] ==
|
||||
InteropNullCheckKind.calleeCheck
|
||||
? js.js(
|
||||
'function(receiver, #) { return #(receiver.#(#)) }',
|
||||
[parameters, interopNullAssert, jsName, parameters],
|
||||
)
|
||||
: js.js(
|
||||
'function(receiver, #) { return receiver.#(#) }',
|
||||
[parameters, jsName, parameters],
|
||||
);
|
||||
interceptorClass!.callStubs.add(
|
||||
_buildStubMethod(stubName, code, element: member),
|
||||
);
|
||||
@@ -625,14 +624,13 @@ class ProgramBuilder {
|
||||
) {
|
||||
String uri = library.canonicalUri.toString();
|
||||
|
||||
List<StaticMethod> statics =
|
||||
memberElements
|
||||
// We omit static stubs here because we use the function bodies directly
|
||||
// when we install the tear offs.
|
||||
.where((e) => e is! FieldEntity && e is! JParameterStub)
|
||||
.cast<FunctionEntity>()
|
||||
.map<StaticMethod>(_buildStaticMethod)
|
||||
.toList();
|
||||
List<StaticMethod> statics = memberElements
|
||||
// We omit static stubs here because we use the function bodies directly
|
||||
// when we install the tear offs.
|
||||
.where((e) => e is! FieldEntity && e is! JParameterStub)
|
||||
.cast<FunctionEntity>()
|
||||
.map<StaticMethod>(_buildStaticMethod)
|
||||
.toList();
|
||||
|
||||
if (library == _commonElements.interceptorsLibrary) {
|
||||
statics.addAll(_generateGetInterceptorMethods());
|
||||
@@ -646,13 +644,11 @@ class ProgramBuilder {
|
||||
)
|
||||
.toList(growable: false);
|
||||
|
||||
List<ClassTypeData> classTypeData =
|
||||
classTypeElements
|
||||
.map(
|
||||
(ClassEntity classTypeElement) =>
|
||||
_classTypeData[classTypeElement]!,
|
||||
)
|
||||
.toList();
|
||||
List<ClassTypeData> classTypeData = classTypeElements
|
||||
.map(
|
||||
(ClassEntity classTypeElement) => _classTypeData[classTypeElement]!,
|
||||
)
|
||||
.toList();
|
||||
classTypeData.addAll(classes.map((Class cls) => cls.typeData).toList());
|
||||
|
||||
return Library(library, uri, statics, classes, classTypeData);
|
||||
@@ -741,8 +737,8 @@ class ProgramBuilder {
|
||||
|
||||
if (_backendUsage.isNoSuchMethodUsed &&
|
||||
cls == _commonElements.objectClass) {
|
||||
Map<js.Name, Selector> selectors =
|
||||
classStubGenerator.computeSelectorsForNsmHandlers();
|
||||
Map<js.Name, Selector> selectors = classStubGenerator
|
||||
.computeSelectorsForNsmHandlers();
|
||||
selectors.forEach((js.Name name, Selector selector) {
|
||||
// If the program contains `const Symbol` names we have to retain them.
|
||||
String selectorName = selector.name;
|
||||
@@ -794,25 +790,20 @@ class ProgramBuilder {
|
||||
}
|
||||
}
|
||||
bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
|
||||
List<Field> instanceFields =
|
||||
onlyForConstructorOrRti
|
||||
? const []
|
||||
: _buildFields(
|
||||
cls: cls,
|
||||
isHolderInterceptedClass: isInterceptedClass,
|
||||
);
|
||||
List<Field> instanceFields = onlyForConstructorOrRti
|
||||
? const []
|
||||
: _buildFields(cls: cls, isHolderInterceptedClass: isInterceptedClass);
|
||||
|
||||
List<StubMethod> gettersSetters =
|
||||
onlyForConstructorOrRti
|
||||
? const []
|
||||
: [
|
||||
for (Field field in instanceFields)
|
||||
if (field.needsGetter)
|
||||
classStubGenerator.generateGetter(field) as StubMethod,
|
||||
for (Field field in instanceFields)
|
||||
if (field.needsUncheckedSetter)
|
||||
classStubGenerator.generateSetter(field) as StubMethod,
|
||||
];
|
||||
List<StubMethod> gettersSetters = onlyForConstructorOrRti
|
||||
? const []
|
||||
: [
|
||||
for (Field field in instanceFields)
|
||||
if (field.needsGetter)
|
||||
classStubGenerator.generateGetter(field) as StubMethod,
|
||||
for (Field field in instanceFields)
|
||||
if (field.needsUncheckedSetter)
|
||||
classStubGenerator.generateSetter(field) as StubMethod,
|
||||
];
|
||||
|
||||
TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(
|
||||
cls,
|
||||
@@ -915,18 +906,17 @@ class ProgramBuilder {
|
||||
);
|
||||
|
||||
void associateNamedTypeVariables() {
|
||||
for (TypeVariableType typeVariable in _codegenWorld.namedTypeVariables
|
||||
.union(_lateNamedTypeVariables)) {
|
||||
for (TypeVariableType typeVariable
|
||||
in _codegenWorld.namedTypeVariables.union(_lateNamedTypeVariables)) {
|
||||
final declaration = typeVariable.element.typeDeclaration as ClassEntity;
|
||||
Iterable<ClassEntity> subtypes =
|
||||
new_rti.mustCheckAllSubtypes(_closedWorld, declaration)
|
||||
? _classHierarchy.subtypesOf(declaration)
|
||||
: _classHierarchy.subclassesOf(declaration);
|
||||
? _classHierarchy.subtypesOf(declaration)
|
||||
: _classHierarchy.subclassesOf(declaration);
|
||||
for (ClassEntity entity in subtypes) {
|
||||
ClassTypeData classTypeData =
|
||||
_nativeData.isJsInteropClass(entity)
|
||||
? _buildClassTypeData(_jsInteropInterceptor)
|
||||
: _buildClassTypeData(entity);
|
||||
ClassTypeData classTypeData = _nativeData.isJsInteropClass(entity)
|
||||
? _buildClassTypeData(_jsInteropInterceptor)
|
||||
: _buildClassTypeData(entity);
|
||||
classTypeData.namedTypeVariables.add(typeVariable);
|
||||
}
|
||||
}
|
||||
@@ -989,10 +979,9 @@ class ProgramBuilder {
|
||||
|
||||
bool canBeApplied = _methodCanBeApplied(element);
|
||||
|
||||
final aliasName =
|
||||
_codegenWorld.isAliasedSuperMember(element)
|
||||
? _namer.aliasedSuperMemberPropertyName(element)
|
||||
: null;
|
||||
final aliasName = _codegenWorld.isAliasedSuperMember(element)
|
||||
? _namer.aliasedSuperMemberPropertyName(element)
|
||||
: null;
|
||||
|
||||
if (isNotApplyTarget) {
|
||||
canTearOff = false;
|
||||
@@ -1365,13 +1354,13 @@ class ProgramBuilder {
|
||||
final stubMethods = _codegenWorld
|
||||
.getParameterStubs(element)
|
||||
.map((stub) {
|
||||
final name =
|
||||
element.isStatic ? null : _namer.instanceMethodName(stub);
|
||||
final name = element.isStatic
|
||||
? null
|
||||
: _namer.instanceMethodName(stub);
|
||||
final callSelector = stub.callSelector;
|
||||
final callName =
|
||||
(callSelector != null)
|
||||
? _namer.invocationName(callSelector)
|
||||
: null;
|
||||
final callName = (callSelector != null)
|
||||
? _namer.invocationName(callSelector)
|
||||
: null;
|
||||
final stubCode = _generatedCode[stub]!;
|
||||
return ParameterStubMethod(
|
||||
name,
|
||||
|
||||
@@ -105,10 +105,9 @@ class Registry {
|
||||
LibrariesMap _mapUnitToLibrariesMap(OutputUnit targetUnit) {
|
||||
if (targetUnit == _lastOutputUnit) return _lastLibrariesMap;
|
||||
|
||||
final result =
|
||||
(targetUnit == _mainOutputUnit)
|
||||
? mainLibrariesMap
|
||||
: _deferredLibrariesMap[targetUnit]!;
|
||||
final result = (targetUnit == _mainOutputUnit)
|
||||
? mainLibrariesMap
|
||||
: _deferredLibrariesMap[targetUnit]!;
|
||||
|
||||
_lastOutputUnit = targetUnit;
|
||||
_lastLibrariesMap = result;
|
||||
|
||||
@@ -110,8 +110,8 @@ class ResourceInfoCollector {
|
||||
'_comment': r'Resources referenced by annotated resource identifers',
|
||||
'AppTag': 'TBD',
|
||||
'environment': environment,
|
||||
'identifiers':
|
||||
_identifierMap.values.toList()..sort(_ResourceIdentifierInfo.compare),
|
||||
'identifiers': _identifierMap.values.toList()
|
||||
..sort(_ResourceIdentifierInfo.compare),
|
||||
};
|
||||
return json;
|
||||
}
|
||||
@@ -144,8 +144,8 @@ class _ResourceIdentifierInfo {
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final files =
|
||||
_files.entries.toList()..sort((a, b) => a.key.compareTo(b.key));
|
||||
final files = _files.entries.toList()
|
||||
..sort((a, b) => a.key.compareTo(b.key));
|
||||
return {
|
||||
"name": _key.name,
|
||||
"uri": _key.uri.toString(),
|
||||
|
||||
@@ -33,7 +33,8 @@ part of 'model_emitter.dart';
|
||||
// JavaScript variables (like `Array`) we are free to chose whatever variable
|
||||
// names we want. Furthermore, the pretty-printer minifies local variables, thus
|
||||
// reducing their size.
|
||||
const String _mainBoilerplate = '''
|
||||
const String _mainBoilerplate =
|
||||
'''
|
||||
(function dartProgram() {
|
||||
|
||||
if (#startupMetrics) {
|
||||
@@ -893,8 +894,9 @@ class FragmentEmitter {
|
||||
js.quoteName(key),
|
||||
value as js.Fun,
|
||||
);
|
||||
final Entity holderKey =
|
||||
method is StaticStubMethod ? method.library : method.element!;
|
||||
final Entity holderKey = method is StaticStubMethod
|
||||
? method.library
|
||||
: method.element!;
|
||||
assert(
|
||||
method is! StaticStubMethod ||
|
||||
method.library == _commonElements.interceptorsLibrary,
|
||||
@@ -1099,10 +1101,9 @@ class FragmentEmitter {
|
||||
js.Expression name,
|
||||
js.Expression code,
|
||||
) {
|
||||
js.Property property =
|
||||
code is js.Fun
|
||||
? js.MethodDefinition(name, code)
|
||||
: js.Property(name, code);
|
||||
js.Property property = code is js.Fun
|
||||
? js.MethodDefinition(name, code)
|
||||
: js.Property(name, code);
|
||||
registerEntityAst(method.element, property);
|
||||
properties.add(property);
|
||||
});
|
||||
@@ -1185,10 +1186,9 @@ class FragmentEmitter {
|
||||
|
||||
// Avoid adding the metadata if a superclass has the same metadata.
|
||||
if (!method.inheritsApplyMetadata) {
|
||||
final applyName =
|
||||
method.applyIndex == 0
|
||||
? method.name!
|
||||
: method.parameterStubs[method.applyIndex - 1].name!;
|
||||
final applyName = method.applyIndex == 0
|
||||
? method.name!
|
||||
: method.parameterStubs[method.applyIndex - 1].name!;
|
||||
properties[js.string(_namer.fixedNames.callCatchAllName)] = js
|
||||
.quoteName(applyName);
|
||||
properties[js.string(_namer.fixedNames.requiredParameterField)] = js
|
||||
@@ -1259,8 +1259,9 @@ class FragmentEmitter {
|
||||
}
|
||||
|
||||
subclasses.forEach((superclass, list) {
|
||||
js.Expression superclassReference =
|
||||
(superclass == null) ? js.LiteralNull() : classReference(superclass);
|
||||
js.Expression superclassReference = (superclass == null)
|
||||
? js.LiteralNull()
|
||||
: classReference(superclass);
|
||||
if (list.length == 1) {
|
||||
Class cls = list.single;
|
||||
var statement = js.js.statement('#(#, #)', [
|
||||
@@ -1621,8 +1622,9 @@ class FragmentEmitter {
|
||||
}
|
||||
}
|
||||
for (Class cls in library.classes) {
|
||||
var methods =
|
||||
cls.methods.where((m) => (m as DartMethod).needsTearOff).toList();
|
||||
var methods = cls.methods
|
||||
.where((m) => (m as DartMethod).needsTearOff)
|
||||
.toList();
|
||||
js.Expression container = js.js("#.prototype", classReference(cls));
|
||||
js.Expression? reference = container;
|
||||
if (methods.length > 1) {
|
||||
@@ -1750,10 +1752,9 @@ class FragmentEmitter {
|
||||
List<js.Statement> statements = [];
|
||||
LocalAliases locals = LocalAliases();
|
||||
for (StaticField field in fields) {
|
||||
String helper =
|
||||
field.isFinal
|
||||
? locals.find('_lazyFinal', 'hunkHelpers.lazyFinal')
|
||||
: locals.find('_lazy', 'hunkHelpers.lazy');
|
||||
String helper = field.isFinal
|
||||
? locals.find('_lazyFinal', 'hunkHelpers.lazyFinal')
|
||||
: locals.find('_lazy', 'hunkHelpers.lazy');
|
||||
js.Expression staticFieldCode = field.code;
|
||||
if (staticFieldCode is js.Fun) {
|
||||
// An arrow function `() => { ...; return e }` is smaller that
|
||||
@@ -2147,14 +2148,13 @@ class FragmentEmitter {
|
||||
ruleset.addRedirection(element, legacyJsObjectClass);
|
||||
} else {
|
||||
Iterable<TypeCheck> checks = typeData.classChecks.checks;
|
||||
Iterable<InterfaceType> supertypes =
|
||||
isInterop
|
||||
? checks.map(
|
||||
(check) => _elementEnvironment.getJsInteropType(check.cls),
|
||||
)
|
||||
: checks.map(
|
||||
(check) => _dartTypes.asInstanceOf(targetType, check.cls)!,
|
||||
);
|
||||
Iterable<InterfaceType> supertypes = isInterop
|
||||
? checks.map(
|
||||
(check) => _elementEnvironment.getJsInteropType(check.cls),
|
||||
)
|
||||
: checks.map(
|
||||
(check) => _dartTypes.asInstanceOf(targetType, check.cls)!,
|
||||
);
|
||||
|
||||
Map<TypeVariableType, DartType> typeVariables = {};
|
||||
Set<TypeVariableType> namedTypeVariables = typeData.namedTypeVariables;
|
||||
@@ -2164,10 +2164,9 @@ class FragmentEmitter {
|
||||
for (TypeVariableType typeVariable in typeData.namedTypeVariables) {
|
||||
TypeVariableEntity element = typeVariable.element;
|
||||
final typeDeclaration = element.typeDeclaration as ClassEntity;
|
||||
final supertype =
|
||||
isInterop
|
||||
? _elementEnvironment.getJsInteropType(typeDeclaration)
|
||||
: _dartTypes.asInstanceOf(targetType, typeDeclaration)!;
|
||||
final supertype = isInterop
|
||||
? _elementEnvironment.getJsInteropType(typeDeclaration)
|
||||
: _dartTypes.asInstanceOf(targetType, typeDeclaration)!;
|
||||
List<DartType> supertypeArguments = supertype.typeArguments;
|
||||
typeVariables[typeVariable] = supertypeArguments[element.index];
|
||||
}
|
||||
|
||||
@@ -281,10 +281,9 @@ class PreFragment {
|
||||
Map<OutputUnit, CodeFragment> outputUnitMap,
|
||||
Map<CodeFragment, FinalizedFragment> codeFragmentMap,
|
||||
) {
|
||||
List<CodeFragment> codeFragments =
|
||||
shouldInterleave
|
||||
? [interleaveEmittedOutputUnits(program)]
|
||||
: bundleEmittedOutputUnits(program);
|
||||
List<CodeFragment> codeFragments = shouldInterleave
|
||||
? [interleaveEmittedOutputUnits(program)]
|
||||
: bundleEmittedOutputUnits(program);
|
||||
finalizedFragment = FinalizedFragment(outputFileName, codeFragments);
|
||||
for (var codeFragment in codeFragments) {
|
||||
codeFragmentMap[codeFragment] = finalizedFragment;
|
||||
@@ -698,19 +697,18 @@ class FragmentMerger {
|
||||
},
|
||||
);
|
||||
|
||||
List<String> partFileNames =
|
||||
fragments
|
||||
.map(
|
||||
(fragment) => deferredPartFileName(
|
||||
_options,
|
||||
fragment.canonicalOutputUnit.name,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
List<String> partFileNames = fragments
|
||||
.map(
|
||||
(fragment) => deferredPartFileName(
|
||||
_options,
|
||||
fragment.canonicalOutputUnit.name,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
(libraryMap['imports'] as Map<String, List<String>>)[importDeferName] =
|
||||
partFileNames;
|
||||
(libraryMap['importPrefixToLoadId'] as Map<String, String>)[import
|
||||
.name!] =
|
||||
(libraryMap['importPrefixToLoadId']
|
||||
as Map<String, String>)[import.name!] =
|
||||
importDeferName;
|
||||
}
|
||||
return mapping;
|
||||
|
||||
@@ -478,12 +478,12 @@ class ClosureDataBuilder {
|
||||
KernelCapturedScope signatureCapturedScope =
|
||||
KernelCapturedScope.forSignature(capturedScope);
|
||||
_updateScopeBasedOnRtiNeed(signatureCapturedScope, rtiNeed, member);
|
||||
_capturedScopeForSignatureMap[closureClassInfo
|
||||
.signatureMethod!] = JsCapturedScope.from(
|
||||
{},
|
||||
signatureCapturedScope,
|
||||
member.enclosingClass,
|
||||
);
|
||||
_capturedScopeForSignatureMap[closureClassInfo.signatureMethod!] =
|
||||
JsCapturedScope.from(
|
||||
{},
|
||||
signatureCapturedScope,
|
||||
member.enclosingClass,
|
||||
);
|
||||
}
|
||||
}
|
||||
callMethods.add(closureClassInfo.callMethod!);
|
||||
@@ -633,8 +633,8 @@ class JsScopeInfo extends ScopeInfo {
|
||||
|
||||
factory JsScopeInfo.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
|
||||
source.readTreeNodes<ir.VariableDeclaration>();
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync = source
|
||||
.readTreeNodes<ir.VariableDeclaration>();
|
||||
Local? thisLocal = source.readLocalOrNull();
|
||||
Map<ir.VariableDeclaration, JContextField> boxedVariables = source
|
||||
.readTreeNodeMap<ir.VariableDeclaration, JContextField>(
|
||||
@@ -679,8 +679,9 @@ class JsCapturedScope extends JsScopeInfo implements CapturedScope {
|
||||
super.boxedVariables,
|
||||
super.capturedScope,
|
||||
super.enclosingClass,
|
||||
) : contextBox =
|
||||
boxedVariables.isNotEmpty ? boxedVariables.values.first.box : null,
|
||||
) : contextBox = boxedVariables.isNotEmpty
|
||||
? boxedVariables.values.first.box
|
||||
: null,
|
||||
super.from();
|
||||
|
||||
@override
|
||||
@@ -688,8 +689,8 @@ class JsCapturedScope extends JsScopeInfo implements CapturedScope {
|
||||
|
||||
factory JsCapturedScope.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
|
||||
source.readTreeNodes<ir.VariableDeclaration>();
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync = source
|
||||
.readTreeNodes<ir.VariableDeclaration>();
|
||||
Local? thisLocal = source.readLocalOrNull();
|
||||
Map<ir.VariableDeclaration, JContextField> boxedVariables = source
|
||||
.readTreeNodeMap<ir.VariableDeclaration, JContextField>(
|
||||
@@ -744,16 +745,16 @@ class JsCapturedLoopScope extends JsCapturedScope implements CapturedLoopScope {
|
||||
|
||||
factory JsCapturedLoopScope.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
|
||||
source.readTreeNodes<ir.VariableDeclaration>();
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync = source
|
||||
.readTreeNodes<ir.VariableDeclaration>();
|
||||
Local? thisLocal = source.readLocalOrNull();
|
||||
Map<ir.VariableDeclaration, JContextField> boxedVariables = source
|
||||
.readTreeNodeMap<ir.VariableDeclaration, JContextField>(
|
||||
() => source.readMember() as JContextField,
|
||||
);
|
||||
Local? context = source.readLocalOrNull();
|
||||
List<ir.VariableDeclaration> boxedLoopVariables =
|
||||
source.readTreeNodes<ir.VariableDeclaration>();
|
||||
List<ir.VariableDeclaration> boxedLoopVariables = source
|
||||
.readTreeNodes<ir.VariableDeclaration>();
|
||||
source.end(tag);
|
||||
return JsCapturedLoopScope.internal(
|
||||
localsUsedInTryOrSync,
|
||||
@@ -844,8 +845,8 @@ class JsClosureClassInfo extends JsScopeInfo
|
||||
|
||||
factory JsClosureClassInfo.readFromDataSource(DataSourceReader source) {
|
||||
source.begin(tag);
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync =
|
||||
source.readTreeNodes<ir.VariableDeclaration>();
|
||||
Iterable<ir.VariableDeclaration> localsUsedInTryOrSync = source
|
||||
.readTreeNodes<ir.VariableDeclaration>();
|
||||
Local? thisLocal = source.readLocalOrNull();
|
||||
Map<ir.VariableDeclaration, JContextField> boxedVariables = source
|
||||
.readTreeNodeMap<ir.VariableDeclaration, JContextField>(
|
||||
|
||||
@@ -468,10 +468,9 @@ class SpecialMemberDefinition implements MemberDefinition {
|
||||
: _node = Deferrable.eager(node);
|
||||
|
||||
SpecialMemberDefinition.from(MemberDefinition baseMember, this.kind)
|
||||
: _node =
|
||||
baseMember is ClosureMemberDefinition
|
||||
? baseMember._node
|
||||
: Deferrable.eager(baseMember.node as ir.TreeNode);
|
||||
: _node = baseMember is ClosureMemberDefinition
|
||||
? baseMember._node
|
||||
: Deferrable.eager(baseMember.node as ir.TreeNode);
|
||||
|
||||
SpecialMemberDefinition._deserialized(this._node, this.kind);
|
||||
|
||||
|
||||
@@ -615,8 +615,10 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
if (data is JClassDataImpl && data.thisType == null) {
|
||||
ir.Class node = data.cls;
|
||||
if (node.typeParameters.isEmpty) {
|
||||
data.thisType =
|
||||
data.rawType = types.interfaceType(cls, const <DartType>[]);
|
||||
data.thisType = data.rawType = types.interfaceType(
|
||||
cls,
|
||||
const <DartType>[],
|
||||
);
|
||||
} else {
|
||||
data.thisType = types.interfaceType(
|
||||
cls,
|
||||
@@ -696,11 +698,10 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
Set<InterfaceType> canonicalSupertypes = {};
|
||||
|
||||
InterfaceType processSupertype(ir.Supertype supertypeNode) {
|
||||
supertypeNode =
|
||||
classHierarchy.getClassAsInstanceOf(
|
||||
node,
|
||||
supertypeNode.classNode,
|
||||
)!;
|
||||
supertypeNode = classHierarchy.getClassAsInstanceOf(
|
||||
node,
|
||||
supertypeNode.classNode,
|
||||
)!;
|
||||
InterfaceType supertype = _typeConverter.visitSupertype(
|
||||
supertypeNode,
|
||||
);
|
||||
@@ -759,10 +760,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
cls,
|
||||
nativeData,
|
||||
);
|
||||
InterfaceType defaultSupertype =
|
||||
data.supertype = _elementEnvironment.getRawType(
|
||||
defaultSuperclass,
|
||||
);
|
||||
InterfaceType defaultSupertype = data.supertype = _elementEnvironment
|
||||
.getRawType(defaultSuperclass);
|
||||
assert(
|
||||
defaultSupertype.typeArguments.isEmpty,
|
||||
"Generic default supertypes are not supported",
|
||||
@@ -1305,8 +1304,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
// library.
|
||||
// TODO(johnniwinther): Cache more results to avoid redundant lookups?
|
||||
cachedMayLookupInMain ??=
|
||||
// Tests permit lookup outside of dart: libraries.
|
||||
allowedNativeTest(elementEnvironment.mainLibrary!.canonicalUri);
|
||||
// Tests permit lookup outside of dart: libraries.
|
||||
allowedNativeTest(elementEnvironment.mainLibrary!.canonicalUri);
|
||||
DartType? type;
|
||||
if (cachedMayLookupInMain!) {
|
||||
type ??= findInLibrary(elementEnvironment.mainLibrary);
|
||||
@@ -1537,8 +1536,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
@override
|
||||
Spannable getSpannable(MemberEntity member, ir.Node node) =>
|
||||
node is ir.TreeNode
|
||||
? computeSourceSpanFromTreeNode(node)
|
||||
: getSourceSpan(member, null);
|
||||
? computeSourceSpanFromTreeNode(node)
|
||||
: getSourceSpan(member, null);
|
||||
|
||||
Iterable<LibraryEntity> get libraryListInternal {
|
||||
return libraryMap.values;
|
||||
@@ -1565,8 +1564,9 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
int index = declaration.typeParameters.indexOf(node);
|
||||
if (declaration.kind == ir.ProcedureKind.Factory) {
|
||||
ir.Class cls = declaration.enclosingClass!;
|
||||
typeVariableMap[node] =
|
||||
typeVariable = getTypeVariableInternal(cls.typeParameters[index]);
|
||||
typeVariableMap[node] = typeVariable = getTypeVariableInternal(
|
||||
cls.typeParameters[index],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1754,10 +1754,9 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
);
|
||||
classes.register(container, containerData, ContextEnv(memberMap));
|
||||
|
||||
InterfaceType? memberThisType =
|
||||
member.enclosingClass != null
|
||||
? elementEnvironment.getThisType(member.enclosingClass!)
|
||||
: null;
|
||||
InterfaceType? memberThisType = member.enclosingClass != null
|
||||
? elementEnvironment.getThisType(member.enclosingClass!)
|
||||
: null;
|
||||
for (ir.VariableDeclaration variable in info.boxedVariables) {
|
||||
boxedFields[variable] = _constructContextFieldEntry(
|
||||
memberThisType,
|
||||
@@ -1804,12 +1803,12 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
InterfaceType supertype, {
|
||||
required bool createSignatureMethod,
|
||||
}) {
|
||||
InterfaceType? memberThisType =
|
||||
member.enclosingClass != null
|
||||
? elementEnvironment.getThisType(member.enclosingClass!)
|
||||
: null;
|
||||
ClassTypeVariableAccess typeVariableAccess =
|
||||
members.getData(member as JMember).classTypeVariableAccess;
|
||||
InterfaceType? memberThisType = member.enclosingClass != null
|
||||
? elementEnvironment.getThisType(member.enclosingClass!)
|
||||
: null;
|
||||
ClassTypeVariableAccess typeVariableAccess = members
|
||||
.getData(member as JMember)
|
||||
.classTypeVariableAccess;
|
||||
if (typeVariableAccess == ClassTypeVariableAccess.instanceField) {
|
||||
// A closure in a field initializer will only be executed in the
|
||||
// constructor and type variables are therefore accessed through
|
||||
@@ -2090,8 +2089,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
|
||||
typeVariableAccess,
|
||||
),
|
||||
);
|
||||
memberMap[signatureMethod.memberName] =
|
||||
closureClassInfo.signatureMethod = signatureMethod;
|
||||
memberMap[signatureMethod.memberName] = closureClassInfo.signatureMethod =
|
||||
signatureMethod;
|
||||
}
|
||||
|
||||
JField _constructClosureField(
|
||||
|
||||
@@ -714,20 +714,19 @@ mixin FunctionDataTypeVariablesMixin implements FunctionData {
|
||||
parent.kind == ir.ProcedureKind.Factory)) {
|
||||
_typeVariables = const <TypeVariableType>[];
|
||||
} else {
|
||||
_typeVariables =
|
||||
functionNode.typeParameters.map<TypeVariableType>((
|
||||
ir.TypeParameter typeParameter,
|
||||
) {
|
||||
return elementMap
|
||||
.getDartType(
|
||||
ir.TypeParameterType(
|
||||
typeParameter,
|
||||
ir.Nullability.nonNullable,
|
||||
),
|
||||
)
|
||||
.withoutNullability
|
||||
as TypeVariableType;
|
||||
}).toList();
|
||||
_typeVariables = functionNode.typeParameters.map<TypeVariableType>((
|
||||
ir.TypeParameter typeParameter,
|
||||
) {
|
||||
return elementMap
|
||||
.getDartType(
|
||||
ir.TypeParameterType(
|
||||
typeParameter,
|
||||
ir.Nullability.nonNullable,
|
||||
),
|
||||
)
|
||||
.withoutNullability
|
||||
as TypeVariableType;
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,10 +226,9 @@ class JsBackendStrategy {
|
||||
GlobalTypeInferenceResults globalTypeInferenceResults,
|
||||
) {
|
||||
JClosedWorld closedWorld = globalTypeInferenceResults.closedWorld;
|
||||
FixedNames fixedNames =
|
||||
_compiler.options.enableMinification
|
||||
? const MinifiedFixedNames()
|
||||
: const FixedNames();
|
||||
FixedNames fixedNames = _compiler.options.enableMinification
|
||||
? const MinifiedFixedNames()
|
||||
: const FixedNames();
|
||||
|
||||
Tracer tracer = Tracer(
|
||||
closedWorld,
|
||||
@@ -239,8 +238,9 @@ class JsBackendStrategy {
|
||||
|
||||
RuntimeTypesSubstitutions rtiSubstitutions;
|
||||
if (_compiler.options.disableRtiOptimization) {
|
||||
final trivialSubs =
|
||||
rtiSubstitutions = TrivialRuntimeTypesSubstitutions(closedWorld);
|
||||
final trivialSubs = rtiSubstitutions = TrivialRuntimeTypesSubstitutions(
|
||||
closedWorld,
|
||||
);
|
||||
_rtiChecksBuilder = TrivialRuntimeTypesChecksBuilder(
|
||||
closedWorld,
|
||||
trivialSubs,
|
||||
@@ -341,12 +341,11 @@ class JsBackendStrategy {
|
||||
closedWorld.nativeData,
|
||||
);
|
||||
FixedNames fixedNames = codegen.fixedNames;
|
||||
_namer =
|
||||
_compiler.options.enableMinification
|
||||
? _compiler.options.useFrequencyNamer
|
||||
? FrequencyBasedNamer(closedWorld, fixedNames)
|
||||
: MinifyNamer(closedWorld, fixedNames)
|
||||
: Namer(closedWorld, fixedNames);
|
||||
_namer = _compiler.options.enableMinification
|
||||
? _compiler.options.useFrequencyNamer
|
||||
? FrequencyBasedNamer(closedWorld, fixedNames)
|
||||
: MinifyNamer(closedWorld, fixedNames)
|
||||
: Namer(closedWorld, fixedNames);
|
||||
_nativeCodegenEnqueuer = NativeCodegenEnqueuer(
|
||||
_compiler.options,
|
||||
closedWorld.elementEnvironment,
|
||||
|
||||
@@ -78,11 +78,11 @@ class JsToFrontendMap {
|
||||
|
||||
DartType? toBackendType(DartType? type, {bool allowFreeVariables = false}) =>
|
||||
type == null
|
||||
? null
|
||||
: _TypeConverter(
|
||||
_backend.types,
|
||||
allowFreeVariables: allowFreeVariables,
|
||||
).visit(type, toBackendEntity);
|
||||
? null
|
||||
: _TypeConverter(
|
||||
_backend.types,
|
||||
allowFreeVariables: allowFreeVariables,
|
||||
).visit(type, toBackendEntity);
|
||||
|
||||
void registerClosureData(ClosureData closureData) {
|
||||
assert(_closureData == null, "Closure data has already been registered.");
|
||||
@@ -360,10 +360,9 @@ class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
|
||||
DartType type = typeConverter.visit(constant.type, toBackendEntity);
|
||||
List<ConstantValue> values = _handleValues(constant.values);
|
||||
final constantIndex = constant.indexObject;
|
||||
final indexObject =
|
||||
constantIndex == null
|
||||
? null
|
||||
: visitJavaScriptObject(constantIndex, null);
|
||||
final indexObject = constantIndex == null
|
||||
? null
|
||||
: visitJavaScriptObject(constantIndex, null);
|
||||
if (identical(values, constant.values) &&
|
||||
identical(indexObject, constant.indexObject) &&
|
||||
type == constant.type) {
|
||||
@@ -385,10 +384,9 @@ class _ConstantConverter implements ConstantValueVisitor<ConstantValue, Null> {
|
||||
final keyList = visitList(constant.keyList, null);
|
||||
final valueList = visitList(constant.valueList, null);
|
||||
final constantIndex = constant.indexObject;
|
||||
final indexObject =
|
||||
constantIndex == null
|
||||
? null
|
||||
: visitJavaScriptObject(constantIndex, null);
|
||||
final indexObject = constantIndex == null
|
||||
? null
|
||||
: visitJavaScriptObject(constantIndex, null);
|
||||
if (identical(keyList, constant.keyList) &&
|
||||
identical(valueList, constant.valueList) &&
|
||||
identical(indexObject, constant.indexObject) &&
|
||||
|
||||
@@ -192,11 +192,13 @@ class JClosedWorld implements World {
|
||||
|
||||
Set<ClassEntity> implementedClasses = source.readClasses().toSet();
|
||||
Set<ClassEntity> liveNativeClasses = source.readClasses().toSet();
|
||||
Set<ClassEntity> extractTypeArgumentsInterfaces =
|
||||
source.readClasses().toSet();
|
||||
Set<ClassEntity> extractTypeArgumentsInterfaces = source
|
||||
.readClasses()
|
||||
.toSet();
|
||||
Set<MemberEntity> liveInstanceMembers = source.readMembers().toSet();
|
||||
Set<MemberEntity> liveAbstractInstanceMembers =
|
||||
source.readMembers().toSet();
|
||||
Set<MemberEntity> liveAbstractInstanceMembers = source
|
||||
.readMembers()
|
||||
.toSet();
|
||||
Set<MemberEntity> assignedInstanceMembers = source.readMembers().toSet();
|
||||
Set<MemberEntity> processedMembers = source.readMembers().toSet();
|
||||
Map<ClassEntity, Set<ClassEntity>> mixinUses = source.readClassMap(
|
||||
@@ -540,8 +542,9 @@ class JClosedWorld implements World {
|
||||
return false;
|
||||
}
|
||||
|
||||
late final ClassEntity _functionLub =
|
||||
getLubOfInstantiatedSubtypes(commonElements.functionClass)!;
|
||||
late final ClassEntity _functionLub = getLubOfInstantiatedSubtypes(
|
||||
commonElements.functionClass,
|
||||
)!;
|
||||
|
||||
/// Returns `true` if [selector] on [receiver] can hit a `call` method on a
|
||||
/// subclass of `Closure` using the [abstractValueDomain].
|
||||
|
||||
@@ -314,14 +314,15 @@ class JClosedWorldBuilder {
|
||||
Set<ClassEntity> helperClassesUsed = map.toBackendClassSet(
|
||||
backendUsage.helperClassesUsed,
|
||||
);
|
||||
Set<RuntimeTypeUse> runtimeTypeUses =
|
||||
backendUsage.runtimeTypeUses.map((RuntimeTypeUse runtimeTypeUse) {
|
||||
return RuntimeTypeUse(
|
||||
runtimeTypeUse.kind,
|
||||
map.toBackendType(runtimeTypeUse.receiverType)!,
|
||||
map.toBackendType(runtimeTypeUse.argumentType),
|
||||
);
|
||||
}).toSet();
|
||||
Set<RuntimeTypeUse> runtimeTypeUses = backendUsage.runtimeTypeUses.map((
|
||||
RuntimeTypeUse runtimeTypeUse,
|
||||
) {
|
||||
return RuntimeTypeUse(
|
||||
runtimeTypeUse.kind,
|
||||
map.toBackendType(runtimeTypeUse.receiverType)!,
|
||||
map.toBackendType(runtimeTypeUse.argumentType),
|
||||
);
|
||||
}).toSet();
|
||||
|
||||
return BackendUsageImpl(
|
||||
globalFunctionDependencies: globalFunctionDependencies,
|
||||
|
||||
@@ -287,18 +287,16 @@ class RecordDataBuilder {
|
||||
) {
|
||||
// Sorted shapes lead to a more consistent class ordering in the generated
|
||||
// code.
|
||||
final shapes =
|
||||
recordTypes.map((type) => type.shape).toSet().toList()
|
||||
..sort(RecordShape.compare);
|
||||
final shapes = recordTypes.map((type) => type.shape).toSet().toList()
|
||||
..sort(RecordShape.compare);
|
||||
|
||||
List<RecordRepresentation> representations = [];
|
||||
for (int i = 0; i < shapes.length; i++) {
|
||||
final shape = shapes[i];
|
||||
final getters = <MemberEntity>[];
|
||||
final cls =
|
||||
shape.fieldCount == 0
|
||||
? _elementMap.commonElements.emptyRecordClass
|
||||
: closedWorldBuilder.buildRecordShapeClass(shape, getters);
|
||||
final cls = shape.fieldCount == 0
|
||||
? _elementMap.commonElements.emptyRecordClass
|
||||
: closedWorldBuilder.buildRecordShapeClass(shape, getters);
|
||||
_gettersByShape[shape] = getters;
|
||||
int shapeTag = i;
|
||||
bool usesList = _computeUsesGeneralClass(cls);
|
||||
|
||||
@@ -639,8 +639,9 @@ class _Substitution extends DartTypeSubstitutionVisitor<Null> {
|
||||
Null argument,
|
||||
bool freshReference,
|
||||
) {
|
||||
DartType? replacement =
|
||||
_lookupCache[variable] ??= _lookupTypeVariableType(variable);
|
||||
DartType? replacement = _lookupCache[variable] ??= _lookupTypeVariableType(
|
||||
variable,
|
||||
);
|
||||
if (replacement == null) return variable; // not substituted.
|
||||
if (!freshReference) return replacement;
|
||||
int count = _counts[variable] = (_counts[variable] ?? 0) + 1;
|
||||
|
||||
@@ -292,8 +292,10 @@ class KernelToElementMap implements IrToElementMap {
|
||||
if (data.thisType == null) {
|
||||
ir.Class node = data.node;
|
||||
if (node.typeParameters.isEmpty) {
|
||||
data.thisType =
|
||||
data.rawType = types.interfaceType(cls, const <DartType>[]);
|
||||
data.thisType = data.rawType = types.interfaceType(
|
||||
cls,
|
||||
const <DartType>[],
|
||||
);
|
||||
} else {
|
||||
data.thisType = types.interfaceType(
|
||||
cls,
|
||||
@@ -370,11 +372,10 @@ class KernelToElementMap implements IrToElementMap {
|
||||
Set<InterfaceType> canonicalSupertypes = <InterfaceType>{};
|
||||
|
||||
InterfaceType processSupertype(ir.Supertype supertypeNode) {
|
||||
supertypeNode =
|
||||
classHierarchy.getClassAsInstanceOf(
|
||||
node,
|
||||
supertypeNode.classNode,
|
||||
)!;
|
||||
supertypeNode = classHierarchy.getClassAsInstanceOf(
|
||||
node,
|
||||
supertypeNode.classNode,
|
||||
)!;
|
||||
InterfaceType supertype = _typeConverter.visitSupertype(
|
||||
supertypeNode,
|
||||
);
|
||||
@@ -1001,8 +1002,8 @@ class KernelToElementMap implements IrToElementMap {
|
||||
// library.
|
||||
// TODO(johnniwinther): Cache more results to avoid redundant lookups?
|
||||
cachedMayLookupInMain ??=
|
||||
// Tests permit lookup outside of dart: libraries.
|
||||
allowedNativeTest(elementEnvironment.mainLibrary!.canonicalUri);
|
||||
// Tests permit lookup outside of dart: libraries.
|
||||
allowedNativeTest(elementEnvironment.mainLibrary!.canonicalUri);
|
||||
DartType? type;
|
||||
if (cachedMayLookupInMain!) {
|
||||
type ??= findInLibrary(elementEnvironment.mainLibrary);
|
||||
@@ -1527,8 +1528,9 @@ class KernelToElementMap implements IrToElementMap {
|
||||
NativeBasicData get nativeBasicData {
|
||||
var data = _nativeBasicData;
|
||||
if (data == null) {
|
||||
data =
|
||||
_nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
|
||||
data = _nativeBasicData = nativeBasicDataBuilder.close(
|
||||
elementEnvironment,
|
||||
);
|
||||
assert(
|
||||
_nativeBasicData != null,
|
||||
failedAt(
|
||||
@@ -1631,13 +1633,12 @@ class KernelToElementMap implements IrToElementMap {
|
||||
} else if (node is ir.FunctionExpression) {
|
||||
function = node.function;
|
||||
}
|
||||
localFunction =
|
||||
localFunctionMap[node] = JLocalFunction(
|
||||
name,
|
||||
memberContext,
|
||||
executableContext,
|
||||
node,
|
||||
);
|
||||
localFunction = localFunctionMap[node] = JLocalFunction(
|
||||
name,
|
||||
memberContext,
|
||||
executableContext,
|
||||
node,
|
||||
);
|
||||
int index = 0;
|
||||
List<JLocalTypeVariable> typeVariables = <JLocalTypeVariable>[];
|
||||
for (ir.TypeParameter typeParameter in function.typeParameters) {
|
||||
|
||||
@@ -557,20 +557,19 @@ class KFunctionData extends KMemberData {
|
||||
parent.kind == ir.ProcedureKind.Factory)) {
|
||||
_typeVariables = const <TypeVariableType>[];
|
||||
} else {
|
||||
_typeVariables =
|
||||
functionNode.typeParameters.map<TypeVariableType>((
|
||||
ir.TypeParameter typeParameter,
|
||||
) {
|
||||
return elementMap
|
||||
.getDartType(
|
||||
ir.TypeParameterType(
|
||||
typeParameter,
|
||||
ir.Nullability.nonNullable,
|
||||
),
|
||||
)
|
||||
.withoutNullability
|
||||
as TypeVariableType;
|
||||
}).toList();
|
||||
_typeVariables = functionNode.typeParameters.map<TypeVariableType>((
|
||||
ir.TypeParameter typeParameter,
|
||||
) {
|
||||
return elementMap
|
||||
.getDartType(
|
||||
ir.TypeParameterType(
|
||||
typeParameter,
|
||||
ir.Nullability.nonNullable,
|
||||
),
|
||||
)
|
||||
.withoutNullability
|
||||
as TypeVariableType;
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,10 +117,9 @@ void reportFrontEndMessage(
|
||||
Iterable<fe.DiagnosticMessage>? relatedInformation = fe
|
||||
.getMessageRelatedInformation(message);
|
||||
DiagnosticMessage mainMessage = convertMessage(message);
|
||||
List<DiagnosticMessage> infos =
|
||||
relatedInformation != null
|
||||
? relatedInformation.map(convertMessage).toList()
|
||||
: const [];
|
||||
List<DiagnosticMessage> infos = relatedInformation != null
|
||||
? relatedInformation.map(convertMessage).toList()
|
||||
: const [];
|
||||
switch (message.severity) {
|
||||
case fe.Severity.internalProblem:
|
||||
throw mainMessage.message.message;
|
||||
|
||||
@@ -400,17 +400,17 @@ class KernelImpactConverter implements ImpactRegistry {
|
||||
impactBuilder.registerStaticUse(
|
||||
isConst
|
||||
? StaticUse.constConstructorInvoke(
|
||||
constructor,
|
||||
callStructure,
|
||||
elementMap.getInterfaceType(type),
|
||||
deferredImport,
|
||||
)
|
||||
constructor,
|
||||
callStructure,
|
||||
elementMap.getInterfaceType(type),
|
||||
deferredImport,
|
||||
)
|
||||
: StaticUse.typedConstructorInvoke(
|
||||
constructor,
|
||||
callStructure,
|
||||
elementMap.getInterfaceType(type),
|
||||
deferredImport,
|
||||
),
|
||||
constructor,
|
||||
callStructure,
|
||||
elementMap.getInterfaceType(type),
|
||||
deferredImport,
|
||||
),
|
||||
);
|
||||
if (type.typeArguments.any((ir.DartType type) => type is! ir.DynamicType)) {
|
||||
registerBackendImpact(_impacts.typeVariableBoundCheck);
|
||||
@@ -808,8 +808,9 @@ class KernelImpactConverter implements ImpactRegistry {
|
||||
ir.DartType? argumentType,
|
||||
) {
|
||||
DartType receiverDartType = elementMap.getDartType(receiverType);
|
||||
DartType? argumentDartType =
|
||||
argumentType == null ? null : elementMap.getDartType(argumentType);
|
||||
DartType? argumentDartType = argumentType == null
|
||||
? null
|
||||
: elementMap.getDartType(argumentType);
|
||||
|
||||
// Enable runtime type support if we discover a getter called
|
||||
// runtimeType. We have to enable runtime type before hitting the
|
||||
@@ -1030,8 +1031,9 @@ class KernelImpactConverter implements ImpactRegistry {
|
||||
final conditionalUse = ConditionalUse.withReplacement(
|
||||
impact: convert(impact.impactData),
|
||||
replacementImpact: convert(impact.replacementImpactData),
|
||||
originalConditions:
|
||||
impact.originalConditions.map(elementMap.getMember).toList(),
|
||||
originalConditions: impact.originalConditions
|
||||
.map(elementMap.getMember)
|
||||
.toList(),
|
||||
original: impact.original,
|
||||
replacement: impact.replacement,
|
||||
);
|
||||
|
||||
@@ -53,8 +53,8 @@ class KernelFrontendStrategy {
|
||||
late final KernelToElementMap _elementMap;
|
||||
late final RuntimeTypesNeedBuilder _runtimeTypesNeedBuilder =
|
||||
_options.disableRtiOptimization
|
||||
? const TrivialRuntimeTypesNeedBuilder()
|
||||
: RuntimeTypesNeedBuilderImpl(elementEnvironment);
|
||||
? const TrivialRuntimeTypesNeedBuilder()
|
||||
: RuntimeTypesNeedBuilderImpl(elementEnvironment);
|
||||
|
||||
RuntimeTypesNeedBuilder get runtimeTypesNeedBuilderForTesting =>
|
||||
_runtimeTypesNeedBuilder;
|
||||
@@ -125,11 +125,8 @@ class KernelFrontendStrategy {
|
||||
MemberEntity member,
|
||||
) {
|
||||
if (!member.isInstanceMember) return;
|
||||
MemberEntity interceptorMember =
|
||||
elementEnvironment.lookupLocalClassMember(
|
||||
interceptorClass,
|
||||
member.memberName,
|
||||
)!;
|
||||
MemberEntity interceptorMember = elementEnvironment
|
||||
.lookupLocalClassMember(interceptorClass, member.memberName)!;
|
||||
// Interceptors must override all Object methods due to calling convention
|
||||
// differences.
|
||||
assert(
|
||||
|
||||
@@ -193,20 +193,19 @@ class KClosedWorld implements BuiltWorld {
|
||||
}
|
||||
|
||||
@override
|
||||
late final Iterable<FunctionEntity> userNoSuchMethods =
|
||||
(() {
|
||||
final result = <FunctionEntity>[];
|
||||
liveMemberUsage.forEach((MemberEntity member, MemberUsage memberUsage) {
|
||||
if (member is FunctionEntity && memberUsage.hasUse) {
|
||||
if (member.isInstanceMember &&
|
||||
member.name == Identifiers.noSuchMethod_ &&
|
||||
!commonElements.isDefaultNoSuchMethodImplementation(member)) {
|
||||
result.add(member);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
})();
|
||||
late final Iterable<FunctionEntity> userNoSuchMethods = (() {
|
||||
final result = <FunctionEntity>[];
|
||||
liveMemberUsage.forEach((MemberEntity member, MemberUsage memberUsage) {
|
||||
if (member is FunctionEntity && memberUsage.hasUse) {
|
||||
if (member.isInstanceMember &&
|
||||
member.name == Identifiers.noSuchMethod_ &&
|
||||
!commonElements.isDefaultNoSuchMethodImplementation(member)) {
|
||||
result.add(member);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
})();
|
||||
|
||||
@override
|
||||
late final Iterable<FunctionEntity> closurizedMembers = (() {
|
||||
@@ -220,49 +219,46 @@ class KClosedWorld implements BuiltWorld {
|
||||
}());
|
||||
|
||||
@override
|
||||
late final Iterable<FunctionEntity> closurizedStatics =
|
||||
(() {
|
||||
final result = <FunctionEntity>{};
|
||||
liveMemberUsage.forEach((MemberEntity member, MemberUsage usage) {
|
||||
if (member.isFunction &&
|
||||
(member.isStatic || member.isTopLevel) &&
|
||||
usage.hasRead) {
|
||||
result.add(member as FunctionEntity);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
})();
|
||||
late final Iterable<FunctionEntity> closurizedStatics = (() {
|
||||
final result = <FunctionEntity>{};
|
||||
liveMemberUsage.forEach((MemberEntity member, MemberUsage usage) {
|
||||
if (member.isFunction &&
|
||||
(member.isStatic || member.isTopLevel) &&
|
||||
usage.hasRead) {
|
||||
result.add(member as FunctionEntity);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
})();
|
||||
|
||||
@override
|
||||
late final Map<MemberEntity, DartType> genericCallableProperties =
|
||||
(() {
|
||||
final result = <MemberEntity, DartType>{};
|
||||
liveMemberUsage.forEach((MemberEntity member, MemberUsage usage) {
|
||||
if (usage.hasRead) {
|
||||
DartType? type;
|
||||
if (member is FieldEntity) {
|
||||
type = elementEnvironment.getFieldType(member);
|
||||
} else if (member.isGetter) {
|
||||
type =
|
||||
elementEnvironment
|
||||
.getFunctionType(member as FunctionEntity)
|
||||
.returnType;
|
||||
}
|
||||
if (type == null) return;
|
||||
if (dartTypes.canAssignGenericFunctionTo(type)) {
|
||||
result[member] = type;
|
||||
} else {
|
||||
type = type.withoutNullability;
|
||||
if (type is InterfaceType) {
|
||||
FunctionType? callType = dartTypes.getCallType(type);
|
||||
if (callType != null &&
|
||||
dartTypes.canAssignGenericFunctionTo(callType)) {
|
||||
result[member] = callType;
|
||||
}
|
||||
}
|
||||
late final Map<MemberEntity, DartType> genericCallableProperties = (() {
|
||||
final result = <MemberEntity, DartType>{};
|
||||
liveMemberUsage.forEach((MemberEntity member, MemberUsage usage) {
|
||||
if (usage.hasRead) {
|
||||
DartType? type;
|
||||
if (member is FieldEntity) {
|
||||
type = elementEnvironment.getFieldType(member);
|
||||
} else if (member.isGetter) {
|
||||
type = elementEnvironment
|
||||
.getFunctionType(member as FunctionEntity)
|
||||
.returnType;
|
||||
}
|
||||
if (type == null) return;
|
||||
if (dartTypes.canAssignGenericFunctionTo(type)) {
|
||||
result[member] = type;
|
||||
} else {
|
||||
type = type.withoutNullability;
|
||||
if (type is InterfaceType) {
|
||||
FunctionType? callType = dartTypes.getCallType(type);
|
||||
if (callType != null &&
|
||||
dartTypes.canAssignGenericFunctionTo(callType)) {
|
||||
result[member] = callType;
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
})();
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class KernelAnnotationProcessor {
|
||||
// otherwise paying the cost to verify by indexing extension types.
|
||||
bool isObjectLiteralConstructor =
|
||||
(memberNode.isExtensionTypeMember &&
|
||||
memberNode.function?.namedParameters.isNotEmpty == true);
|
||||
memberNode.function?.namedParameters.isNotEmpty == true);
|
||||
if (function.isExternal &&
|
||||
(isExplicitlyJsLibrary || isObjectLiteralConstructor)) {
|
||||
// External members of explicit js-interop library are implicitly
|
||||
|
||||
+3
-4
@@ -65,10 +65,9 @@ void transformClass(Class cls) {
|
||||
// TODO(jensj): Provide a "referenceFrom" if we need to support
|
||||
// the incremental compiler.
|
||||
ensureExistingProcedureMaps();
|
||||
Procedure? existingProcedure =
|
||||
procedure.kind == ProcedureKind.Setter
|
||||
? existingSetters[procedure.name]
|
||||
: existingNonSetters[procedure.name];
|
||||
Procedure? existingProcedure = procedure.kind == ProcedureKind.Setter
|
||||
? existingSetters[procedure.name]
|
||||
: existingNonSetters[procedure.name];
|
||||
if (existingProcedure != null) {
|
||||
cls.procedures.remove(existingProcedure);
|
||||
}
|
||||
|
||||
@@ -104,14 +104,13 @@ class LateLowering {
|
||||
Name _mangleFieldName(Field field) {
|
||||
assert(_shouldLowerInstanceField(field));
|
||||
final prefix = _lateInstanceFieldPrefix;
|
||||
final suffix =
|
||||
field.initializer == null
|
||||
? field.isFinal
|
||||
? _lateFinalUninitializedSuffix
|
||||
: _lateAssignableUninitializedSuffix
|
||||
: field.isFinal
|
||||
? _lateFinalInitializedSuffix
|
||||
: _lateAssignableInitializedSuffix;
|
||||
final suffix = field.initializer == null
|
||||
? field.isFinal
|
||||
? _lateFinalUninitializedSuffix
|
||||
: _lateAssignableUninitializedSuffix
|
||||
: field.isFinal
|
||||
? _lateFinalInitializedSuffix
|
||||
: _lateAssignableInitializedSuffix;
|
||||
|
||||
Class cls = field.enclosingClass!;
|
||||
return Name(
|
||||
@@ -122,8 +121,8 @@ class LateLowering {
|
||||
|
||||
ConstructorInvocation _callCellConstructor(Expression name, int fileOffset) =>
|
||||
_omitLateNames
|
||||
? _callCellUnnamedConstructor(fileOffset)
|
||||
: _callCellNamedConstructor(name, fileOffset);
|
||||
? _callCellUnnamedConstructor(fileOffset)
|
||||
: _callCellNamedConstructor(name, fileOffset);
|
||||
|
||||
ConstructorInvocation _callCellUnnamedConstructor(int fileOffset) =>
|
||||
ConstructorInvocation(
|
||||
@@ -143,10 +142,9 @@ class LateLowering {
|
||||
Expression name,
|
||||
Expression initializer,
|
||||
int fileOffset,
|
||||
) =>
|
||||
_omitLateNames
|
||||
? _callInitializedCellUnnamedConstructor(initializer, fileOffset)
|
||||
: _callInitializedCellNamedConstructor(name, initializer, fileOffset);
|
||||
) => _omitLateNames
|
||||
? _callInitializedCellUnnamedConstructor(initializer, fileOffset)
|
||||
: _callInitializedCellNamedConstructor(name, initializer, fileOffset);
|
||||
|
||||
ConstructorInvocation _callInitializedCellUnnamedConstructor(
|
||||
Expression initializer,
|
||||
@@ -326,10 +324,9 @@ class LateLowering {
|
||||
|
||||
int fileOffset = node.fileOffset;
|
||||
VariableGet cell = _variableCellRead(variable, fileOffset);
|
||||
_Reader reader =
|
||||
variable.initializer == null
|
||||
? _readLocal
|
||||
: (variable.isFinal ? _readInitializedFinal : _readInitialized);
|
||||
_Reader reader = variable.initializer == null
|
||||
? _readLocal
|
||||
: (variable.isFinal ? _readInitializedFinal : _readInitialized);
|
||||
return _callReader(
|
||||
reader,
|
||||
cell,
|
||||
@@ -346,14 +343,13 @@ class LateLowering {
|
||||
|
||||
int fileOffset = node.fileOffset;
|
||||
VariableGet cell = _variableCellRead(variable, fileOffset);
|
||||
Procedure setter =
|
||||
variable.initializer == null
|
||||
? (variable.isFinal
|
||||
? _coreTypes.cellFinalLocalValueSetter
|
||||
: _coreTypes.cellValueSetter)
|
||||
: (variable.isFinal
|
||||
? _coreTypes.initializedCellFinalValueSetter
|
||||
: _coreTypes.initializedCellValueSetter);
|
||||
Procedure setter = variable.initializer == null
|
||||
? (variable.isFinal
|
||||
? _coreTypes.cellFinalLocalValueSetter
|
||||
: _coreTypes.cellValueSetter)
|
||||
: (variable.isFinal
|
||||
? _coreTypes.initializedCellFinalValueSetter
|
||||
: _coreTypes.initializedCellValueSetter);
|
||||
return _callSetter(setter, cell, node.value, fileOffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ class _ModularTransformer extends Transformer {
|
||||
_awaitLowering = AwaitLowering(coreTypes),
|
||||
_asyncLowering =
|
||||
(options?.features.simpleAsyncToFuture.isEnabled ?? false)
|
||||
? AsyncLowering(coreTypes)
|
||||
: null;
|
||||
? AsyncLowering(coreTypes)
|
||||
: null;
|
||||
|
||||
@override
|
||||
TreeNode defaultMember(Member node) {
|
||||
|
||||
@@ -298,8 +298,8 @@ class NativeCodegenEnqueuer extends NativeEnqueuer {
|
||||
_addSubtypes(superclass, emitter);
|
||||
|
||||
_elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
|
||||
List<ClassEntity> subtypes =
|
||||
emitter.subtypes[type.element] ??= <ClassEntity>[];
|
||||
List<ClassEntity> subtypes = emitter.subtypes[type.element] ??=
|
||||
<ClassEntity>[];
|
||||
subtypes.add(cls);
|
||||
});
|
||||
|
||||
@@ -311,8 +311,8 @@ class NativeCodegenEnqueuer extends NativeEnqueuer {
|
||||
superclass = _elementEnvironment.getSuperClass(superclass)!;
|
||||
}
|
||||
|
||||
List<ClassEntity> directSubtypes =
|
||||
emitter.directSubtypes[superclass] ??= <ClassEntity>[];
|
||||
List<ClassEntity> directSubtypes = emitter.directSubtypes[superclass] ??=
|
||||
<ClassEntity>[];
|
||||
directSubtypes.add(cls);
|
||||
}
|
||||
|
||||
|
||||
@@ -722,25 +722,22 @@ class CompilerOptions implements DiagnosticOptions {
|
||||
/// extension does not match the expected extension for the current [stage]
|
||||
/// then the last segment is treated as a prefix. Only set when `--stage` is
|
||||
/// specified.
|
||||
late final String _outputPrefix =
|
||||
(() {
|
||||
if (_stageFlag == null) return '';
|
||||
final extension = _outputExtension;
|
||||
late final String _outputPrefix = (() {
|
||||
if (_stageFlag == null) return '';
|
||||
final extension = _outputExtension;
|
||||
|
||||
return (extension != null && _outputFilename.endsWith(extension))
|
||||
? ''
|
||||
: _outputFilename;
|
||||
})();
|
||||
return (extension != null && _outputFilename.endsWith(extension))
|
||||
? ''
|
||||
: _outputFilename;
|
||||
})();
|
||||
|
||||
/// Output directory specified by the user via the `--out` flag. The directory
|
||||
/// is calculated by resolving the substring prior to the final URI segment
|
||||
/// (i.e. before the final slash) relative to [Uri.base]. Defaults to
|
||||
/// [Uri.base] if `--out` is not provided or does not include a directory.
|
||||
late final Uri _outputDir =
|
||||
(() =>
|
||||
(_outputUri != null)
|
||||
? Uri.base.resolveUri(_outputUri!).resolve('.')
|
||||
: Uri.base)();
|
||||
late final Uri _outputDir = (() => (_outputUri != null)
|
||||
? Uri.base.resolveUri(_outputUri!).resolve('.')
|
||||
: Uri.base)();
|
||||
|
||||
/// Computes a resolved output URI based on value provided via the `--out`
|
||||
/// flag. Updates [outputUri] based on the result and returns the value.
|
||||
@@ -835,8 +832,11 @@ class CompilerOptions implements DiagnosticOptions {
|
||||
options,
|
||||
Flags.benchmarkingExperiment,
|
||||
)
|
||||
..buildId =
|
||||
_extractStringOption(options, '--build-id=', _undeterminedBuildID)!
|
||||
..buildId = _extractStringOption(
|
||||
options,
|
||||
'--build-id=',
|
||||
_undeterminedBuildID,
|
||||
)!
|
||||
..compileForServer = _hasOption(options, Flags.serverMode)
|
||||
..deferredMapUri = _extractUriOption(options, '--deferred-map=')
|
||||
.._deferredLoadIdMapUri = _extractUriOption(
|
||||
@@ -887,8 +887,10 @@ class CompilerOptions implements DiagnosticOptions {
|
||||
.._disableMinification = _hasOption(options, Flags.noMinify)
|
||||
..omitLateNames = _hasOption(options, Flags.omitLateNames)
|
||||
.._noOmitLateNames = _hasOption(options, Flags.noOmitLateNames)
|
||||
..enableNativeLiveTypeAnalysis =
|
||||
!_hasOption(options, Flags.disableNativeLiveTypeAnalysis)
|
||||
..enableNativeLiveTypeAnalysis = !_hasOption(
|
||||
options,
|
||||
Flags.disableNativeLiveTypeAnalysis,
|
||||
)
|
||||
..enableUserAssertions =
|
||||
_hasOption(options, Flags.enableCheckedMode) ||
|
||||
_hasOption(options, Flags.enableAsserts)
|
||||
@@ -938,8 +940,10 @@ class CompilerOptions implements DiagnosticOptions {
|
||||
)
|
||||
..testMode = _hasOption(options, Flags.testMode)
|
||||
..trustPrimitives = _hasOption(options, Flags.trustPrimitives)
|
||||
..useFrequencyNamer =
|
||||
!_hasOption(options, Flags.noFrequencyBasedMinification)
|
||||
..useFrequencyNamer = !_hasOption(
|
||||
options,
|
||||
Flags.noFrequencyBasedMinification,
|
||||
)
|
||||
..useMultiSourceInfo = _hasOption(options, Flags.useMultiSourceInfo)
|
||||
..useNewSourceInfo = _hasOption(options, Flags.useNewSourceInfo)
|
||||
..useSimpleLoadIds = _hasOption(options, Flags.useSimpleLoadIds)
|
||||
|
||||
@@ -146,8 +146,9 @@ class OrderedTypeSet {
|
||||
void forEach(int level, void Function(InterfaceType type) f) {
|
||||
if (level < levels) {
|
||||
Link<InterfaceType> pointer = _levels[level];
|
||||
Link<InterfaceType> end =
|
||||
level > 0 ? _levels[level - 1] : const Link<InterfaceType>();
|
||||
Link<InterfaceType> end = level > 0
|
||||
? _levels[level - 1]
|
||||
: const Link<InterfaceType>();
|
||||
// TODO(het): checking `isNotEmpty` should be unnecessary, remove when
|
||||
// constants are properly canonicalized
|
||||
while (pointer.isNotEmpty && !identical(pointer, end)) {
|
||||
@@ -161,8 +162,9 @@ class OrderedTypeSet {
|
||||
int level = hierarchyDepth;
|
||||
if (level < levels) {
|
||||
Link<InterfaceType> pointer = _levels[level];
|
||||
Link<InterfaceType> end =
|
||||
level > 0 ? _levels[level - 1] : const Link<InterfaceType>();
|
||||
Link<InterfaceType> end = level > 0
|
||||
? _levels[level - 1]
|
||||
: const Link<InterfaceType>();
|
||||
// TODO(het): checking `isNotEmpty` should be unnecessary, remove when
|
||||
// constants are properly canonicalized
|
||||
while (pointer.isNotEmpty && !identical(pointer, end)) {
|
||||
|
||||
@@ -79,20 +79,18 @@ abstract class Deferrable<E> {
|
||||
E Function(DataSourceReader source) f,
|
||||
int offset, {
|
||||
bool cacheData = true,
|
||||
}) =>
|
||||
cacheData
|
||||
? _DeferredCache(reader, f, offset)
|
||||
: _Deferred(reader, f, offset);
|
||||
}) => cacheData
|
||||
? _DeferredCache(reader, f, offset)
|
||||
: _Deferred(reader, f, offset);
|
||||
static Deferrable<E> deferredWithArg<E, A>(
|
||||
DataSourceReader reader,
|
||||
E Function(DataSourceReader source, A arg) f,
|
||||
A arg,
|
||||
int offset, {
|
||||
bool cacheData = true,
|
||||
}) =>
|
||||
cacheData
|
||||
? _DeferredCacheWithArg(reader, f, arg, offset)
|
||||
: _DeferredWithArg(reader, f, arg, offset);
|
||||
}) => cacheData
|
||||
? _DeferredCacheWithArg(reader, f, arg, offset)
|
||||
: _DeferredWithArg(reader, f, arg, offset);
|
||||
const factory Deferrable.eager(E data) = _Eager;
|
||||
|
||||
const Deferrable();
|
||||
|
||||
@@ -234,8 +234,9 @@ class UnorderedIndexedSource<E extends Object> implements IndexedSource<E> {
|
||||
offset = markerOrOffset - _indicatorOffset;
|
||||
}
|
||||
bool isLocal = _isLocalOffset(offset);
|
||||
final globalOffset =
|
||||
isLocal ? _localToGlobalOffset(offset, source) : offset;
|
||||
final globalOffset = isLocal
|
||||
? _localToGlobalOffset(offset, source)
|
||||
: offset;
|
||||
final cachedValue = _cache[globalOffset];
|
||||
if (cachedValue != null) return cachedValue;
|
||||
return _readAtOffset(
|
||||
@@ -268,8 +269,9 @@ class UnorderedIndexedSource<E extends Object> implements IndexedSource<E> {
|
||||
offset = markerOrOffset - _indicatorOffset;
|
||||
}
|
||||
bool isLocal = _isLocalOffset(offset);
|
||||
final globalOffset =
|
||||
isLocal ? _localToGlobalOffset(offset, source) : offset;
|
||||
final globalOffset = isLocal
|
||||
? _localToGlobalOffset(offset, source)
|
||||
: offset;
|
||||
return _readAtOffset(
|
||||
source,
|
||||
readValue,
|
||||
@@ -299,13 +301,12 @@ class UnorderedIndexedSource<E extends Object> implements IndexedSource<E> {
|
||||
}) {
|
||||
final realSource = isLocal ? source : findSource(globalOffset);
|
||||
final realOffset = _globalToRealOffset(globalOffset, realSource);
|
||||
final value =
|
||||
isLocal
|
||||
? source.readWithOffset(realOffset, readValue)
|
||||
: source.readWithSource(
|
||||
realSource,
|
||||
() => source.readWithOffset(realOffset, readValue),
|
||||
);
|
||||
final value = isLocal
|
||||
? source.readWithOffset(realOffset, readValue)
|
||||
: source.readWithSource(
|
||||
realSource,
|
||||
() => source.readWithOffset(realOffset, readValue),
|
||||
);
|
||||
if (isCached) _cache[globalOffset] = value;
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ String computeMemberName(ir.Member member) {
|
||||
// forwarders (see dartbug.com/33732).
|
||||
String libraryPrefix =
|
||||
member.name.isPrivate &&
|
||||
member.name.libraryReference != member.enclosingLibrary.reference
|
||||
? '${member.name.libraryReference?.canonicalName?.name}:'
|
||||
: '';
|
||||
member.name.libraryReference != member.enclosingLibrary.reference
|
||||
? '${member.name.libraryReference?.canonicalName?.name}:'
|
||||
: '';
|
||||
String name = member.name.text;
|
||||
if (member is ir.Constructor) {
|
||||
name = '.$name';
|
||||
@@ -271,14 +271,14 @@ class MemberData {
|
||||
}
|
||||
|
||||
ir.Constant getConstantByIndex(ir.ConstantExpression node, int index) {
|
||||
ConstantNodeIndexerVisitor indexer =
|
||||
_constantIndexMap[node] ??= _createConstantIndexer(node);
|
||||
ConstantNodeIndexerVisitor indexer = _constantIndexMap[node] ??=
|
||||
_createConstantIndexer(node);
|
||||
return indexer.getConstant(index);
|
||||
}
|
||||
|
||||
int getIndexByConstant(ir.ConstantExpression node, ir.Constant constant) {
|
||||
ConstantNodeIndexerVisitor indexer =
|
||||
_constantIndexMap[node] ??= _createConstantIndexer(node);
|
||||
ConstantNodeIndexerVisitor indexer = _constantIndexMap[node] ??=
|
||||
_createConstantIndexer(node);
|
||||
return indexer.getIndex(constant);
|
||||
}
|
||||
|
||||
|
||||
@@ -1194,8 +1194,8 @@ class DataSinkWriter {
|
||||
|
||||
MemberData get currentMemberData {
|
||||
final currentMemberContext = _currentMemberContext!;
|
||||
return _currentMemberData ??=
|
||||
_memberData[currentMemberContext] ??= MemberData(currentMemberContext);
|
||||
return _currentMemberData ??= _memberData[currentMemberContext] ??=
|
||||
MemberData(currentMemberContext);
|
||||
}
|
||||
|
||||
MemberData _getMemberData(ir.TreeNode node) {
|
||||
|
||||
@@ -183,11 +183,11 @@ class DataSourceReader {
|
||||
}) {
|
||||
return useDeferredStrategy
|
||||
? Deferrable<E>.deferred(
|
||||
this,
|
||||
f,
|
||||
_sourceReader.readDeferred(),
|
||||
cacheData: cacheData,
|
||||
)
|
||||
this,
|
||||
f,
|
||||
_sourceReader.readDeferred(),
|
||||
cacheData: cacheData,
|
||||
)
|
||||
: Deferrable<E>.eager(_sourceReader.readDeferredAsEager(() => f(this)));
|
||||
}
|
||||
|
||||
@@ -198,15 +198,15 @@ class DataSourceReader {
|
||||
}) {
|
||||
return useDeferredStrategy
|
||||
? Deferrable.deferredWithArg<E, A>(
|
||||
this,
|
||||
f,
|
||||
arg,
|
||||
_sourceReader.readDeferred(),
|
||||
cacheData: cacheData,
|
||||
)
|
||||
this,
|
||||
f,
|
||||
arg,
|
||||
_sourceReader.readDeferred(),
|
||||
cacheData: cacheData,
|
||||
)
|
||||
: Deferrable<E>.eager(
|
||||
_sourceReader.readDeferredAsEager(() => f(this, arg)),
|
||||
);
|
||||
_sourceReader.readDeferredAsEager(() => f(this, arg)),
|
||||
);
|
||||
}
|
||||
|
||||
/// Invoke [f] in the context of [member]. This sets up support for
|
||||
@@ -852,10 +852,12 @@ class DataSourceReader {
|
||||
)..addAll(typeParameters);
|
||||
for (int index = 0; index < typeParameterCount; index++) {
|
||||
typeParameters[index].name = readString();
|
||||
typeParameters[index].bound =
|
||||
_readDartTypeNode(functionTypeVariables)!;
|
||||
typeParameters[index].defaultType =
|
||||
_readDartTypeNode(functionTypeVariables)!;
|
||||
typeParameters[index].bound = _readDartTypeNode(
|
||||
functionTypeVariables,
|
||||
)!;
|
||||
typeParameters[index].defaultType = _readDartTypeNode(
|
||||
functionTypeVariables,
|
||||
)!;
|
||||
}
|
||||
ir.DartType returnType = _readDartTypeNode(functionTypeVariables)!;
|
||||
ir.Nullability nullability = readEnum(ir.Nullability.values);
|
||||
@@ -1293,10 +1295,9 @@ class DataSourceReader {
|
||||
final keyList = readConstant() as ListConstantValue;
|
||||
final valueList = readConstant() as ListConstantValue;
|
||||
bool onlyStringKeys = readBool();
|
||||
final indexObject =
|
||||
onlyStringKeys
|
||||
? readConstant() as JavaScriptObjectConstantValue
|
||||
: null;
|
||||
final indexObject = onlyStringKeys
|
||||
? readConstant() as JavaScriptObjectConstantValue
|
||||
: null;
|
||||
return constant_system.JavaScriptMapConstant(
|
||||
type,
|
||||
keyList,
|
||||
|
||||
@@ -53,8 +53,9 @@ class SerializationTask extends CompilerTask {
|
||||
this._provider,
|
||||
this._outputProvider,
|
||||
Measurer measurer,
|
||||
) : _valueInterner =
|
||||
_options.features.internValues.isEnabled ? ValueInterner() : null,
|
||||
) : _valueInterner = _options.features.internValues.isEnabled
|
||||
? ValueInterner()
|
||||
: null,
|
||||
super(measurer);
|
||||
|
||||
@override
|
||||
|
||||
@@ -302,10 +302,9 @@ class FormattingDiagnosticHandler implements api.CompilerDiagnostics {
|
||||
file.getLocationMessage(color(message), begin, end, colorize: color),
|
||||
);
|
||||
} else {
|
||||
String position =
|
||||
begin != null && end != null && end - begin > 0
|
||||
? '@$begin+${end - begin}'
|
||||
: '';
|
||||
String position = begin != null && end != null && end - begin > 0
|
||||
? '@$begin+${end - begin}'
|
||||
: '';
|
||||
print(
|
||||
'${provider.relativizeUri(uri)}$position:\n'
|
||||
'${color(message)}',
|
||||
@@ -415,8 +414,9 @@ class RandomAccessFileOutputProvider implements api.CompilerOutput {
|
||||
|
||||
RandomAccessFile output;
|
||||
try {
|
||||
output = (File(uri.toFilePath())
|
||||
..createSync(recursive: true)).openSync(mode: FileMode.write);
|
||||
output = (File(
|
||||
uri.toFilePath(),
|
||||
)..createSync(recursive: true)).openSync(mode: FileMode.write);
|
||||
} on FileSystemException catch (e) {
|
||||
onFailure('$e');
|
||||
}
|
||||
@@ -450,8 +450,9 @@ class RandomAccessFileOutputProvider implements api.CompilerOutput {
|
||||
|
||||
RandomAccessFile output;
|
||||
try {
|
||||
output = (File(uri.toFilePath())
|
||||
..createSync(recursive: true)).openSync(mode: FileMode.write);
|
||||
output = (File(
|
||||
uri.toFilePath(),
|
||||
)..createSync(recursive: true)).openSync(mode: FileMode.write);
|
||||
} on FileSystemException catch (e) {
|
||||
onFailure('$e');
|
||||
}
|
||||
|
||||
@@ -190,8 +190,8 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
_loopHandler = KernelLoopHandler(this);
|
||||
_typeBuilder = KernelTypeBuilder(this, _elementMap);
|
||||
graph.element = targetElement;
|
||||
graph.sourceInformation =
|
||||
_sourceInformationBuilder.buildVariableDeclaration();
|
||||
graph.sourceInformation = _sourceInformationBuilder
|
||||
.buildVariableDeclaration();
|
||||
localsHandler = LocalsHandler(
|
||||
this,
|
||||
targetElement,
|
||||
@@ -352,10 +352,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
AbstractValue type, {
|
||||
bool isElided = false,
|
||||
}) {
|
||||
HLocalValue result =
|
||||
isElided
|
||||
? HLocalValue(parameter, type)
|
||||
: HParameterValue(parameter, type);
|
||||
HLocalValue result = isElided
|
||||
? HLocalValue(parameter, type)
|
||||
: HParameterValue(parameter, type);
|
||||
if (lastAddedParameter == null) {
|
||||
graph.entry.addBefore(graph.entry.first, result);
|
||||
} else {
|
||||
@@ -435,16 +434,16 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
KernelToTypeInferenceMapImpl(member, globalInferenceResults),
|
||||
_currentFrame != null
|
||||
? _currentFrame!.sourceInformationBuilder.forContext(
|
||||
member,
|
||||
callSourceInformation,
|
||||
)
|
||||
member,
|
||||
callSourceInformation,
|
||||
)
|
||||
: _sourceInformationStrategy.createBuilderForContext(member),
|
||||
memberNode != null
|
||||
? ir.StaticTypeContext(
|
||||
memberNode,
|
||||
elementMap.typeEnvironment,
|
||||
cache: ir.StaticTypeCacheImpl(),
|
||||
)
|
||||
memberNode,
|
||||
elementMap.typeEnvironment,
|
||||
cache: ir.StaticTypeCacheImpl(),
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
@@ -1716,10 +1715,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
|
||||
if (options.experimentUnreachableMethodsThrow) {
|
||||
var emptyParameters = parameters.values.where(
|
||||
(parameter) =>
|
||||
_abstractValueDomain
|
||||
.isEmpty(parameter.instructionType)
|
||||
.isDefinitelyTrue,
|
||||
(parameter) => _abstractValueDomain
|
||||
.isEmpty(parameter.instructionType)
|
||||
.isDefinitelyTrue,
|
||||
);
|
||||
if (emptyParameters.isNotEmpty) {
|
||||
_addComment('$emptyParameters inferred as [empty]');
|
||||
@@ -2199,15 +2197,13 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
handleParameter(functionNode.positionalParameters[position]);
|
||||
}
|
||||
if (functionNode.namedParameters.isNotEmpty) {
|
||||
List<ir.VariableDeclaration> namedParameters =
|
||||
functionNode.namedParameters
|
||||
// Filter elided parameters.
|
||||
.where(
|
||||
(p) => function.parameterStructure.namedParameters.contains(
|
||||
p.name,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
List<ir.VariableDeclaration> namedParameters = functionNode
|
||||
.namedParameters
|
||||
// Filter elided parameters.
|
||||
.where(
|
||||
(p) => function.parameterStructure.namedParameters.contains(p.name),
|
||||
)
|
||||
.toList();
|
||||
// Sort by file offset to visit parameters in declaration order.
|
||||
namedParameters.sort(nativeOrdering);
|
||||
namedParameters.forEach(handleParameter);
|
||||
@@ -2724,10 +2720,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
|
||||
node.iterable.accept(this);
|
||||
array = pop();
|
||||
isFixed =
|
||||
_abstractValueDomain
|
||||
.isFixedLengthJsIndexable(array.instructionType)
|
||||
.isDefinitelyTrue;
|
||||
isFixed = _abstractValueDomain
|
||||
.isFixedLengthJsIndexable(array.instructionType)
|
||||
.isDefinitelyTrue;
|
||||
localsHandler.updateLocal(
|
||||
indexVariable,
|
||||
graph.addConstantInt(0, closedWorld),
|
||||
@@ -2775,10 +2770,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
// the condition.
|
||||
HInstruction value = HIndex(array, index, type)
|
||||
..sourceInformation = sourceInformation;
|
||||
final staticType =
|
||||
_abstractValueDomain
|
||||
.createFromStaticType(_getStaticForInElementType(node))
|
||||
.abstractValue;
|
||||
final staticType = _abstractValueDomain
|
||||
.createFromStaticType(_getStaticForInElementType(node))
|
||||
.abstractValue;
|
||||
value.instructionType = _abstractValueDomain.intersection(
|
||||
value.instructionType,
|
||||
staticType,
|
||||
@@ -3730,8 +3724,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
// TODO(https://dartbug.com/51777): Consider alternative with single switch
|
||||
// statement.
|
||||
|
||||
JumpTarget switchTarget =
|
||||
_localsMap.getJumpTargetForSwitch(switchStatement)!;
|
||||
JumpTarget switchTarget = _localsMap.getJumpTargetForSwitch(
|
||||
switchStatement,
|
||||
)!;
|
||||
localsHandler.updateLocal(switchTarget, graph.addConstantNull(closedWorld));
|
||||
|
||||
var switchCases = List<ir.SwitchCase?>.from(switchStatement.cases);
|
||||
@@ -5497,10 +5492,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
final receiverStaticType = _getStaticType(
|
||||
invocation.arguments.positional[1],
|
||||
);
|
||||
AbstractValue receiverType =
|
||||
_abstractValueDomain
|
||||
.createFromStaticType(receiverStaticType)
|
||||
.abstractValue;
|
||||
AbstractValue receiverType = _abstractValueDomain
|
||||
.createFromStaticType(receiverStaticType)
|
||||
.abstractValue;
|
||||
push(
|
||||
HInvokeClosure(
|
||||
selector,
|
||||
@@ -5636,11 +5630,12 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
String name = _readStringLiteral(invocation.arguments.positional[0]);
|
||||
final typeArgumentsLiteral =
|
||||
invocation.arguments.positional[1] as ir.ListLiteral;
|
||||
List<DartType> typeArguments =
|
||||
typeArgumentsLiteral.expressions.map((ir.Expression expression) {
|
||||
final typeLiteral = expression as ir.TypeLiteral;
|
||||
return _elementMap.getDartType(typeLiteral.type);
|
||||
}).toList();
|
||||
List<DartType> typeArguments = typeArgumentsLiteral.expressions.map((
|
||||
ir.Expression expression,
|
||||
) {
|
||||
final typeLiteral = expression as ir.TypeLiteral;
|
||||
return _elementMap.getDartType(typeLiteral.type);
|
||||
}).toList();
|
||||
|
||||
final positionalArgumentsLiteral =
|
||||
invocation.arguments.positional[2] as ir.ListLiteral;
|
||||
@@ -6061,13 +6056,12 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
);
|
||||
return;
|
||||
}
|
||||
final globalName =
|
||||
_foreignConstantStringArgument(
|
||||
invocation,
|
||||
1,
|
||||
'JS_EMBEDDED_GLOBAL',
|
||||
'second ',
|
||||
)!;
|
||||
final globalName = _foreignConstantStringArgument(
|
||||
invocation,
|
||||
1,
|
||||
'JS_EMBEDDED_GLOBAL',
|
||||
'second ',
|
||||
)!;
|
||||
js.Template expr = js.js.expressionTemplateYielding(
|
||||
_emitter.generateEmbeddedGlobalAccess(globalName),
|
||||
);
|
||||
@@ -6694,8 +6688,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
return;
|
||||
}
|
||||
|
||||
HInstruction checkedExpression =
|
||||
_visitPositionalArguments(invocation.arguments).single;
|
||||
HInstruction checkedExpression = _visitPositionalArguments(
|
||||
invocation.arguments,
|
||||
).single;
|
||||
push(
|
||||
HIsLateSentinel(checkedExpression, _abstractValueDomain.boolType)
|
||||
..sourceInformation = sourceInformation,
|
||||
@@ -6886,14 +6881,12 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
List<DartType> typeArguments,
|
||||
SourceInformation? sourceInformation,
|
||||
) {
|
||||
AbstractValue typeBound =
|
||||
_abstractValueDomain
|
||||
.createFromStaticType(staticReceiverType)
|
||||
.abstractValue;
|
||||
receiverType =
|
||||
receiverType == null
|
||||
? typeBound
|
||||
: _abstractValueDomain.intersection(receiverType, typeBound);
|
||||
AbstractValue typeBound = _abstractValueDomain
|
||||
.createFromStaticType(staticReceiverType)
|
||||
.abstractValue;
|
||||
receiverType = receiverType == null
|
||||
? typeBound
|
||||
: _abstractValueDomain.intersection(receiverType, typeBound);
|
||||
|
||||
// We prefer to not inline certain operations on indexables,
|
||||
// because the constant folder will handle them better and turn
|
||||
@@ -7034,10 +7027,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
if (node is ir.InstanceInvocation ||
|
||||
node is ir.FunctionInvocation ||
|
||||
node is ir.InstanceGet) {
|
||||
final staticType =
|
||||
_abstractValueDomain
|
||||
.createFromStaticType(_getStaticType(node as ir.Expression))
|
||||
.abstractValue;
|
||||
final staticType = _abstractValueDomain
|
||||
.createFromStaticType(_getStaticType(node as ir.Expression))
|
||||
.abstractValue;
|
||||
// Narrow to front-end inferred type, but only if `receiverType` is
|
||||
// disjoint with LegacyJavaScriptObject. Global type inference does not
|
||||
// trust the legacy js-interop methods, so we should not start doing so
|
||||
@@ -7106,8 +7098,10 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
// TODO(johnniwinther): can we elide those parameters? This should be
|
||||
// consistent with what we do with instance methods.
|
||||
final procedure = node as ir.Procedure;
|
||||
List<ir.VariableDeclaration> namedParameters =
|
||||
procedure.function.namedParameters.toList();
|
||||
List<ir.VariableDeclaration> namedParameters = procedure
|
||||
.function
|
||||
.namedParameters
|
||||
.toList();
|
||||
|
||||
namedParameters.sort(nativeOrdering);
|
||||
for (ir.VariableDeclaration variable in namedParameters) {
|
||||
@@ -7146,10 +7140,9 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
|
||||
var nativeBehavior = NativeBehavior()..sideEffects.setAllSideEffects();
|
||||
|
||||
DartType type =
|
||||
element is ConstructorEntity
|
||||
? _elementEnvironment.getThisType(element.enclosingClass)
|
||||
: _elementEnvironment.getFunctionType(element).returnType;
|
||||
DartType type = element is ConstructorEntity
|
||||
? _elementEnvironment.getThisType(element.enclosingClass)
|
||||
: _elementEnvironment.getFunctionType(element).returnType;
|
||||
// Native behavior effects here are similar to native/behavior.dart.
|
||||
// The return type is dynamic because we don't trust js-interop type
|
||||
// declarations.
|
||||
@@ -7260,15 +7253,13 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
final functionType = expressionType.withoutNullability as FunctionType;
|
||||
bool typeArgumentsNeeded = _rtiNeed.methodNeedsTypeArguments(target);
|
||||
|
||||
List<DartType> typeArguments =
|
||||
node.typeArguments
|
||||
.map(
|
||||
(type) =>
|
||||
typeArgumentsNeeded
|
||||
? _elementMap.getDartType(type)
|
||||
: _commonElements.dynamicType,
|
||||
)
|
||||
.toList();
|
||||
List<DartType> typeArguments = node.typeArguments
|
||||
.map(
|
||||
(type) => typeArgumentsNeeded
|
||||
? _elementMap.getDartType(type)
|
||||
: _commonElements.dynamicType,
|
||||
)
|
||||
.toList();
|
||||
registry.registerGenericInstantiation(
|
||||
GenericInstantiation(functionType, typeArguments),
|
||||
);
|
||||
@@ -8255,8 +8246,8 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
assert(selector.applies(function));
|
||||
CallStructure callStructure = selector.callStructure;
|
||||
ParameterStructure parameterStructure = function.parameterStructure;
|
||||
List<String> selectorArgumentNames =
|
||||
selector.callStructure.getOrderedNamedArguments();
|
||||
List<String> selectorArgumentNames = selector.callStructure
|
||||
.getOrderedNamedArguments();
|
||||
bool methodNeedsTypeArguments = _rtiNeed.methodNeedsTypeArguments(function);
|
||||
List<HInstruction> compiledArguments = [];
|
||||
|
||||
@@ -8335,8 +8326,8 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
} else {
|
||||
assert(callStructure.typeArgumentCount == 0);
|
||||
// Pass type variable bounds as type arguments.
|
||||
for (TypeVariableType typeVariable in _elementEnvironment
|
||||
.getFunctionTypeVariables(function)) {
|
||||
for (TypeVariableType typeVariable
|
||||
in _elementEnvironment.getFunctionTypeVariables(function)) {
|
||||
compiledArguments.add(
|
||||
_computeTypeArgumentDefaultValue(function, typeVariable),
|
||||
);
|
||||
@@ -8444,8 +8435,8 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
|
||||
|
||||
bool hasTypeParameters = function.parameterStructure.typeParameters > 0;
|
||||
bool needsTypeArguments = _rtiNeed.methodNeedsTypeArguments(function);
|
||||
for (TypeVariableType typeVariable in _elementEnvironment
|
||||
.getFunctionTypeVariables(function)) {
|
||||
for (TypeVariableType typeVariable
|
||||
in _elementEnvironment.getFunctionTypeVariables(function)) {
|
||||
HInstruction argument;
|
||||
if (hasTypeParameters && needsTypeArguments) {
|
||||
argument = compiledArguments[argumentIndex++];
|
||||
|
||||
@@ -92,11 +92,11 @@ class SsaCodeGeneratorTask extends CompilerTask {
|
||||
return finish(
|
||||
element.asyncMarker.isAsync
|
||||
? (element.asyncMarker.isYielding
|
||||
? js.AsyncModifier.asyncStar
|
||||
: js.AsyncModifier.async)
|
||||
? js.AsyncModifier.asyncStar
|
||||
: js.AsyncModifier.async)
|
||||
: (element.asyncMarker.isYielding
|
||||
? js.AsyncModifier.syncStar
|
||||
: js.AsyncModifier.sync),
|
||||
? js.AsyncModifier.syncStar
|
||||
: js.AsyncModifier.sync),
|
||||
);
|
||||
} else {
|
||||
return finish(js.AsyncModifier.sync);
|
||||
@@ -2663,10 +2663,9 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
|
||||
|
||||
assert(_nativeData.isNativeMember(target), 'non-native target: $node');
|
||||
|
||||
String? targetName =
|
||||
_nativeData.hasFixedBackendName(target)
|
||||
? _nativeData.getFixedBackendName(target)
|
||||
: target.name;
|
||||
String? targetName = _nativeData.hasFixedBackendName(target)
|
||||
? _nativeData.getFixedBackendName(target)
|
||||
: target.name;
|
||||
|
||||
void invokeWithJavaScriptReceiver(js.Expression receiverExpression) {
|
||||
// JS-interop target names can be paths ("a.b"), so we parse them to
|
||||
@@ -2689,10 +2688,9 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
|
||||
inputs,
|
||||
start: target.isInstanceMember ? 1 : 0,
|
||||
);
|
||||
template =
|
||||
target is ConstructorEntity
|
||||
? 'new #.$targetName(#)'
|
||||
: '#.$targetName(#)';
|
||||
template = target is ConstructorEntity
|
||||
? 'new #.$targetName(#)'
|
||||
: '#.$targetName(#)';
|
||||
templateInputs = [receiverExpression, arguments];
|
||||
}
|
||||
js.Expression expression = js.js
|
||||
@@ -3313,11 +3311,10 @@ class SsaCodeGenerator implements HVisitor<void>, HBlockInformationVisitor {
|
||||
}
|
||||
|
||||
void generateArrayLiteral(HLiteralList node) {
|
||||
List<js.Expression> elements =
|
||||
node.inputs.map((HInstruction input) {
|
||||
use(input);
|
||||
return pop();
|
||||
}).toList();
|
||||
List<js.Expression> elements = node.inputs.map((HInstruction input) {
|
||||
use(input);
|
||||
return pop();
|
||||
}).toList();
|
||||
push(
|
||||
js.ArrayInitializer(
|
||||
elements,
|
||||
|
||||
@@ -161,10 +161,9 @@ class SsaInstructionSelection extends HBaseVisitor<HInstruction?>
|
||||
// We also leave HIf nodes in place when one branch is dead.
|
||||
HInstruction condition = current.inputs.first;
|
||||
if (condition is HConstant) {
|
||||
successor =
|
||||
condition.constant is TrueConstantValue
|
||||
? current.thenBlock
|
||||
: current.elseBlock;
|
||||
successor = condition.constant is TrueConstantValue
|
||||
? current.thenBlock
|
||||
: current.elseBlock;
|
||||
}
|
||||
}
|
||||
if (successor != null && successor.id > current.block!.id) {
|
||||
@@ -224,10 +223,9 @@ class SsaInstructionSelection extends HBaseVisitor<HInstruction?>
|
||||
// ToPrimitive conversions of an object occur when the other operand is a
|
||||
// primitive (Number, String, Symbol and, indirectly, Boolean). We use
|
||||
// 'intercepted' types as a proxy for all the primitive types.
|
||||
bool _intercepted(AbstractValue type) =>
|
||||
_abstractValueDomain
|
||||
.isInterceptor(_abstractValueDomain.excludeNull(type))
|
||||
.isPotentiallyTrue;
|
||||
bool _intercepted(AbstractValue type) => _abstractValueDomain
|
||||
.isInterceptor(_abstractValueDomain.excludeNull(type))
|
||||
.isPotentiallyTrue;
|
||||
|
||||
@override
|
||||
HBinaryBitOp visitBinaryBitOp(HBinaryBitOp node) {
|
||||
|
||||
@@ -216,10 +216,12 @@ class SsaSimplifyInterceptors extends HBaseVisitor<bool>
|
||||
// If multiple instructions are present in bestBlock, we scan bestBlock from
|
||||
// the start to find first instruction. If the [dominator] hint is in the
|
||||
// same block, can start from there instead.
|
||||
Set<HInstruction> set =
|
||||
instructions.where((i) => i.block == bestBlock).toSet();
|
||||
HInstruction? current =
|
||||
(dominator?.block == bestBlock) ? dominator : bestBlock.first;
|
||||
Set<HInstruction> set = instructions
|
||||
.where((i) => i.block == bestBlock)
|
||||
.toSet();
|
||||
HInstruction? current = (dominator?.block == bestBlock)
|
||||
? dominator
|
||||
: bestBlock.first;
|
||||
while (current != null && !set.contains(current)) {
|
||||
current = current.next;
|
||||
}
|
||||
|
||||
@@ -156,17 +156,16 @@ class InvokeDynamicSpecializer {
|
||||
HGetLength length = HGetLength(
|
||||
array,
|
||||
abstractValueDomain.positiveIntType,
|
||||
isAssignable:
|
||||
abstractValueDomain
|
||||
.isFixedLengthJsIndexable(array.instructionType)
|
||||
.isPotentiallyFalse,
|
||||
isAssignable: abstractValueDomain
|
||||
.isFixedLengthJsIndexable(array.instructionType)
|
||||
.isPotentiallyFalse,
|
||||
);
|
||||
block.addBefore(indexerNode, length);
|
||||
|
||||
AbstractValue type =
|
||||
indexArgument.isPositiveInteger(abstractValueDomain).isDefinitelyTrue
|
||||
? indexArgument.instructionType
|
||||
: abstractValueDomain.positiveIntType;
|
||||
? indexArgument.instructionType
|
||||
: abstractValueDomain.positiveIntType;
|
||||
HBoundsCheck check = HBoundsCheck(indexArgument, length, array, type)
|
||||
..sourceInformation = indexerNode.sourceInformation;
|
||||
block.addBefore(indexerNode, check);
|
||||
@@ -232,8 +231,9 @@ class IndexAssignSpecializer extends InvokeDynamicSpecializer {
|
||||
.isDefinitelyTrue) {
|
||||
needsMutableCheck = true;
|
||||
} else if (receiver.isArray(abstractValueDomain).isDefinitelyTrue) {
|
||||
needsMutableCheck =
|
||||
receiver.isModifiableArray(abstractValueDomain).isPotentiallyFalse;
|
||||
needsMutableCheck = receiver
|
||||
.isModifiableArray(abstractValueDomain)
|
||||
.isPotentiallyFalse;
|
||||
} else {
|
||||
if (receiver.isMutableIndexable(abstractValueDomain).isPotentiallyFalse) {
|
||||
return null;
|
||||
|
||||
@@ -392,10 +392,9 @@ class LocalsHandler {
|
||||
HInstruction receiver = readLocal(
|
||||
closureData.getClosureEntity(_localsMap!)!,
|
||||
);
|
||||
AbstractValue type =
|
||||
local is BoxLocal
|
||||
? _abstractValueDomain.nonNullType
|
||||
: getTypeOfCapturedVariable(redirect);
|
||||
AbstractValue type = local is BoxLocal
|
||||
? _abstractValueDomain.nonNullType
|
||||
: getTypeOfCapturedVariable(redirect);
|
||||
HInstruction fieldGet = HFieldGet(
|
||||
redirect,
|
||||
receiver,
|
||||
|
||||
@@ -1935,10 +1935,9 @@ abstract class HInvokeDynamic extends HInvoke implements InstructionContext {
|
||||
AbstractValue resultType,
|
||||
) : _selector = selector,
|
||||
_originalReceiverType = _receiverType,
|
||||
specializer =
|
||||
isIntercepted
|
||||
? InvokeDynamicSpecializer.lookupSpecializer(selector)
|
||||
: const InvokeDynamicSpecializer(),
|
||||
specializer = isIntercepted
|
||||
? InvokeDynamicSpecializer.lookupSpecializer(selector)
|
||||
: const InvokeDynamicSpecializer(),
|
||||
super(inputs, resultType) {
|
||||
isInterceptedCall = isIntercepted;
|
||||
}
|
||||
@@ -2100,10 +2099,9 @@ class HInvokeDynamicGetter extends HInvokeDynamicField {
|
||||
|
||||
// There might be an interceptor input, so `inputs.last` is the dart receiver.
|
||||
@override
|
||||
bool canThrow(AbstractValueDomain domain) =>
|
||||
isTearOff
|
||||
? inputs.last.isNull(domain).isPotentiallyTrue
|
||||
: super.canThrow(domain);
|
||||
bool canThrow(AbstractValueDomain domain) => isTearOff
|
||||
? inputs.last.isNull(domain).isPotentiallyTrue
|
||||
: super.canThrow(domain);
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
|
||||
@@ -95,10 +95,9 @@ class SsaOptimizerTask extends CompilerTask {
|
||||
|
||||
OptimizationTestLog? log;
|
||||
if (retainDataForTesting) {
|
||||
log =
|
||||
loggersForTesting[member] = OptimizationTestLog(
|
||||
closedWorld.dartTypes,
|
||||
);
|
||||
log = loggersForTesting[member] = OptimizationTestLog(
|
||||
closedWorld.dartTypes,
|
||||
);
|
||||
}
|
||||
|
||||
measure(() {
|
||||
@@ -478,10 +477,9 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
|
||||
|
||||
// condition ? false : true --> !condition
|
||||
if (_isBoolConstant(left, false) && _isBoolConstant(right, true)) {
|
||||
HInstruction replacement =
|
||||
HNot(condition, _abstractValueDomain.boolType)
|
||||
..sourceElement = phi.sourceElement
|
||||
..sourceInformation = phi.sourceInformation;
|
||||
HInstruction replacement = HNot(condition, _abstractValueDomain.boolType)
|
||||
..sourceElement = phi.sourceElement
|
||||
..sourceInformation = phi.sourceInformation;
|
||||
block.addAtEntry(replacement);
|
||||
block.rewrite(phi, replacement);
|
||||
block.removePhi(phi);
|
||||
@@ -614,10 +612,9 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
|
||||
_abstractValueDomain.boolType,
|
||||
);
|
||||
block.addAtEntry(compare);
|
||||
HInstruction replacement =
|
||||
HNot(compare, _abstractValueDomain.boolType)
|
||||
..sourceElement = phi.sourceElement
|
||||
..sourceInformation = phi.sourceInformation;
|
||||
HInstruction replacement = HNot(compare, _abstractValueDomain.boolType)
|
||||
..sourceElement = phi.sourceElement
|
||||
..sourceInformation = phi.sourceInformation;
|
||||
block.rewrite(phi, replacement);
|
||||
block.addAfter(compare, replacement);
|
||||
block.removePhi(phi);
|
||||
@@ -1222,13 +1219,12 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
|
||||
final name = PublicName(
|
||||
_nativeData.computeUnescapedJSInteropName(method.name!),
|
||||
);
|
||||
final selector =
|
||||
method.isGetter
|
||||
? Selector.getter(name)
|
||||
: Selector.call(
|
||||
name,
|
||||
CallStructure.unnamed(invocation.inputs.length),
|
||||
);
|
||||
final selector = method.isGetter
|
||||
? Selector.getter(name)
|
||||
: Selector.call(
|
||||
name,
|
||||
CallStructure.unnamed(invocation.inputs.length),
|
||||
);
|
||||
if (_nativeData.interopNullChecks.containsKey(selector)) {
|
||||
FunctionType type = _closedWorld.elementEnvironment.getFunctionType(
|
||||
method,
|
||||
@@ -2083,11 +2079,10 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
|
||||
|
||||
HInstruction receiver = node.getDartReceiver(_closedWorld);
|
||||
AbstractValue receiverType = receiver.instructionType;
|
||||
final member =
|
||||
node.element ??= _closedWorld.locateSingleMember(
|
||||
node.selector,
|
||||
receiverType,
|
||||
);
|
||||
final member = node.element ??= _closedWorld.locateSingleMember(
|
||||
node.selector,
|
||||
receiverType,
|
||||
);
|
||||
if (member == null) return node;
|
||||
|
||||
if (member is FieldEntity) {
|
||||
@@ -2906,10 +2901,9 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
|
||||
if (shiftedMask is IntConstantValue && shiftedMask.isUInt32()) {
|
||||
// TODO(sra): The shift type should be available from the abstract
|
||||
// value domain.
|
||||
AbstractValue shiftType =
|
||||
shiftedMask.isZero
|
||||
? _abstractValueDomain.uint32Type
|
||||
: _abstractValueDomain.uint31Type;
|
||||
AbstractValue shiftType = shiftedMask.isZero
|
||||
? _abstractValueDomain.uint32Type
|
||||
: _abstractValueDomain.uint31Type;
|
||||
var shift = HShiftRight(operand, count, shiftType)
|
||||
..sourceInformation = node.sourceInformation;
|
||||
|
||||
@@ -3176,10 +3170,9 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
|
||||
// We also leave HIf nodes in place when one branch is dead.
|
||||
HInstruction condition = current.inputs.first;
|
||||
if (condition is HConstant) {
|
||||
successor =
|
||||
condition.constant is TrueConstantValue
|
||||
? current.thenBlock
|
||||
: current.elseBlock;
|
||||
successor = condition.constant is TrueConstantValue
|
||||
? current.thenBlock
|
||||
: current.elseBlock;
|
||||
assert(successor.isLive);
|
||||
}
|
||||
}
|
||||
@@ -3459,8 +3452,9 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
|
||||
if (branch is HIf) {
|
||||
if (branch.thenBlock.isLive == branch.elseBlock.isLive) return;
|
||||
assert(branch.condition is HConstant);
|
||||
HBasicBlock liveSuccessor =
|
||||
branch.thenBlock.isLive ? branch.thenBlock : branch.elseBlock;
|
||||
HBasicBlock liveSuccessor = branch.thenBlock.isLive
|
||||
? branch.thenBlock
|
||||
: branch.elseBlock;
|
||||
HInstruction instruction = liveSuccessor.first!;
|
||||
// Move instructions up until the final control flow instruction or pinned
|
||||
// HTypeKnown.
|
||||
@@ -3912,10 +3906,10 @@ class SsaGlobalValueNumberer implements OptimizationPhase {
|
||||
// Propagate loop changes flags upwards.
|
||||
final parentLoopHeader = block.parentLoopHeader;
|
||||
if (parentLoopHeader != null) {
|
||||
loopChangesFlags[parentLoopHeader
|
||||
.id] = loopChangesFlags[parentLoopHeader.id].union(
|
||||
(block.isLoopHeader()) ? loopChangesFlags[id] : changesFlags,
|
||||
);
|
||||
loopChangesFlags[parentLoopHeader.id] =
|
||||
loopChangesFlags[parentLoopHeader.id].union(
|
||||
(block.isLoopHeader()) ? loopChangesFlags[id] : changesFlags,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +90,9 @@ class SsaFunctionCompiler implements FunctionCompiler {
|
||||
// for the target function but stubs are so simple that this usually doesn't
|
||||
// produce better code. Deserializing inference results is also expensive so
|
||||
// we avoid it here.
|
||||
final inferenceResults =
|
||||
member is JParameterStub
|
||||
? _trivialInferenceResults
|
||||
: _globalInferenceResults;
|
||||
final inferenceResults = member is JParameterStub
|
||||
? _trivialInferenceResults
|
||||
: _globalInferenceResults;
|
||||
JClosedWorld closedWorld = _globalInferenceResults.closedWorld;
|
||||
|
||||
CodegenRegistry registry = CodegenRegistry(
|
||||
|
||||
@@ -155,10 +155,9 @@ class HInstructionStringifier implements HVisitor<String> {
|
||||
AbstractValueDomain get _abstractValueDomain =>
|
||||
closedWorld.abstractValueDomain;
|
||||
|
||||
String visit(HInstruction node) =>
|
||||
node is HControlFlow
|
||||
? node.accept(this)
|
||||
: '${node.accept(this)} ${node.instructionType}';
|
||||
String visit(HInstruction node) => node is HControlFlow
|
||||
? node.accept(this)
|
||||
: '${node.accept(this)} ${node.instructionType}';
|
||||
|
||||
String temporaryId(HInstruction instruction) {
|
||||
String prefix;
|
||||
|
||||
@@ -36,10 +36,9 @@ abstract class TypeBuilder {
|
||||
if (type is! InterfaceType) return null;
|
||||
// The type element is either a class or the void element.
|
||||
ClassEntity element = type.element;
|
||||
AbstractValue mask =
|
||||
includeNull
|
||||
? _abstractValueDomain.createNullableSubtype(element)
|
||||
: _abstractValueDomain.createNonNullSubtype(element);
|
||||
AbstractValue mask = includeNull
|
||||
? _abstractValueDomain.createNullableSubtype(element)
|
||||
: _abstractValueDomain.createNonNullSubtype(element);
|
||||
if (hasLateSentinel) mask = _abstractValueDomain.includeLateSentinel(mask);
|
||||
return mask;
|
||||
}
|
||||
@@ -52,10 +51,9 @@ abstract class TypeBuilder {
|
||||
|
||||
/// Create an instruction to simply trust the provided type.
|
||||
HInstruction _trustType(HInstruction original, DartType type) {
|
||||
bool hasLateSentinel =
|
||||
_abstractValueDomain
|
||||
.isLateSentinel(original.instructionType)
|
||||
.isPotentiallyTrue;
|
||||
bool hasLateSentinel = _abstractValueDomain
|
||||
.isLateSentinel(original.instructionType)
|
||||
.isPotentiallyTrue;
|
||||
final mask = trustTypeMask(type, hasLateSentinel: hasLateSentinel);
|
||||
if (mask == null) return original;
|
||||
return HTypeKnown.pinned(mask, original);
|
||||
|
||||
@@ -273,8 +273,9 @@ class SsaTypePropagator extends HBaseVisitor<AbstractValue>
|
||||
PrimitiveCheckKind kind,
|
||||
DartType typeExpression,
|
||||
) {
|
||||
Selector? selector =
|
||||
(kind == PrimitiveCheckKind.receiverType) ? instruction.selector : null;
|
||||
Selector? selector = (kind == PrimitiveCheckKind.receiverType)
|
||||
? instruction.selector
|
||||
: null;
|
||||
HPrimitiveCheck converted = HPrimitiveCheck(
|
||||
typeExpression,
|
||||
kind,
|
||||
@@ -373,8 +374,8 @@ class SsaTypePropagator extends HBaseVisitor<AbstractValue>
|
||||
}
|
||||
AbstractValue type =
|
||||
right.isIntegerOrNull(abstractValueDomain).isDefinitelyTrue
|
||||
? abstractValueDomain.excludeNull(right.instructionType)
|
||||
: abstractValueDomain.numType;
|
||||
? abstractValueDomain.excludeNull(right.instructionType)
|
||||
: abstractValueDomain.numType;
|
||||
// TODO(ngeoffray): Some number operations don't have a builtin
|
||||
// variant and will do the check in their method anyway. We
|
||||
// still add a check because it allows to GVN these operations,
|
||||
|
||||
@@ -885,10 +885,9 @@ class SsaValueRangeAnalyzer extends HBaseVisitor<Range>
|
||||
constantNum = IntConstantValue(BigInt.zero);
|
||||
}
|
||||
|
||||
BigInt intValue =
|
||||
constantNum is IntConstantValue
|
||||
? constantNum.intValue
|
||||
: BigInt.from(constantNum.doubleValue.toInt());
|
||||
BigInt intValue = constantNum is IntConstantValue
|
||||
? constantNum.intValue
|
||||
: BigInt.from(constantNum.doubleValue.toInt());
|
||||
Value value = info.newIntValue(intValue);
|
||||
return info.newNormalizedRange(value, value);
|
||||
}
|
||||
@@ -1309,8 +1308,9 @@ class SsaValueRangeAnalyzer extends HBaseVisitor<Range>
|
||||
if (node.falseBranch.predecessors.length == 1) {
|
||||
assert(node.falseBranch.predecessors[0] == node.block);
|
||||
constant_system.BinaryOperation reverse = negateOperation(operation);
|
||||
constant_system.BinaryOperation reversedMirror =
|
||||
flipOperation(reverse)!;
|
||||
constant_system.BinaryOperation reversedMirror = flipOperation(
|
||||
reverse,
|
||||
)!;
|
||||
// Update the false branch to use narrower ranges for [left] and
|
||||
// [right].
|
||||
Range range = computeConstrainedRange(reverse, leftRange, rightRange);
|
||||
@@ -1359,10 +1359,9 @@ class LoopUpdateRecognizer extends HBaseVisitor<Range?> {
|
||||
Range? run(HPhi loopPhi) {
|
||||
// Create a marker range for the loop phi. This is the symbolic initial
|
||||
// value of the loop variable for one iteration.
|
||||
bool isPositive =
|
||||
loopPhi
|
||||
.isPositiveInteger(closedWorld.abstractValueDomain)
|
||||
.isDefinitelyTrue;
|
||||
bool isPositive = loopPhi
|
||||
.isPositiveInteger(closedWorld.abstractValueDomain)
|
||||
.isDefinitelyTrue;
|
||||
final lowerMarker = info.newMarkerValue(
|
||||
isLower: true,
|
||||
isPositive: isPositive,
|
||||
@@ -1390,10 +1389,12 @@ class LoopUpdateRecognizer extends HBaseVisitor<Range?> {
|
||||
|
||||
Value lowerLimit = isPositive ? info.intZero : info.minIntValue;
|
||||
Value upperLimit = info.maxIntValue;
|
||||
Value lowerBound =
|
||||
deltaRange.lower == lowerMarker ? startRange.lower : lowerLimit;
|
||||
Value upperBound =
|
||||
deltaRange.upper == upperMarker ? startRange.upper : upperLimit;
|
||||
Value lowerBound = deltaRange.lower == lowerMarker
|
||||
? startRange.lower
|
||||
: lowerLimit;
|
||||
Value upperBound = deltaRange.upper == upperMarker
|
||||
? startRange.upper
|
||||
: upperLimit;
|
||||
|
||||
// Widen the update range and union with the start range.
|
||||
final widened = updateRange.replaceMarkers(lowerBound, upperBound);
|
||||
|
||||
@@ -135,10 +135,9 @@ class CallStructure {
|
||||
/// The names of the named arguments in canonicalized order.
|
||||
List<String> getOrderedNamedArguments() => const [];
|
||||
|
||||
CallStructure get nonGeneric =>
|
||||
typeArgumentCount == 0
|
||||
? this
|
||||
: CallStructure(argumentCount, namedArguments);
|
||||
CallStructure get nonGeneric => typeArgumentCount == 0
|
||||
? this
|
||||
: CallStructure(argumentCount, namedArguments);
|
||||
|
||||
/// Short textual representation use for testing.
|
||||
String get shortText {
|
||||
@@ -287,15 +286,14 @@ class _NamedCallStructure extends CallStructure {
|
||||
identical(namedArguments, getOrderedNamedArguments());
|
||||
|
||||
@override
|
||||
CallStructure toNormalized() =>
|
||||
isNormalized
|
||||
? this
|
||||
: _NamedCallStructure(
|
||||
argumentCount,
|
||||
getOrderedNamedArguments(),
|
||||
typeArgumentCount,
|
||||
getOrderedNamedArguments(),
|
||||
);
|
||||
CallStructure toNormalized() => isNormalized
|
||||
? this
|
||||
: _NamedCallStructure(
|
||||
argumentCount,
|
||||
getOrderedNamedArguments(),
|
||||
typeArgumentCount,
|
||||
getOrderedNamedArguments(),
|
||||
);
|
||||
|
||||
@override
|
||||
List<String> getOrderedNamedArguments() {
|
||||
|
||||
@@ -811,8 +811,8 @@ class ClassHierarchyBuilder {
|
||||
{};
|
||||
|
||||
bool isInheritedInSubtypeOf(ClassEntity x, ClassEntity y) {
|
||||
_InheritedInSubtypeCache cache =
|
||||
_inheritedInSubtypeCacheMap[x] ??= _InheritedInSubtypeCache();
|
||||
_InheritedInSubtypeCache cache = _inheritedInSubtypeCacheMap[x] ??=
|
||||
_InheritedInSubtypeCache();
|
||||
return cache.isInheritedInSubtypeOf(this, x, y);
|
||||
}
|
||||
}
|
||||
@@ -839,12 +839,11 @@ class _InheritedInThisClassCache {
|
||||
} else {
|
||||
set = _map![thisClass];
|
||||
}
|
||||
set ??=
|
||||
_map![thisClass] = _computeInheritingInThisClassSet(
|
||||
builder,
|
||||
memberHoldingClass,
|
||||
thisClass,
|
||||
);
|
||||
set ??= _map![thisClass] = _computeInheritingInThisClassSet(
|
||||
builder,
|
||||
memberHoldingClass,
|
||||
thisClass,
|
||||
);
|
||||
return set.hasLiveClass(builder);
|
||||
}
|
||||
|
||||
|
||||
@@ -408,10 +408,10 @@ class ClassHierarchyNode {
|
||||
} else {
|
||||
dynamic subclasses = _directSubclasses;
|
||||
if (sorted) {
|
||||
subclasses =
|
||||
_directSubclasses.toList()..sort((a, b) {
|
||||
return a.cls.name.compareTo(b.cls.name);
|
||||
});
|
||||
subclasses = _directSubclasses.toList()
|
||||
..sort((a, b) {
|
||||
return a.cls.name.compareTo(b.cls.name);
|
||||
});
|
||||
}
|
||||
bool needsComma = false;
|
||||
for (ClassHierarchyNode child in subclasses) {
|
||||
@@ -1027,10 +1027,9 @@ class SubtypesIterator implements Iterator<ClassEntity> {
|
||||
bool moveNext() {
|
||||
if (elements == null && hierarchyNodes == null) {
|
||||
// Initial state. Iterate through subclasses.
|
||||
elements =
|
||||
iterable.subtypeSet.node
|
||||
.subclassesByMask(mask, strict: !includeRoot)
|
||||
.iterator;
|
||||
elements = iterable.subtypeSet.node
|
||||
.subclassesByMask(mask, strict: !includeRoot)
|
||||
.iterator;
|
||||
}
|
||||
if (elements != null && elements!.moveNext()) {
|
||||
return true;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user